diff options
-rw-r--r-- | .gitattributes | 7 | ||||
-rw-r--r-- | .gitignore | 56 | ||||
-rw-r--r-- | ChangeLog | 683 | ||||
-rw-r--r-- | INSTALL | 150 | ||||
-rw-r--r-- | INSTALL-win32.txt | 25 | ||||
-rw-r--r-- | Makefile.am | 167 | ||||
-rw-r--r-- | Makefile.in | 664 | ||||
-rw-r--r-- | README.IPv6 | 97 | ||||
-rw-r--r-- | README.polarssl | 28 | ||||
-rw-r--r-- | TODO.IPv6 | 209 | ||||
-rw-r--r-- | acinclude.m4 | 127 | ||||
-rw-r--r-- | aclocal.m4 | 10 | ||||
-rw-r--r-- | build/Makefile.am | 17 | ||||
-rw-r--r-- | build/Makefile.in | 615 | ||||
-rw-r--r-- | build/ltrc.inc | 23 | ||||
-rw-r--r-- | build/msvc/Makefile.am | 15 | ||||
-rw-r--r-- | build/msvc/Makefile.in | 613 | ||||
-rw-r--r-- | build/msvc/msvc-generate/Makefile.am | 18 | ||||
-rw-r--r-- | build/msvc/msvc-generate/Makefile.in | 418 | ||||
-rwxr-xr-x | build/msvc/msvc-generate/Makefile.mak | 13 | ||||
-rw-r--r-- | build/msvc/msvc-generate/msvc-generate.js | 118 | ||||
-rw-r--r-- | build/msvc/msvc-generate/msvc-generate.vcxproj | 69 | ||||
-rw-r--r-- | compat.m4 | 75 | ||||
-rw-r--r-- | config-msvc-version.h.in | 10 | ||||
-rw-r--r-- | config-msvc.h | 122 | ||||
-rw-r--r-- | config-version.h.in | 1 | ||||
-rw-r--r-- | config.h.in | 287 | ||||
-rwxr-xr-x | configure | 13336 | ||||
-rw-r--r-- | configure.ac | 1615 | ||||
-rw-r--r-- | configure_h.awk | 39 | ||||
-rw-r--r-- | configure_log.awk | 33 | ||||
-rw-r--r-- | crypto.h | 421 | ||||
-rwxr-xr-x | debug/doval | 4 | ||||
-rwxr-xr-x | debug/dovalns | 2 | ||||
-rw-r--r-- | distro/Makefile.am | 15 | ||||
-rw-r--r-- | distro/Makefile.in | 613 | ||||
-rw-r--r-- | distro/rpm/Makefile.am | 18 | ||||
-rw-r--r-- | distro/rpm/Makefile.in | 420 | ||||
-rwxr-xr-x | distro/rpm/openvpn.init.d.rhel (renamed from sample-scripts/openvpn.init) | 0 | ||||
-rw-r--r-- | distro/rpm/openvpn.init.d.suse (renamed from suse/openvpn.init) | 2 | ||||
-rw-r--r-- | distro/rpm/openvpn.spec (renamed from openvpn.spec.in) | 125 | ||||
-rw-r--r-- | distro/rpm/openvpn.spec.in (renamed from openvpn.spec) | 125 | ||||
-rw-r--r-- | doc/Makefile.am | 31 | ||||
-rw-r--r-- | doc/Makefile.in (renamed from install-win32/Makefile.in) | 357 | ||||
-rw-r--r-- | doc/README.plugins (renamed from plugin/README) | 0 | ||||
-rw-r--r-- | doc/management-notes.txt (renamed from management/management-notes.txt) | 201 | ||||
-rw-r--r-- | doc/openvpn.8 (renamed from openvpn.8) | 712 | ||||
-rwxr-xr-x | doclean | 73 | ||||
-rw-r--r-- | domake-win | 138 | ||||
-rw-r--r-- | easy-rsa/1.0/README | 161 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-ca | 13 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-dh | 12 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-inter | 19 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-key | 20 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-key-pass | 20 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-key-pkcs12 | 21 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-key-server | 22 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-req | 18 | ||||
-rwxr-xr-x | easy-rsa/1.0/build-req-pass | 18 | ||||
-rwxr-xr-x | easy-rsa/1.0/clean-all | 19 | ||||
-rw-r--r-- | easy-rsa/1.0/list-crl | 18 | ||||
-rw-r--r-- | easy-rsa/1.0/make-crl | 18 | ||||
-rw-r--r-- | easy-rsa/1.0/openssl.cnf | 255 | ||||
-rw-r--r-- | easy-rsa/1.0/revoke-crt | 18 | ||||
-rwxr-xr-x | easy-rsa/1.0/revoke-full | 29 | ||||
-rwxr-xr-x | easy-rsa/1.0/sign-req | 18 | ||||
-rw-r--r-- | easy-rsa/1.0/vars | 49 | ||||
-rw-r--r-- | easy-rsa/2.0/Makefile | 13 | ||||
-rw-r--r-- | easy-rsa/2.0/README | 229 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-ca | 8 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-dh | 11 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-inter | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-key | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-key-pass | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-key-pkcs12 | 8 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-key-server | 10 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-req | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/build-req-pass | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/clean-all | 16 | ||||
-rwxr-xr-x | easy-rsa/2.0/inherit-inter | 39 | ||||
-rwxr-xr-x | easy-rsa/2.0/list-crl | 13 | ||||
-rwxr-xr-x | easy-rsa/2.0/openssl-0.9.6.cnf | 265 | ||||
-rwxr-xr-x | easy-rsa/2.0/openssl-0.9.8.cnf | 290 | ||||
-rwxr-xr-x | easy-rsa/2.0/openssl-1.0.0.cnf | 285 | ||||
-rw-r--r-- | easy-rsa/2.0/openssl-1.0.0.cnf-old-copy | 285 | ||||
-rwxr-xr-x | easy-rsa/2.0/pkitool | 379 | ||||
-rwxr-xr-x | easy-rsa/2.0/revoke-full | 40 | ||||
-rwxr-xr-x | easy-rsa/2.0/sign-req | 7 | ||||
-rw-r--r-- | easy-rsa/2.0/tmp/README | 229 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-ca | 8 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-dh | 11 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-inter | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-key | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-key-pass | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-key-pkcs12 | 8 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-key-server | 10 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-req | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/build-req-pass | 7 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/clean-all | 16 | ||||
-rw-r--r-- | easy-rsa/2.0/tmp/file | 1 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/inherit-inter | 39 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/list-crl | 13 | ||||
-rw-r--r-- | easy-rsa/2.0/tmp/openssl-0.9.6.cnf | 265 | ||||
-rw-r--r-- | easy-rsa/2.0/tmp/openssl-1.0.0.cnf | 285 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/pkitool | 379 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/revoke-full | 40 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/sign-req | 7 | ||||
-rw-r--r-- | easy-rsa/2.0/tmp/vars | 74 | ||||
-rwxr-xr-x | easy-rsa/2.0/tmp/whichopensslcnf | 23 | ||||
-rwxr-xr-x | easy-rsa/2.0/vars | 74 | ||||
-rwxr-xr-x | easy-rsa/2.0/whichopensslcnf | 26 | ||||
-rw-r--r-- | easy-rsa/Windows/README.txt | 44 | ||||
-rw-r--r-- | easy-rsa/Windows/build-ca-pass.bat | 8 | ||||
-rw-r--r-- | easy-rsa/Windows/build-ca.bat | 4 | ||||
-rw-r--r-- | easy-rsa/Windows/build-dh.bat | 4 | ||||
-rw-r--r-- | easy-rsa/Windows/build-key-pass.bat | 8 | ||||
-rw-r--r-- | easy-rsa/Windows/build-key-pkcs12.bat | 10 | ||||
-rw-r--r-- | easy-rsa/Windows/build-key-server-pass.bat | 8 | ||||
-rw-r--r-- | easy-rsa/Windows/build-key-server.bat | 8 | ||||
-rw-r--r-- | easy-rsa/Windows/build-key.bat | 8 | ||||
-rw-r--r-- | easy-rsa/Windows/clean-all.bat | 13 | ||||
-rw-r--r-- | easy-rsa/Windows/index.txt.start | 0 | ||||
-rwxr-xr-x | easy-rsa/Windows/init-config.bat | 1 | ||||
-rw-r--r-- | easy-rsa/Windows/revoke-full.bat | 13 | ||||
-rw-r--r-- | easy-rsa/Windows/serial.start | 1 | ||||
-rw-r--r-- | easy-rsa/Windows/vars.bat.sample | 40 | ||||
-rw-r--r-- | forward.h | 86 | ||||
-rw-r--r-- | fragment.h | 188 | ||||
-rw-r--r-- | ieproxy.c | 146 | ||||
-rw-r--r-- | ieproxy.h | 24 | ||||
-rw-r--r-- | images/Makefile.am | 41 | ||||
-rwxr-xr-x | images/icon.ico | bin | 22486 -> 0 bytes | |||
-rwxr-xr-x | images/install-whirl.bmp | bin | 25820 -> 0 bytes | |||
-rw-r--r-- | include/Makefile.am | 15 | ||||
-rw-r--r-- | include/Makefile.in | 509 | ||||
-rw-r--r-- | include/openvpn-plugin.h (renamed from openvpn-plugin.h) | 339 | ||||
-rw-r--r-- | install-win32/GetWindowsVersion.nsi | 109 | ||||
-rw-r--r-- | install-win32/Makefile.am | 97 | ||||
-rw-r--r-- | install-win32/build-pkcs11-helper.sh | 24 | ||||
-rw-r--r-- | install-win32/buildinstaller | 14 | ||||
-rw-r--r-- | install-win32/ddk-common | 2 | ||||
-rw-r--r-- | install-win32/doclean | 6 | ||||
-rw-r--r-- | install-win32/dosname.pl | 9 | ||||
-rw-r--r-- | install-win32/getgui | 19 | ||||
-rw-r--r-- | install-win32/getopenssl | 19 | ||||
-rw-r--r-- | install-win32/getpkcs11helper | 17 | ||||
-rw-r--r-- | install-win32/getprebuilt | 10 | ||||
-rw-r--r-- | install-win32/getxgui | 28 | ||||
-rw-r--r-- | install-win32/ifdef.pl | 53 | ||||
-rw-r--r-- | install-win32/m4todef.pl | 15 | ||||
-rw-r--r-- | install-win32/macro.pl | 61 | ||||
-rw-r--r-- | install-win32/makeopenvpn | 37 | ||||
-rw-r--r-- | install-win32/maketap | 17 | ||||
-rw-r--r-- | install-win32/maketapinstall | 15 | ||||
-rw-r--r-- | install-win32/maketext | 59 | ||||
-rw-r--r-- | install-win32/openssl/README.txt | 21 | ||||
-rw-r--r-- | install-win32/openssl/openssl097.patch | 68 | ||||
-rw-r--r-- | install-win32/openssl/openssl098.patch | 56 | ||||
-rwxr-xr-x | install-win32/openvpn.nsi | 886 | ||||
-rwxr-xr-x | install-win32/setpath.nsi | 231 | ||||
-rw-r--r-- | install-win32/settings.in | 71 | ||||
-rw-r--r-- | install-win32/trans.pl | 97 | ||||
-rwxr-xr-x | install-win32/u2d.c | 20 | ||||
-rw-r--r-- | install-win32/winconfig | 18 | ||||
-rwxr-xr-x | ltmain.sh | 8745 | ||||
-rw-r--r-- | lzo.h | 136 | ||||
-rw-r--r-- | m4/ax_emptyarray.m4 | 40 | ||||
-rw-r--r-- | m4/ax_socklen_t.m4 | 65 | ||||
-rw-r--r-- | m4/ax_varargs.m4 | 77 | ||||
-rw-r--r-- | m4/libtool.m4 | 7441 | ||||
-rw-r--r-- | m4/ltoptions.m4 | 369 | ||||
-rw-r--r-- | m4/ltsugar.m4 | 123 | ||||
-rw-r--r-- | m4/ltversion.m4 | 23 | ||||
-rw-r--r-- | m4/lt~obsolete.m4 | 98 | ||||
-rw-r--r-- | m4/pkg.m4 | 159 | ||||
-rw-r--r-- | msvc-build.bat | 48 | ||||
-rw-r--r-- | msvc-dev.bat | 26 | ||||
-rw-r--r-- | msvc-env.bat | 30 | ||||
-rw-r--r-- | openvpn.sln | 38 | ||||
-rw-r--r-- | plugin/auth-pam/.svnignore | 1 | ||||
-rwxr-xr-x | plugin/auth-pam/Makefile | 30 | ||||
-rwxr-xr-x | plugin/down-root/Makefile | 17 | ||||
-rw-r--r-- | reliable.h | 163 | ||||
-rw-r--r-- | sample-keys/ta.key | 21 | ||||
-rw-r--r-- | sample/Makefile.am | 34 | ||||
-rw-r--r-- | sample/Makefile.in (renamed from images/Makefile.in) | 185 | ||||
-rw-r--r-- | sample/sample-config-files/README (renamed from sample-config-files/README) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/client.conf (renamed from sample-config-files/client.conf) | 0 | ||||
-rwxr-xr-x | sample/sample-config-files/firewall.sh (renamed from sample-config-files/firewall.sh) | 0 | ||||
-rwxr-xr-x | sample/sample-config-files/home.up (renamed from sample-config-files/home.up) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/loopback-client (renamed from sample-config-files/loopback-client) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/loopback-server (renamed from sample-config-files/loopback-server) | 0 | ||||
-rwxr-xr-x | sample/sample-config-files/office.up (renamed from sample-config-files/office.up) | 0 | ||||
-rwxr-xr-x | sample/sample-config-files/openvpn-shutdown.sh (renamed from sample-config-files/openvpn-shutdown.sh) | 0 | ||||
-rwxr-xr-x | sample/sample-config-files/openvpn-startup.sh (renamed from sample-config-files/openvpn-startup.sh) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/server.conf (renamed from sample-config-files/server.conf) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/static-home.conf (renamed from sample-config-files/static-home.conf) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/static-office.conf (renamed from sample-config-files/static-office.conf) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/tls-home.conf (renamed from sample-config-files/tls-home.conf) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/tls-office.conf (renamed from sample-config-files/tls-office.conf) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/xinetd-client-config (renamed from sample-config-files/xinetd-client-config) | 0 | ||||
-rw-r--r-- | sample/sample-config-files/xinetd-server-config (renamed from sample-config-files/xinetd-server-config) | 0 | ||||
-rw-r--r-- | sample/sample-keys/README (renamed from sample-keys/README) | 0 | ||||
-rw-r--r-- | sample/sample-keys/ca.crt (renamed from sample-keys/ca.crt) | 0 | ||||
-rw-r--r-- | sample/sample-keys/ca.key (renamed from sample-keys/ca.key) | 0 | ||||
-rw-r--r-- | sample/sample-keys/client.crt (renamed from sample-keys/client.crt) | 0 | ||||
-rw-r--r-- | sample/sample-keys/client.key (renamed from sample-keys/client.key) | 0 | ||||
-rw-r--r-- | sample/sample-keys/dh1024.pem (renamed from sample-keys/dh1024.pem) | 0 | ||||
-rw-r--r-- | sample/sample-keys/pass.crt (renamed from sample-keys/pass.crt) | 0 | ||||
-rw-r--r-- | sample/sample-keys/pass.key (renamed from sample-keys/pass.key) | 0 | ||||
-rw-r--r-- | sample/sample-keys/pkcs12.p12 (renamed from sample-keys/pkcs12.p12) | bin | 2685 -> 2685 bytes | |||
-rw-r--r-- | sample/sample-keys/server.crt (renamed from sample-keys/server.crt) | 0 | ||||
-rw-r--r-- | sample/sample-keys/server.key (renamed from sample-keys/server.key) | 0 | ||||
-rw-r--r-- | sample/sample-plugins/defer/README (renamed from plugin/defer/README) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/defer/build | 15 | ||||
-rw-r--r-- | sample/sample-plugins/defer/simple.c (renamed from plugin/defer/simple.c) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/defer/simple.def (renamed from plugin/defer/simple.def) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/defer/winbuild (renamed from plugin/examples/winbuild) | 2 | ||||
-rwxr-xr-x | sample/sample-plugins/log/build (renamed from plugin/examples/build) | 9 | ||||
-rw-r--r-- | sample/sample-plugins/log/log.c (renamed from plugin/examples/log.c) | 0 | ||||
-rw-r--r-- | sample/sample-plugins/log/log_v3.c | 247 | ||||
-rwxr-xr-x | sample/sample-plugins/log/winbuild (renamed from plugin/defer/winbuild) | 2 | ||||
-rw-r--r-- | sample/sample-plugins/simple/README (renamed from plugin/examples/README) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/simple/build (renamed from plugin/defer/build) | 9 | ||||
-rw-r--r-- | sample/sample-plugins/simple/simple.c (renamed from plugin/examples/simple.c) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/simple/simple.def (renamed from plugin/examples/simple.def) | 0 | ||||
-rwxr-xr-x | sample/sample-plugins/simple/winbuild | 18 | ||||
-rwxr-xr-x | sample/sample-scripts/auth-pam.pl (renamed from sample-scripts/auth-pam.pl) | 0 | ||||
-rwxr-xr-x | sample/sample-scripts/bridge-start (renamed from sample-scripts/bridge-start) | 0 | ||||
-rwxr-xr-x | sample/sample-scripts/bridge-stop (renamed from sample-scripts/bridge-stop) | 0 | ||||
-rwxr-xr-x | sample/sample-scripts/ucn.pl (renamed from sample-scripts/ucn.pl) | 0 | ||||
-rwxr-xr-x | sample/sample-scripts/verify-cn (renamed from sample-scripts/verify-cn) | 6 | ||||
-rwxr-xr-x | sample/sample-windows/sample.ovpn (renamed from install-win32/sample.ovpn) | 0 | ||||
-rw-r--r-- | service-win32/Makefile.am | 41 | ||||
-rw-r--r-- | service-win32/msvc.mak | 30 | ||||
-rw-r--r-- | src/Makefile.am | 15 | ||||
-rw-r--r-- | src/Makefile.in | 613 | ||||
-rw-r--r-- | src/compat/Makefile.am | 29 | ||||
-rw-r--r-- | src/compat/Makefile.in | 546 | ||||
-rw-r--r-- | src/compat/compat-basename.c | 50 | ||||
-rw-r--r-- | src/compat/compat-daemon.c | 100 | ||||
-rw-r--r-- | src/compat/compat-dirname.c | 119 | ||||
-rw-r--r-- | src/compat/compat-gettimeofday.c | 131 | ||||
-rw-r--r-- | src/compat/compat-inet_ntop.c | 76 | ||||
-rw-r--r-- | src/compat/compat-inet_pton.c | 79 | ||||
-rw-r--r-- | src/compat/compat-stdbool.h | 12 | ||||
-rw-r--r-- | src/compat/compat.h | 68 | ||||
-rw-r--r-- | src/compat/compat.vcxproj | 87 | ||||
-rw-r--r-- | src/compat/compat.vcxproj.filters | 42 | ||||
-rw-r--r-- | src/openvpn/Makefile.am | 126 | ||||
-rw-r--r-- | src/openvpn/Makefile.in | 758 | ||||
-rw-r--r-- | src/openvpn/base64.c (renamed from base64.c) | 41 | ||||
-rw-r--r-- | src/openvpn/base64.h (renamed from base64.h) | 8 | ||||
-rw-r--r-- | src/openvpn/basic.h (renamed from basic.h) | 15 | ||||
-rw-r--r-- | src/openvpn/buffer.c (renamed from buffer.c) | 111 | ||||
-rw-r--r-- | src/openvpn/buffer.h (renamed from buffer.h) | 85 | ||||
-rw-r--r-- | src/openvpn/circ_list.h (renamed from circ_list.h) | 0 | ||||
-rw-r--r-- | src/openvpn/clinat.c | 269 | ||||
-rw-r--r-- | src/openvpn/clinat.h | 65 | ||||
-rw-r--r-- | src/openvpn/common.h (renamed from common.h) | 7 | ||||
-rw-r--r-- | src/openvpn/console.c | 238 | ||||
-rw-r--r-- | src/openvpn/console.h (renamed from memcmp.c) | 24 | ||||
-rw-r--r-- | src/openvpn/crypto.c (renamed from crypto.c) | 724 | ||||
-rw-r--r-- | src/openvpn/crypto.h | 398 | ||||
-rw-r--r-- | src/openvpn/crypto_backend.h | 488 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.c | 753 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.h | 73 | ||||
-rw-r--r-- | src/openvpn/crypto_polarssl.c | 605 | ||||
-rw-r--r-- | src/openvpn/crypto_polarssl.h | 95 | ||||
-rw-r--r-- | src/openvpn/cryptoapi.c (renamed from cryptoapi.c) | 51 | ||||
-rw-r--r-- | src/openvpn/cryptoapi.h (renamed from cryptoapi.h) | 0 | ||||
-rw-r--r-- | src/openvpn/dhcp.c (renamed from dhcp.c) | 85 | ||||
-rw-r--r-- | src/openvpn/dhcp.h (renamed from dhcp.h) | 0 | ||||
-rw-r--r-- | src/openvpn/errlevel.h (renamed from errlevel.h) | 20 | ||||
-rw-r--r-- | src/openvpn/error.c (renamed from error.c) | 93 | ||||
-rw-r--r-- | src/openvpn/error.h (renamed from error.h) | 21 | ||||
-rw-r--r-- | src/openvpn/event.c (renamed from event.c) | 18 | ||||
-rw-r--r-- | src/openvpn/event.h (renamed from event.h) | 0 | ||||
-rw-r--r-- | src/openvpn/fdmisc.c (renamed from fdmisc.c) | 8 | ||||
-rw-r--r-- | src/openvpn/fdmisc.h (renamed from fdmisc.h) | 0 | ||||
-rw-r--r-- | src/openvpn/forward-inline.h (renamed from forward-inline.h) | 6 | ||||
-rw-r--r-- | src/openvpn/forward.c (renamed from forward.c) | 130 | ||||
-rw-r--r-- | src/openvpn/forward.h | 242 | ||||
-rw-r--r-- | src/openvpn/fragment.c (renamed from fragment.c) | 6 | ||||
-rw-r--r-- | src/openvpn/fragment.h | 479 | ||||
-rw-r--r-- | src/openvpn/gremlin.c (renamed from gremlin.c) | 6 | ||||
-rw-r--r-- | src/openvpn/gremlin.h (renamed from gremlin.h) | 0 | ||||
-rw-r--r-- | src/openvpn/helper.c (renamed from helper.c) | 69 | ||||
-rw-r--r-- | src/openvpn/helper.h (renamed from helper.h) | 0 | ||||
-rw-r--r-- | src/openvpn/httpdigest.c (renamed from httpdigest.c) | 87 | ||||
-rw-r--r-- | src/openvpn/httpdigest.h (renamed from httpdigest.h) | 0 | ||||
-rw-r--r-- | src/openvpn/init.c (renamed from init.c) | 710 | ||||
-rw-r--r-- | src/openvpn/init.h (renamed from init.h) | 1 | ||||
-rw-r--r-- | src/openvpn/integer.h (renamed from integer.h) | 0 | ||||
-rw-r--r-- | src/openvpn/interval.c (renamed from interval.c) | 6 | ||||
-rw-r--r-- | src/openvpn/interval.h (renamed from interval.h) | 0 | ||||
-rw-r--r-- | src/openvpn/list.c (renamed from list.c) | 6 | ||||
-rw-r--r-- | src/openvpn/list.h (renamed from list.h) | 0 | ||||
-rw-r--r-- | src/openvpn/lladdr.c (renamed from lladdr.c) | 8 | ||||
-rw-r--r-- | src/openvpn/lladdr.h (renamed from lladdr.h) | 0 | ||||
-rw-r--r-- | src/openvpn/lzo.c (renamed from lzo.c) | 59 | ||||
-rw-r--r-- | src/openvpn/lzo.h | 347 | ||||
-rw-r--r-- | src/openvpn/manage.c (renamed from manage.c) | 465 | ||||
-rw-r--r-- | src/openvpn/manage.h (renamed from manage.h) | 75 | ||||
-rw-r--r-- | src/openvpn/mbuf.c (renamed from mbuf.c) | 6 | ||||
-rw-r--r-- | src/openvpn/mbuf.h (renamed from mbuf.h) | 0 | ||||
-rw-r--r-- | src/openvpn/memdbg.h (renamed from memdbg.h) | 0 | ||||
-rw-r--r-- | src/openvpn/misc.c (renamed from misc.c) | 759 | ||||
-rw-r--r-- | src/openvpn/misc.h (renamed from misc.h) | 136 | ||||
-rw-r--r-- | src/openvpn/mroute.c (renamed from mroute.c) | 175 | ||||
-rw-r--r-- | src/openvpn/mroute.h (renamed from mroute.h) | 4 | ||||
-rw-r--r-- | src/openvpn/mss.c (renamed from mss.c) | 6 | ||||
-rw-r--r-- | src/openvpn/mss.h (renamed from mss.h) | 0 | ||||
-rw-r--r-- | src/openvpn/mstats.c | 122 | ||||
-rw-r--r-- | src/openvpn/mstats.h (renamed from mudp.h) | 29 | ||||
-rw-r--r-- | src/openvpn/mtcp.c (renamed from mtcp.c) | 9 | ||||
-rw-r--r-- | src/openvpn/mtcp.h (renamed from mtcp.h) | 9 | ||||
-rw-r--r-- | src/openvpn/mtu.c (renamed from mtu.c) | 6 | ||||
-rw-r--r-- | src/openvpn/mtu.h (renamed from mtu.h) | 68 | ||||
-rw-r--r-- | src/openvpn/mudp.c (renamed from mudp.c) | 20 | ||||
-rw-r--r-- | src/openvpn/mudp.h | 71 | ||||
-rw-r--r-- | src/openvpn/multi.c (renamed from multi.c) | 261 | ||||
-rw-r--r-- | src/openvpn/multi.h (renamed from multi.h) | 166 | ||||
-rw-r--r-- | src/openvpn/ntlm.c (renamed from ntlm.c) | 69 | ||||
-rw-r--r-- | src/openvpn/ntlm.h (renamed from ntlm.h) | 0 | ||||
-rw-r--r-- | src/openvpn/occ-inline.h (renamed from occ-inline.h) | 0 | ||||
-rw-r--r-- | src/openvpn/occ.c (renamed from occ.c) | 10 | ||||
-rw-r--r-- | src/openvpn/occ.h (renamed from occ.h) | 0 | ||||
-rw-r--r-- | src/openvpn/openvpn.c (renamed from openvpn.c) | 82 | ||||
-rw-r--r-- | src/openvpn/openvpn.h (renamed from openvpn.h) | 204 | ||||
-rwxr-xr-x | src/openvpn/openvpn.vcxproj | 263 | ||||
-rw-r--r-- | src/openvpn/openvpn.vcxproj.filters | 458 | ||||
-rw-r--r-- | src/openvpn/openvpn_win32_resources.rc | 43 | ||||
-rw-r--r-- | src/openvpn/options.c (renamed from options.c) | 1511 | ||||
-rw-r--r-- | src/openvpn/options.h (renamed from options.h) | 191 | ||||
-rw-r--r-- | src/openvpn/otime.c (renamed from otime.c) | 90 | ||||
-rw-r--r-- | src/openvpn/otime.h (renamed from otime.h) | 17 | ||||
-rw-r--r-- | src/openvpn/packet_id.c (renamed from packet_id.c) | 170 | ||||
-rw-r--r-- | src/openvpn/packet_id.h (renamed from packet_id.h) | 11 | ||||
-rw-r--r-- | src/openvpn/perf.c (renamed from perf.c) | 6 | ||||
-rw-r--r-- | src/openvpn/perf.h (renamed from perf.h) | 0 | ||||
-rw-r--r-- | src/openvpn/pf-inline.h (renamed from pf-inline.h) | 0 | ||||
-rw-r--r-- | src/openvpn/pf.c (renamed from pf.c) | 16 | ||||
-rw-r--r-- | src/openvpn/pf.h (renamed from pf.h) | 0 | ||||
-rw-r--r-- | src/openvpn/ping-inline.h (renamed from ping-inline.h) | 0 | ||||
-rw-r--r-- | src/openvpn/ping.c (renamed from ping.c) | 6 | ||||
-rw-r--r-- | src/openvpn/ping.h (renamed from ping.h) | 0 | ||||
-rw-r--r-- | src/openvpn/pkcs11.c (renamed from pkcs11.c) | 122 | ||||
-rw-r--r-- | src/openvpn/pkcs11.h (renamed from pkcs11.h) | 6 | ||||
-rw-r--r-- | src/openvpn/pkcs11_backend.h | 75 | ||||
-rw-r--r-- | src/openvpn/pkcs11_openssl.c | 192 | ||||
-rw-r--r-- | src/openvpn/pkcs11_polarssl.c | 126 | ||||
-rw-r--r-- | src/openvpn/platform.c | 344 | ||||
-rw-r--r-- | src/openvpn/platform.h | 140 | ||||
-rw-r--r-- | src/openvpn/plugin.c (renamed from plugin.c) | 156 | ||||
-rw-r--r-- | src/openvpn/plugin.h (renamed from plugin.h) | 45 | ||||
-rw-r--r-- | src/openvpn/pool.c (renamed from pool.c) | 81 | ||||
-rw-r--r-- | src/openvpn/pool.h (renamed from pool.h) | 7 | ||||
-rw-r--r-- | src/openvpn/proto.c (renamed from proto.c) | 6 | ||||
-rw-r--r-- | src/openvpn/proto.h (renamed from proto.h) | 52 | ||||
-rw-r--r-- | src/openvpn/proxy.c (renamed from proxy.c) | 282 | ||||
-rw-r--r-- | src/openvpn/proxy.h (renamed from proxy.h) | 30 | ||||
-rw-r--r-- | src/openvpn/ps.c (renamed from ps.c) | 128 | ||||
-rw-r--r-- | src/openvpn/ps.h (renamed from ps.h) | 4 | ||||
-rw-r--r-- | src/openvpn/push.c (renamed from push.c) | 122 | ||||
-rw-r--r-- | src/openvpn/push.h (renamed from push.h) | 5 | ||||
-rw-r--r-- | src/openvpn/pushlist.h (renamed from pushlist.h) | 0 | ||||
-rw-r--r-- | src/openvpn/reliable.c (renamed from reliable.c) | 10 | ||||
-rw-r--r-- | src/openvpn/reliable.h | 480 | ||||
-rw-r--r-- | src/openvpn/route.c (renamed from route.c) | 2060 | ||||
-rw-r--r-- | src/openvpn/route.h (renamed from route.h) | 172 | ||||
-rw-r--r-- | src/openvpn/schedule.c (renamed from schedule.c) | 6 | ||||
-rw-r--r-- | src/openvpn/schedule.h (renamed from schedule.h) | 0 | ||||
-rw-r--r-- | src/openvpn/session_id.c (renamed from session_id.c) | 10 | ||||
-rw-r--r-- | src/openvpn/session_id.h (renamed from session_id.h) | 4 | ||||
-rw-r--r-- | src/openvpn/shaper.c (renamed from shaper.c) | 10 | ||||
-rw-r--r-- | src/openvpn/shaper.h (renamed from shaper.h) | 4 | ||||
-rw-r--r-- | src/openvpn/sig.c (renamed from sig.c) | 28 | ||||
-rw-r--r-- | src/openvpn/sig.h (renamed from sig.h) | 2 | ||||
-rw-r--r-- | src/openvpn/socket.c (renamed from socket.c) | 1221 | ||||
-rw-r--r-- | src/openvpn/socket.h (renamed from socket.h) | 245 | ||||
-rw-r--r-- | src/openvpn/socks.c (renamed from socks.c) | 65 | ||||
-rw-r--r-- | src/openvpn/socks.h (renamed from socks.h) | 3 | ||||
-rw-r--r-- | src/openvpn/ssl.c (renamed from ssl.c) | 2685 | ||||
-rw-r--r-- | src/openvpn/ssl.h | 507 | ||||
-rw-r--r-- | src/openvpn/ssl_backend.h | 435 | ||||
-rw-r--r-- | src/openvpn/ssl_common.h | 498 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.c | 1175 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.h | 58 | ||||
-rw-r--r-- | src/openvpn/ssl_polarssl.c | 870 | ||||
-rw-r--r-- | src/openvpn/ssl_polarssl.h | 82 | ||||
-rw-r--r-- | src/openvpn/ssl_verify.c | 1265 | ||||
-rw-r--r-- | src/openvpn/ssl_verify.h | 252 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_backend.h | 249 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_openssl.c | 622 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_openssl.h | 76 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_polarssl.c | 409 | ||||
-rw-r--r-- | src/openvpn/ssl_verify_polarssl.h | 82 | ||||
-rw-r--r-- | src/openvpn/status.c (renamed from status.c) | 55 | ||||
-rw-r--r-- | src/openvpn/status.h (renamed from status.h) | 6 | ||||
-rw-r--r-- | src/openvpn/syshead.h (renamed from syshead.h) | 204 | ||||
-rw-r--r-- | src/openvpn/tun.c (renamed from tun.c) | 1111 | ||||
-rw-r--r-- | src/openvpn/tun.h (renamed from tun.h) | 28 | ||||
-rw-r--r-- | src/openvpn/win32.c (renamed from win32.c) | 258 | ||||
-rw-r--r-- | src/openvpn/win32.h (renamed from win32.h) | 32 | ||||
-rw-r--r-- | src/openvpnserv/Makefile.am | 27 | ||||
-rw-r--r-- | src/openvpnserv/Makefile.in (renamed from service-win32/Makefile.in) | 200 | ||||
-rwxr-xr-x | src/openvpnserv/openvpnserv.c (renamed from service-win32/openvpnserv.c) | 28 | ||||
-rw-r--r-- | src/openvpnserv/openvpnserv.vcxproj | 112 | ||||
-rw-r--r-- | src/openvpnserv/openvpnserv.vcxproj.filters | 35 | ||||
-rw-r--r-- | src/openvpnserv/openvpnserv_resources.rc | 43 | ||||
-rw-r--r-- | src/openvpnserv/service.c (renamed from service-win32/service.c) | 5 | ||||
-rw-r--r-- | src/openvpnserv/service.h (renamed from service-win32/service.h) | 4 | ||||
-rw-r--r-- | src/plugins/Makefile.am | 15 | ||||
-rw-r--r-- | src/plugins/Makefile.in | 613 | ||||
-rw-r--r-- | src/plugins/auth-pam/Makefile.am | 27 | ||||
-rw-r--r-- | src/plugins/auth-pam/Makefile.in | 619 | ||||
-rw-r--r-- | src/plugins/auth-pam/README.auth-pam (renamed from plugin/auth-pam/README) | 2 | ||||
-rw-r--r-- | src/plugins/auth-pam/auth-pam.c (renamed from plugin/auth-pam/auth-pam.c) | 29 | ||||
-rw-r--r-- | src/plugins/auth-pam/auth-pam.exports | 4 | ||||
-rw-r--r-- | src/plugins/auth-pam/pamdl.c (renamed from plugin/auth-pam/pamdl.c) | 8 | ||||
-rw-r--r-- | src/plugins/auth-pam/pamdl.h (renamed from plugin/auth-pam/pamdl.h) | 4 | ||||
-rw-r--r-- | src/plugins/down-root/Makefile.am | 23 | ||||
-rw-r--r-- | src/plugins/down-root/Makefile.in | 612 | ||||
-rw-r--r-- | src/plugins/down-root/README.down-root (renamed from plugin/down-root/README) | 0 | ||||
-rw-r--r-- | src/plugins/down-root/down-root.c (renamed from plugin/down-root/down-root.c) | 6 | ||||
-rw-r--r-- | src/plugins/down-root/down-root.exports | 4 | ||||
-rw-r--r-- | ssl.h | 849 | ||||
-rwxr-xr-x | tap-win32/MAKEFILE | 6 | ||||
-rwxr-xr-x | tap-win32/SOURCES.in | 64 | ||||
-rwxr-xr-x | tap-win32/common.h | 82 | ||||
-rwxr-xr-x | tap-win32/constants.h | 52 | ||||
-rwxr-xr-x | tap-win32/dhcp.c | 599 | ||||
-rwxr-xr-x | tap-win32/dhcp.h | 164 | ||||
-rwxr-xr-x | tap-win32/endian.h | 35 | ||||
-rwxr-xr-x | tap-win32/error.c | 378 | ||||
-rwxr-xr-x | tap-win32/error.h | 88 | ||||
-rwxr-xr-x | tap-win32/hexdump.c | 69 | ||||
-rwxr-xr-x | tap-win32/hexdump.h | 63 | ||||
-rwxr-xr-x | tap-win32/i386/OemWin2k.inf.in | 195 | ||||
-rwxr-xr-x | tap-win32/instance.c | 241 | ||||
-rwxr-xr-x | tap-win32/lock.h | 75 | ||||
-rwxr-xr-x | tap-win32/macinfo.c | 154 | ||||
-rwxr-xr-x | tap-win32/macinfo.h | 38 | ||||
-rwxr-xr-x | tap-win32/mem.c | 186 | ||||
-rwxr-xr-x | tap-win32/proto.h | 224 | ||||
-rwxr-xr-x | tap-win32/prototypes.h | 260 | ||||
-rwxr-xr-x | tap-win32/resource.rc | 58 | ||||
-rwxr-xr-x | tap-win32/tapdrvr.c | 3145 | ||||
-rwxr-xr-x | tap-win32/types.h | 178 | ||||
-rw-r--r-- | tests/Makefile.am | 23 | ||||
-rw-r--r-- | tests/Makefile.in | 518 | ||||
-rwxr-xr-x | tests/t_client.sh (renamed from t_client.sh) | 72 | ||||
-rwxr-xr-x | tests/t_client.sh.in (renamed from t_client.sh.in) | 64 | ||||
-rwxr-xr-x | tests/t_cltsrv-down.sh (renamed from t_cltsrv-down.sh) | 0 | ||||
-rwxr-xr-x | tests/t_cltsrv.sh (renamed from t_cltsrv.sh) | 14 | ||||
-rwxr-xr-x | tests/t_lpback.sh (renamed from t_lpback.sh) | 5 | ||||
-rw-r--r-- | version.m4 | 12 | ||||
-rw-r--r-- | version.sh.in | 4 | ||||
-rw-r--r-- | win/__init__.py | 0 | ||||
-rw-r--r-- | win/autodefs.h.in | 31 | ||||
-rw-r--r-- | win/build.py | 23 | ||||
-rw-r--r-- | win/build_all.py | 69 | ||||
-rw-r--r-- | win/build_ddk.py | 55 | ||||
-rw-r--r-- | win/build_exe.py | 15 | ||||
-rw-r--r-- | win/config.h.in | 323 | ||||
-rw-r--r-- | win/config.py | 21 | ||||
-rw-r--r-- | win/config_all.py | 13 | ||||
-rw-r--r-- | win/config_tap.py | 35 | ||||
-rw-r--r-- | win/config_ti.py | 18 | ||||
-rw-r--r-- | win/js.py | 10 | ||||
-rw-r--r-- | win/make_dist.py | 107 | ||||
-rw-r--r-- | win/msvc.mak.in | 57 | ||||
-rwxr-xr-x | win/openvpn.nsi | 822 | ||||
-rwxr-xr-x | win/openvpn.nsi.orig | 822 | ||||
-rwxr-xr-x | win/setpath.nsi | 231 | ||||
-rw-r--r-- | win/settings.in | 87 | ||||
-rw-r--r-- | win/show.py | 9 | ||||
-rw-r--r-- | win/sign.py | 19 | ||||
-rw-r--r-- | win/tap_span.py | 129 | ||||
-rw-r--r-- | win/wb.py | 322 |
481 files changed, 64363 insertions, 30220 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..34463f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.c eol=lf +*.h eol=lf +*.rc eol=lf +*.txt eol=lf +*.bat eol=lf +*.vc*proj* eol=crlf +*.sln eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a04afff --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +*.[oa] +*.l[oa] +*.dll +*.exe +*.exe.* +*.obj +*.pyc +*.so +*~ +*.idb +*.suo +*.ncb +*.vcproj.* +*.vcxproj.user +*.sln.cache +*.log +Release +Debug +Win32-Output +.deps +.libs +Makefile +Makefile.in +aclocal.m4 +autodefs.h +autom4te.cache +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +configure.h +depcomp +stamp-h1 +install-sh +missing +ltmain.sh +libtool +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +version.sh +msvc-env-local.bat +config-msvc-local.h +config-msvc-version.h +doc/openvpn.8.html +distro/rpm/openvpn.spec +tests/t_client.sh +tests/t_client-*-20??????-??????/ +src/openvpn/openvpn +config-version.h @@ -1,67 +1,674 @@ OpenVPN Change Log -Copyright (C) 2002-2011 OpenVPN Technologies, Inc. <sales@openvpn.net> - -2011.07.01 -- Versoin 2.2.1 -David Sommerseth (4): - Don't define ENABLE_PUSH_PEER_INFO if SSL is not available - Fix compiling issues with pkcs11 when --disable-management is configured - Remove support for Linux 2.2 configuration fallback - Revert "Add new openssl.cnf to easy-rsa/Windows" - Prepared for releasing OpenVPN 2.2.1 - - Gustavo Zacarias (1): - Fix compile issues when using --enable-small and --disable-ssl/--disable-crypto - - Matthew L. Creech (1): - Fix 2.2.0 build failure when management interface disabled - - Robert Fischer (2): - Added info about --show-proxy-settings - Documented --x509-username-field option - - Samuli Seppänen (5): - Fix a build-ca issue on Windows - Add new openssl.cnf to easy-rsa/Windows - Updated "easy-rsa" for OpenSSL 1.0.0 - Made domake-win builds to use easy-rsa/2.0/openssl-1.0.0.cnf - Fixes to easy-rsa/2.0 - - Simon Matter (1): - Fix issues with some older GCC compilers - -2011.04.21 -- Version 2.2.0 -David Sommerseth (4): +Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net> + +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. + +Arne Schwabe (2): + Document man agent-external-key + Options parsing demands unnecessary configuration if PKCS11 is used + +David Sommerseth (2): + Make git ignore some more files + Remove the support for using system() when executing external programs or scripts + +Heiko Hund (2): + Fix display of plugin hook types + Support UTF-8 --client-config-dir + +Kenneth Rose (1): + Fix v3 plugins to support returning values back to OpenVPN. + +2012.09.12 -- Version 2.3_beta1 +Arne Schwabe (7): + Fixes error: --key fails with EXTERNAL_PRIVATE_KEY: No such file or directory if --management-external-key is used + Merge almost identical create_socket_tcp and create_socket_tcp6 + Document the inlining of files in openvpn and document key-direction + Merge getaddr_multi and getaddr6 into one function + Document --management-client and --management-signal a bit better + Document that keep alive will double the second value in server mode and give a short explanation why the value is chosen. + Add checks for external-key-managements + +David Sommerseth (1): + Fix reconnect issues when --push and UDP is used on the server + +Gert Doering (4): + Reduce --version string detail about IPv6 to just "[IPv6]". + Put actual OpenVPN command line on top of corresponding log file. + Keep pre-existing tun/tap devices around on *BSD + make "ipv6 ifconfig" on linux compatible with busybox ifconfig + +Heiko Hund (6): + fix regression with --http-proxy[-*] options + add x_msg_va() log function + add API for plug-ins to write to openvpn log + remove stale _openssl_get_subject() prototype + remove unused flag SSLF_NO_NAME_REMAPPING + Add --compat-names option + +2012.07.20 -- Version 2.3_alpha3 +Arne Schwabe (1): + Fix compiling with --disable-management + +Gert Doering (1): + Repair "tap server" mode brokenness caused by <stdbool.h> fallout + +Heiko Hund (4): + make non-blocking connect work on Windows + don't treat socket related errors special anymore + remove unused show_connection_list debug function + add option --management-query-proxy + +2012.06.29 -- Version 2.3_alpha2 +Adriaan de Jong (11): + Fixed off-by-one in serial length calculation + Migrated x509_get_subject to use of the garbage collector + Migrated x509_get_serial to use the garbage collector + Migrated x509_get_sha1_hash to use the garbage collector + Ensure sys/un.h autoconf detection includes sys/socket.h + Added support for new PolarSSL 1.1 RNG + Added a configuration option to enable prediction resistance in the PolarSSL random number generator. + Use POLARSSL_CFLAGS instead of POLARSSL_CRYPTO_CFLAGS in configure.ac + Removed support for PolarSSL < 1.1 + Updated README.polarssl with build system changes. + Removed stray "Fox-IT hardening" string. + +Alon Bar-Lev (94): + build: version should not contain '-' + package: rpm: strip should be handled by package management + cleanup: options.c: remove redundant include + cleanup: remove C++ warnings + cleanup: win32.c: wrong printf format + cleanup: remove redundant ';' + cleanup: crypto_openssl.c: remove support for pre-openssl-0.9.6 + cleanup: tun.c: fix incorrect option in message (ip-win32) + cleanup: memcmp.c: remove unused source + fixup: init.c: add missing conditional for ENABLE_CLIENT_CR + build: correct place to alter WINVER is at build system + Update .gitignore + build: handle printf style format in mingw + build: rename plugin directory to plugins + build: plugins: properly use CC, CFLAGS and LDFLAGS + build: we need the sample.ovpn in future + Remove install-win32 + Remove easy-rsa + Remove tap-win32 + cleanup: rename tap-windows function from win32 to win + build: remove windows specific build system + build: split acinclude.m4 into m4/* + build: m4/ax_varargs.m4: cleanup + build: m4/ax_emptyarray.m4: cleanup + build: m4/ax_socklen_t.m4: cleanup + build: autotools: first pass of trivial autotools changes + build: autoconf: remove OPENVPN_ADD_LIBS useless macro + build: remove awk and non-standard autoconf output processing + build: standard directory layout + build: add libtool + windows resources for executables + build: autoconf: commands as environment + build: libdl usage + build: properly detect and use socket libs + build: autoconf: minor cleanups + build: proper selinux detection and usage + build: distribute pkg.m4 + build: proper pkcs11-helper detection and usage + build: properly process lzo-stub + build: proper lzo detection and usage + build: proper crypto detection and usage + build: autoconf: update defaults for options + build: win-msvc: msbuild format + build: move out config.h include from syshead + build: split out compat + build: move gettimeofday() emulation to compat + build: move daemon() emulation into compat + build: move inet_ntop(), inet_pton() emulation into compat + cleanup: move console related function into its own module + build: move wrappers into platform module + build: windows: install version.sh to allow installer read version + build: distribute samples in windows + build: use tap-windows.h as external dependency + build: ax_varargs.m4: fixups + build: autoconf: misc sockets fixups + build: enable lzo by default + build: windows: set vendor to openvpn project + cleanups + build: assume dlfcn is available on all supported platforms + build: openbsd: detect netinet/ip.h correctly + build: tap: search for tap header + build: msvc: upgrade to Visual Studio 2010 + fixups + Enable pedantic in windows compilation + cleanup: flags should not be bool + cleanup: avoid using ~0 - generic + cleanup: avoid using ~0 - ipv6 + cleanup: avoid using ~0 - netmask + cleanup: avoid using ~0 - windows + cleanup: gc usage + build: fix some statement left from conversion + build: properly detect netinet/ip.h structs + build: properly detect TUNSETPERSIST + cleanup: plugin: support C++ plugin + cleanup: remove C++ comments + cleanup: add .gitattributes to control eol style explicitly + crash: packet_id_debug_print: sl may be null + build: use stdbool.h if available + build: fix typo in --enable-save-password + build: windows: convert resources to UTF-8 + build: check minimum polarssl version + cleanup: update .gitignore + cleanup: spec: make space/tab consistent + build: spec: we support openssl >= 0.9.7 + build: insall README* document using build system + build: detect sys/wait.h required for *bsd + build: add git revision to --version output if build from git repository + build: cleanup: yet another forgotten brackets + build: update INSTALL to recent changes + build: support platforms that does not need explicit tun headers + build: do not support <polarssl-1.1.0 + build: add --with-special-build to provide special build string + cleanup: pkcs11.c: resolve wanings + build: integrate plugins build into core build + build: plugins: set defaults based on platform + cleanup: windows: convert argv (UCS-2 to UTF-8) at earliest + build: msvc: chdir with change drive to script location + +Arne Schwabe (7): + Add the query to the error message. + Explain that route-nopull also causes the client to ignore dhcp options. + Add the name of the context where option is not allowed to the error message. + Only use tmpdir if tmp_dir is really used. + Completely remove ancient IANA port warning. + Remove ENABLE_INLINE_FILES conditionals + Remove ENABLE_CONNECTIONS ifdefs + +David Sommerseth (5): + Clean-up: Presume that Linux is always IPv6 capable at build time + Simplify check_cmd_access() function + Change version to indicate the master branch is not a version + Some filesystems don't like ':', which is a path 'make dist' would use + Remove two unused functions + +Frank de Brabander (1): + Fix reported compile issues on OSX 10.6.8 + +Gert Doering (10): + repair t_client.sh test after build system revolution + t_client.sh iproute2 script fixes + t_client.sh - fix for iproute2, print summary line + Implement search for "first free" tun/tap device on Solaris + cleanup and redefine metric handling for IPv6 routes + remove "*option" element in "struct route_ipv6" + Remove warning about explicit support for IPv6 support not provided MacOS X + Add missing pieces to IPv6 route gateway handling. + Update TODO.IPv6 list + Remove #include "config.h" from ssl_polarssl.h + +Heiko Hund (3): + remove wrapper code for Windows CryptoAPI function + fix warnings in event.c when building for win32-64 + remove the --auto-proxy option from openvpn + +Igor Novgorodov (1): + Remove calls to OpenSSL when building with --disable-ssl + +Jonathan K. Bullard (2): + Fix file access checks on commands + Clarified the docs and help screen about what a 'cmd' is + +Samuli Seppänen (1): + Added notes about upgrading from 2.3-alpha1 and earlier to INSTALL-win32.txt + +2012.02.21 -- Version 2.3-alpha1 +Adriaan de Jong (127): + Added Doxygen doxyfile + Changed configure to accept --with-ssl-type=openssl + Refactored to rand_bytes for OpenSSL-independency + Refactored OpenSSL-specific constants + Refactored maximum cipher and hmac length constants + Refactored show_available_* functions + Refactored SSL_clear_error() + Refactored crypto initialisation functions + Refactored DES key manipulation functions + Refactored NTLM DES key generation + Refactored message digest type functions + Refactored message digest functions + Refactored HMAC functions + Refactored cipher key types + Refactored cipher functions + Added PRNG doxygen + Refactored: Moved crypto.h inline functions to end of file + Removed stale OpenSSL defines from crypto.h + Added a check for Openssl or PolarSSL defines + Refactored: Added stubs for new files + Refactored SSL initialisation functions + Refactored TLS_PRF to new hmac and md primitives + Refactored tls_show_available_ciphers + Refactored get_highest_preference_tls_cipher + Refactored root SSL context initialisation + Refactored new external key code + Refactored DH paramater loading + Refactored root TLS option settings + Refactored PKCS#12 key loading + Refactored PKCS#11 loading + Refactored windows cert loading + Refactored load certificate functions + Refactored private key loading code + Refactored external key loading from management + Refactored CA and extra certs code + Refactored cipher restriction code + Refactored tls_options, key_state, and key_source data structures + Refactored initalisation of key_states + Refactored key_state free code + Refactored print_details + Refactored key_state read code (including bio_read()) + Refactored key_state write functions + Refactored: Moved BIO debug functions to OpenSSL backend + Refactored: removed ks and ks_lame macro for clarity + Refactored: moved write_empty_string function back + Refactored Doxygen for tls_multi functions + Migrated data structures needed by verification functions to ssl_common.h + Refactored client_config_dir_exclusive function + Refactored certificate hash lock checks + Refactored common name locking functions + Refactored username and password authentication code + Add some extra comments + Refactored: split verify_callback into two parts + Added function to extract and verify the subject from a certificate + Added function to verify and extract the username + Refactored: removed global x509_username_field + Refactored: separated environment setup during verification + Refactored: Netscape certificate type verification + Refactored key usage verification code + Refactored EKU verification + Refactored tls-remote checking + Refactored tls-verify-plugin code + Refactored tls-verify script code + Refactored CRL checks + Minor cleanup in verify_cert: + Refactored: Moved verify_cert to ssl_verify + Cleaned up ssl.h + Refactored: made M_SSL dependent on USE_OPENSSL + Refactored: renamed X509 functions from verify_* + Separated OpenSSL-specific parts of the PKCS#11 driver + Modified base64 code in preparation for PolarSSL merge + Final cleanup before PolarSSL addition: + Refactored X509 track feature to be contained within the openssl backend + Added PolarSSL support: + Fixed a missing include in ssl_backend.h + Fixed a bug in the hash generation in ssl_verify_openssl.c + Added SHA_DIGEST_SIZE definition + Changed PolarSSL crypto backend to support v0.99-pre5 + Updated ssl_polarssl.c to work with 0.99-pre5 + Fixed a compilation warning for size_t key sizes + Added a warning that the PolarSSL library does not support pkcs12 files. + Added warning that --capath is not available with PolarSSL + Disable CryptoAPI when not using OpenSSL, and document that fact. + Removed support for management external keys in PolarSSL + Removed stray X509_free from ssl.c + Refactored (and disabled for PolarSSL) support for writing external cert files in scripts + Added an extra define to allow building without PKCS#11 + Added SSL library to title string + Disabled X.509 track and username selection for PolarSSL + Hardening: periodically reset the PRNG's nonce value + Fixes for the plugin system: + Further improvements to plugin support: + Fixed an unintentional change in the options calculated key size. + Moved print messages back to generic crypto.c from cipher backends + Moved HMAC prints back to main crypto module + Added back checks for ks->authenticated in verify_user_pass + Moved gc_new and gc_free to begin end of function + Fixed a bug in the return value of ssl_verify when pre_verify failed + Unified verification function return values: + Removed a stray Fox-IT tag + Fixed a typo: print the subject instead of the serial for verification errors + Made SSL_CIPHER const in print_details, to fix warning + Moved to PolarSSL 1.0.0: + Added missing #ifdef to allow --disable-managent to work again + Fixed disabling crypto and SSL + Got rid of a few magic numbers in ntlm.c + Removed obsolete des_cblock and des_keyschedule + Further removal of des_old.h based calls + Fixed missing comma in plugin.h + Moved prng_uninit out of crypto_uninit_lib + Moved CryptoAPI header include to the ssl_openssl.c + Reordered functions to ensure warning-free Windows build + Added options to switch between OpenSSL and PolarSSL and PKCS11... + Moved from strsep to strtok, for Windows compatibility + Minor cleanup to enable warning-free Windows build: + Fixed a typo when initialising cryptoapi certs + Minor code cleanup: cleaned up error handling in verify_cert. + Moved out of memory prototype to error.h, as the definition is in error.c + Removed support for calling gc_malloc with a NULL gc_arena struct + + (The follwing patches from Adriaan was mistakenly merged with + the wrong commit author in the git tree) + Doxygen: Added data channel crypto docs + Added control channel crypto docs + Added compression docs + Added reliability layer documentation + Added memory management documentation + Added data channel fragmentation docs + Added main/control docs + Moved doxygen-specific files to a separate directory + +Byron Ellacott (1): + autoconf fixes for building on OSX + +David Sommerseth (50): + Provide 'dev_type' environment variable to plug-ins and script hooks + Define the new openvpn_plugin_{open,func}_v3() API + Implement the core v3 plug-in function calls. + Extend the v3 plug-in API to send over X509 certificates + Added a simple plug-in demonstrating the v3 plug-in API. + Separate the general plug-in version constant and v3 plug-in structs version + Use a version-less version identifier on the master branch Fix the --client-cert-not-required feature Change the default --tmp-dir path to a more suitable path Improve the mysprintf() issue in openvpnserv.c Add a simple comment regarding openvpn_snprintf() is duplicated - -Gert Doering (1): + Merge branch 'feat_ipv6_transport' + Merge branch 'feat_ipv6_payload' + Merge branch 'svn-branch-2.1' into merge + Solved hidden merge conflicts between master and svn-branch-2.1 + Fix const declarations in plug-in v3 structs + Merge remote-tracking branch 'cron2/feat_ipv6_payload_2.3' + Don't define ENABLE_PUSH_PEER_INFO if SSL is not available + Fix compiling issues with pkcs11 when --disable-management is configured + Remove support for Linux 2.2 configuration fallback + Revert "Add new openssl.cnf to easy-rsa/Windows" + Merge remote branch SVN 2.1 into the git tree + Merge branch 'svn-merger' + Fix Microsoft Visual Studio incompatibility in plugin.c + Fixed compile issues on FreeBSD and Solaris + Fix PolarSSL and --pkcs12 option issues + Fix FreeBSD/OpenBSD/NetBSD compiler warnings in get_default_gateway() + Make '--win-sys env' default + Do some file/directory tests before really starting openvpn + Fix bug after removing Linux 2.2 support + Don't look for 'stdin' file when using --auth-user-pass + Fix compiling with --disable-crypto and/or --disable-ssl + Fix a couple of issues in openvpn_execve() + Move away from openvpn_basename() over to platform provided basename() + Enable access() when building in Visual Studio + New Windows build fixes + Fix compilation errors on Linux platforms without SO_MARK + autotools ./configure don't like compat.h + Fix pool logging when IPv6 is not enabled + Don't check for file presence on inline files + Add --route-pre-down/OPENVPN_PLUGIN_ROUTE_PREDOWN script/plug-in hook + Enhance the error handling in _openssl_get_subject() + Fix assert() situations where gc_malloc() is called without a gc_arena object + Fix compile issues when plug-ins are disabled. + Remove --show-gateway if debug info is not enabled (--disable-debug) + Fix compile issues with status.c + Connection entry {tun,link}_mtu_defined not set correctly + Makefile.am referenced a now non-existing config-win32.h + Makefile.am was missing ssl_common.h + Revamp check_file_access() checks in stdin scenarios + +Davide Guerri (1): + New feauture: Add --stale-routes-check + +Frank de Brabander (1): + Fixed wrong return type of cipher_kt_mode + +Frederic Crozat (1): + Add support to forward console query to systemd + +Gert Doering (45): Add more detailed explanation regarding the function of "--rdns-internal" + Enable IPv6 Payload in OpenVPN p2mp tun server mode. 20100104-1 release. + remove NOTES file from commit - private scribbling + NetBSD fixes - on 4.0 and up, use multi-af mode. + new feature: "ifconfig-ipv6-push" (from ccd/ config) + add some TODOs to TODO.IPv6 + undo accidential duplication of existing "--iroute" line in the help text + basic documentation of IPv6 related options and their syntax + Enable IPv6 Payload in OpenVPN p2mp tun server mode. + remove NOTES file from commit - private scribbling + env_block(): if PATH is not set, add standard PATH setting to env + add IPv6 route add / route delete code for windows (using "netsh") + - Win32 IPv6 ifconfig support, using "netsh" calls + drop "book ipv6" from open_tun() and tuncfg() prototypes + document recent changes and open TODOs, adapt --version info, tag release + Win32: set next-hop for IPv6 routes according to TUN/TAP mode + when deleting a route on win32, also add gateway address + WIN32: if IPv6 requested in TUN mode, check if TUN/TAP driver < 9.7 + revert unconditionally-enabling of setenv_es() logging + implement IPv6 ifconfig + route setup/deletion on OpenBSD + full "VPN client connect" test framework for OpenVPN t_client.rc-sample + renamed t_client.sh to t_client.sh.in + 2.2-beta3 has a signed TAP driver with the IPv6 code - test for 9.8 + correct URL for "more information about IPv6 patch is *here*" + bugfix for linux/iproute2: IPv6 ifconfig code block was not called for "dev tun"+"topology subnet" + bump IPv6 version number (openvpn --version) to 20100922-1 + Implement "ipv6 ifconfig" for TAP interfaces on Solaris interfaces + rebased to 2.2RC2 (beta 2.2 branch) + Windows IPv6 cleanup - properly remove IPv6 routes and interface config + For all accesses to "struct route_list * rl", check first that rl is non-NULL + Replace 32-bit-based add_in6_addr() implementation by an 8-bit based one + Platform cleanup for NetBSD + Move block for "stale-routes-check" config inside #ifdef P2MP_SERVER block + add missing break between "case IPv4" and "case IPv6" + bump tap driver version from 9.8 to 9.9 + log error message and exit for "win32, tun mode, tap driver version 9.8" + work around inet_ntop/inet_pton problems for MSVC builds on WinXP + Fix build-up of duplicate IPv6 routes on reconnect. + Fix list-overrun checks in copy_route_[ipv6_]option_list() + add "print test titles" and "use sudo" functionality to t_client.rc + Platform cleanup for FreeBSD + Implement IPv6 interface config with non-/64 prefix lengths. + Fix RUN_SUDO functionality for t_client.sh + Document IPv6-related environment variables. + Platform cleanup for OpenBSD Gisle Vanem (1): Avoid re-defining uint32_t when using mingw compiler -James Yonan (1): - Fixed bug in port-share that could cause port share process to crash with output like this: +Gustavo Zacarias (1): + Fix compile issues when using --enable-small and --disable-ssl/--disable-crypto + +Heiko Hund (16): + add .gitignore to official repository + remove function is_proto_tcp() + remove legacy code to query IE proxy information + lowercase include header name in syshead.h + define IN6_ARE_ADDR_EQUAL macro for WIN32 + add --mark option to set SO_MARK sockopt + Windows UTF-8 input/output + UTF-8 X.509 distinguished names + set Windows environment variables as UCS-2 + handle Windows unicode paths + replace check for TARGET_WIN32 with WIN32 + do not use mode_t on Windows + use the underscore version of stat on Windows + make MSVC link against shell32 as well + move variable declaration to top of function + define access mode flag X_OK as 0 on Windows + +Igor Novgorodov (1): + The code blocks enabled by ENABLE_CLIENT_CR depends on management + +James Yonan (57): + Added "management-external-key" option. + Minor addition of logging info before and after execution of Windows net commands. + Misc fixes to r6708. + Added --x509-track option. + * added --management-up-down option to allow management interface to be notified of tunnel up/down events. + Fixed minor compile issue triggered on builds where MANAGEMENT_DEF_AUTH is not enabled. + Implemented get_default_gateway_mac_addr for Mac OS X + Fixes to r6925. + Properly handle certificate serial numbers > 32 bits. + Added "client-nat" option for stateless, one-to-one NAT on the client side. + Renamed branch to reflect that it is no longer beta. + env_filter_match now includes the serial number of all certs + Fixed issue where a client might receive multiple push replies from a server + Fixed bug introduced in r7031 that might cause this error message: + Extended "client-kill" management interface command (server-side) + Client will now try to reconnect if no push reply received within handshake-window seconds. + Version 2.1.3n + Fixed compiling issues when using --disable-crypto + Added "management-external-key" option. + Misc fixes to r6708. + win/sign.py now accepts an optional tap-dir argument. + Added "auth-token" client directive + Added ./configure --enable-osxipconfig option for Mac OS X + Added more packet ID debug info at debug level 3 for debugging false positive packet replays. + Fixed bug that incorrectly placed stricter TCP packet replay rules on UDP sessions + Fixed bug in port-share that could cause port share process to crash + For Mac OSX, when DARWIN_USE_IPCONFIG is defined, retry ipconfig command on failure + Version 2.1.3t + Revert r7092 and r7151, i.e. remove --enable-osxipconfig configure option. + Added 'dir' flag to "crl-verify" (see man page for info). + Added new "extra-certs" and "verify-hash" options + Fixed compile issues on Windows. + Added --enable-lzo-stub configure option to build an OpenVPN client without LZO + Added optional journal directory argument to "port-share" directive + Reduce log verbosity at level 3, with a focus on removing excessive log verbosity generated by port-share activity. + env_filter_match now includes the serial number of all certs in chain + Added support for static challenge/response protocol. + r7316 fixes. + Added redirect-gateway block-local flag, with support for Linux, Mac OS X + Extended x509-track to allow SHA1 certificate hash to be extracted + Added "management-query-remote" directive (client) to allow the management interface to override the "remote" directive. + Version 2.1.5. + Fixed MSVC compile error related to r7408. + Redact "echo" directive strings from log, since these strings (going forward) could conceivably contain security-sensitive data. + Modified sanitize_control_message to remove redacted data from control string rather than blotting it out with "_" chars. + Changed CC_PRINT character class to allow UTF-8 chars. + Increased the --verb threshold for "PID_ERR replay" messages to 4 from 3. + Fixed issue where redirect-gateway block-local code was not correctly calculating... + CC_PRINT character class now allows any 8-bit character value >= 32. + "status" management interface command (version >= 2) will now include the username for each connected user. + Minor fix to CC_PRINT char class + Fixed management interface bug where >FATAL notifications were not being output properly + Raised D_PID_DEBUG_LOW from level 3 to 4 to reduce replay error verbosity at level 3. + Added "memstats" option to maintain real-time operating stats in a memory-mapped file. + Fixed client issues with DHCP Router option extraction/deletion when using layer 2 with DHCP proxy: + Allow "tap-win32 dynamic <offset>" to be used in topology subnet mode. + Added support for "on-link" routes on Linux client + +Jan Just Keijser (1): + Made some options connection-entry specific + +Joe Patterson (1): + common_name passing in auth_pam plugin + +JuanJo Ciarlante (40): + * rebased openvpn-2.1_rc1b.jjo.20061206.d.patch + * created getaddr6(), use it from resolve_remote() + * migrated all getaddrinfo() to getaddr6 + * socket.c: use USE_PF_INET6 in switch constructs to actually toss them out, + * support --disable-ipv6 build properly: + * important fix for tcp6 reconnection was incorrectly creating a PF_INET socket + * added README.ipv6.txt + * fixed win32 non-ipv6 build + * ipv6 on win32 "milestone": 1st snapshot that passes all unittests + * document ipv6 milestone status + * doc update w/unittests results + * make possible to x-compile openvpn/win32 in Linux + * correctly setup hints.ai_socktype for getaddrinfo(), althought sorta hacky, see TODO.ipv6. + * renamed README.ipv6{.txt,} + * updated {README,TODO}.ipv6 from feedback at openvpn-devel mlist + * init.c: document the ENABLE_MANAGEMENT place to work on + * init.c: small in-doc tweaks + * fix multi-tcp crash (corrected assertion) + * TODO.ipv6 update + * socket.c: better buf logic in print_sockaddr_ex + * fixed segfault for undef address family in print_sockaddr_ex (thanks Marcel!) + * doc updates + * openbsd: no IFF_MULTICAST, #ifdef around it + * no new funcionality, just small cleanups + * (prototype) fix for supporting "redirect-gateway" for tunneled ipv4 over ipv6 endpoints + * polished redirect-gateway (ipv4 on ipv6 endpoints) support + * updated doc + * fix --disable-ipv6 build + * doc updates + * rebased to v2.1.1 release + * undo mroute.c changes related to ipv6 payload + * fix --multihome for ipv4 + * fix --multihome for ipv6 + * ipv6-0.4.14: fix xinetd usage + * ipv6-0.4.15: add --multihome support to xBSD + * ipv6-0.4.15b: rebase over openvpn-testing-master + * ipv6-0.4.16: fix mingw32 build + * make ipv6_payload compile under windowze + USE_PF_INET6 by default for v2.3 + fix ipv6 compilation under macosx >= 1070 - v3 + +Markus Koetter (1): + Add extv3 X509 field support to --x509-username-field + +Matthew L. Creech (1): + Fix 2.2.0 build failure when management interface disabled + +Matthias Andree (1): + Skip rather than fail test in addressless FreeBSD jails. -Robert Fischer / rf (4): +Robert Fischer (8): Update man page with info about --capath Update man page with info about --connect-timeout + Added info about --show-proxy-settings + Documented --x509-username-field option + Documented --errors-to-stderr option + Documented --push-peer-info option Update man page with info about --remote-random-hostname Added man page entry for --management-client -Samuli Seppänen (6): +Samuli Seppänen (19): Add man page entry for --redirect-private Change all CRLF linefeeds to LF linefeeds Fix a bug in devcon source code handling Removed Win2k from supported platforms list in INSTALL and win/openvpn.nsi Fixed copying of tapinstall.exe to dist/bin when using prebuilt TAP-drivers Fixed a bug with GUI icon deletion on upgrade from 2.2-RC or earlier + Fix a build-ca issue on Windows + Add new openssl.cnf to easy-rsa/Windows + Updated "easy-rsa" for OpenSSL 1.0.0 + Made domake-win builds to use easy-rsa/2.0/openssl-1.0.0.cnf + Fixes to easy-rsa/2.0 + Merged TODO.IPv6 with TODO.ipv6 and README.IPv6 with README.ipv6 + Fixed a number of fatal build errors on Visual Studio 2008 + Fix a Visual Studio 2008 build issue in socket.c + Additional Visual Studio 2008 build fixes to tun.c + Fixed a typo in win32.h that prevented building with Visual Studio + Fixed a regression causing VS2008/Python build failure + Fix a Visual Studio 2008 build error in tun.c + Fix a Visual Studio 2008 build error in options.c + +Simon Matter (1): + Fix issues with some older GCC compilers + +Stefan Hellermann (2): + plugin.h: update prototype of plugin_call dummy in !ENABLE_PLUGIN case + Fixed typo in plugin.h chantra (1): Clarify --tmp-dir option +smos (1): + Change the netsh.exe command from "add" to "set". + +2011.12.25 -- Version 2.x-master +James Yonan (1): + Added support for "on-link" routes on Linux client -- these are + routes where the gateway is specified as an interface rather than + an address. This allows redirect-gateway to work on Linux clients + whose connection to the internet is via a point-to-point link + such as PPP. + + Note that at the moment, this capability is incompatible with + the "redirect-gateway block-local" directive -- this is because + the block-local directive blocks all traffic from the local LAN + except for the local and gateway addresses. Since a PPP link + is essentially a subnet of two addresses, local and remote (i.e. + gateway), the set of addresses that would be blocked by block-local + is empty. Therefore, the "redirect-gateway block-local" directive + will be ignored on PPP links. + + To view the OpenVPN client's current determination of the default + gateway, use this command: + + ./openvpn --show-gateway + 2011.03.24 -- Version 2.2-RC2 Alon Bar-Lev (1): Windows cross-compile cleanup @@ -60,28 +60,30 @@ OPTIONAL (but recommended): (2) 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 - to add "--with-lzo-headers" and "--with-lzo-lib" directives to - "configure", pointing to /usr/local/include and /usr/local/lib - respectively since gcc will not find them otherwise. + to add CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" + directives to "configure", since gcc will not find them otherwise. (3) Pthread library. OPTIONAL (for developers only): - (1) Autoconf 2.50 or higher + Automake 1.5 or higher + (1) Autoconf 2.59 or higher + Automake 1.9 or higher -- available from http://www.gnu.org/software/software.html (2) Dmalloc library -- available from http://dmalloc.com/ ************************************************************************* -CHECK OUT SOURCE FROM SUBVERSION REPOSITORY: +CHECK OUT SOURCE FROM SOURCE REPOSITORY: + + git clone https://github.com/OpenVPN/openvpn Check out stable version: - svn checkout http://svn.openvpn.net/projects/openvpn/trunk/openvpn openvpn + git checkout -b 2.2 remotes/origin/release/2.2 + + Check out master (unstable) branch: - Check out beta21 branch: + git checkout master - svn checkout http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn openvpn ************************************************************************* @@ -93,18 +95,18 @@ BUILD COMMANDS FROM TARBALL: ************************************************************************* -BUILD COMMANDS FROM SUBVERSION REPOSITORY CHECKOUT: +BUILD COMMANDS FROM SOURCE REPOSITORY CHECKOUT: - autoreconf -i -v + autoreconf -i -v -f ./configure make make install ************************************************************************* -BUILD A TARBALL FROM SUBVERSION REPOSITORY CHECKOUT: +BUILD A TARBALL FROM SOURCE REPOSITORY CHECKOUT: - autoreconf -i -v + autoreconf -i -v -f ./configure make dist @@ -121,36 +123,85 @@ Test Crypto: Test SSL/TLS negotiations (runs for 2 minutes): -./openvpn --config sample-config-files/loopback-client (In one window) -./openvpn --config sample-config-files/loopback-server (Simultaneously in another window) +./openvpn --config sample/sample-config-files/loopback-client (In one window) +./openvpn --config sample/sample-config-files/loopback-server (Simultaneously in another window) ************************************************************************* OPTIONS for ./configure: - --enable-pthread Compile pthread support for - improved latency during SSL/TLS key - negotiations (Linux or Solaris only) - - --disable-lzo Do not compile LZO compression support - --disable-crypto Do not compile OpenSSL crypto support - --disable-ssl Do not compile OpenSSL SSL support for - TLS-based key exchange - - --with-ssl-headers=DIR Crypto/SSL Include files location - --with-ssl-lib=DIR Crypto/SSL Library location - --with-lzo-headers=DIR LZO Include files location - --with-lzo-lib=DIR LZO Library location - - --with-ifconfig-path=PATH Path to ifconfig tool (only need to - specify if in a non-standard location) - - --with-leak-check=TYPE Build with memory leak checking - TYPE = dmalloc or ssl - - --enable-strict Enable strict compiler warnings - - --enable-strict-options Enable strict options check between peers + --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-crypto disable crypto support [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] + --disable-multi disable client/server support (--mode server + + client mode) [default=yes] + --disable-server disable server support only (but retain client + support) [default=yes] + --disable-plugins disable plug-in support [default=yes] + --disable-eurephia disable support for the eurephia plug-in + [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) + [default=yes] + --disable-port-share disable TCP server port-share support (--port-share) + [default=yes] + --disable-debug disable debugging support (disable gremlin and verb + 7+ messages) [default=yes] + --enable-small enable smaller executable size (disable OCC, usage + message, and verb 4 parm list) [default=yes] + --enable-password-save allow --askpass and --auth-user-pass passwords to be + read from a file [default=yes] + --enable-iproute2 enable support for iproute2 [default=no] + --disable-def-auth disable deferred authentication [default=yes] + --disable-pf disable internal packet filter [default=yes] + --enable-strict enable strict compiler warnings (debugging option) + [default=no] + --enable-pedantic enable pedantic compiler warnings, will not generate + a working executable (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] + +ENVIRONMENT for ./configure: + + IFCONFIG full path to ipconfig utility + ROUTE full path to route utility + IPROUTE full path to ip utility + NETSTAT path to netstat utility + 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 + POLARSSL_CFLAGS + C compiler flags for polarssl + POLARSSL_LIBS + linker flags for polarssl + LZO_CFLAGS C compiler flags for lzo + LZO_LIBS linker flags for lzo + PKCS11_HELPER_CFLAGS + C compiler flags for PKCS11_HELPER, overriding pkg-config + PKCS11_HELPER_LIBS + linker flags for PKCS11_HELPER, overriding pkg-config ************************************************************************* @@ -316,28 +367,3 @@ CAVEATS & BUGS: IV for OFB and CFB modes. This is not an issue if you are using CBC cipher mode (the default), or if you are using OFB or CFB cipher mode with SSL/TLS authentication. - -****************************************************************************** - -Subject: [Openvpn-users] Re: Windows XP 64 bit -From: Hypherion -Date: Thu, 14 Apr 2005 07:01:17 +0000 (UTC) - -Well I managed to build a Windows XP 64 bit driver myself and it's working -great, I can connect to my server again :) - -I had to use the WinDDK for Windows 2003 Service Pack 1 and just built the -driver in the Windows 2003 AMD64 environment. I had to comment out the -MAPINFO:FIXUPS directive in the SOURCES file. - -Then I copied and renamed (devcon.exe/tapinstall.exe) from -C:\WINDDK\3790.1830\tools\devcon\amd64. - -I had to edit the file OemWin2k.inf and change the Manufactured + Product -Section to: - -[Manufacturer] - %Provider% = tap0901, NTamd64 - -[tap0901.NTamd64] - %DeviceDescription% = tap0901.ndi, tap0901 diff --git a/INSTALL-win32.txt b/INSTALL-win32.txt index 5a0f3a9..1ef3869 100644 --- a/INSTALL-win32.txt +++ b/INSTALL-win32.txt @@ -1,3 +1,28 @@ +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 diff --git a/Makefile.am b/Makefile.am index f311837..c580579 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,7 @@ # # Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> # Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@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 @@ -23,142 +24,78 @@ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -LDADD = @LIBOBJS@ -.PHONY: plugin - # This option prevents autoreconf from overriding our COPYING and # INSTALL targets: -AUTOMAKE_OPTIONS = foreign +AUTOMAKE_OPTIONS = foreign 1.9 +ACLOCAL_AMFLAGS = -I m4 MAINTAINERCLEANFILES = \ config.log config.status \ $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \ $(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \ + $(srcdir)/m4/libtool.m4 $(srcdir)/m4/lt~obsolete.m4 \ + $(srcdir)/m4/ltoptions.m4 $(srcdir)/m4/ltsugar.m4 \ + $(srcdir)/m4/ltversion.m4 \ $(srcdir)/depcomp $(srcdir)/aclocal.m4 \ - $(srcdir)/config.guess $(srcdir)/config.sub \ - $(srcdir)/openvpn.spec -CLEANFILES = openvpn.8.html configure.h + $(srcdir)/config.guess $(srcdir)/config.sub + +CLEANFILES = \ + config-version.h EXTRA_DIST = \ - easy-rsa \ - sample-config-files \ - sample-keys \ - sample-scripts \ - suse \ - tap-win32 \ contrib \ - debug \ - plugin \ - win + debug -SUBDIRS = \ - images \ - service-win32 \ - install-win32 +.PHONY: config-version.h -TESTS = t_client.sh t_lpback.sh t_cltsrv.sh -sbin_PROGRAMS = openvpn +if GIT_CHECKOUT +BUILT_SOURCES = \ + config-version.h +endif -dist_doc_DATA = \ - management/management-notes.txt +SUBDIRS = build distro include src sample doc tests -dist_noinst_SCRIPTS = \ - $(TESTS) \ - doclean \ - domake-win \ - t_cltsrv-down.sh \ - configure_h.awk configure_log.awk +dist_doc_DATA = \ + README \ + README.IPv6 \ + README.polarssl \ + COPYRIGHT.GPL \ + COPYING dist_noinst_DATA = \ - openvpn.spec \ - COPYRIGHT.GPL \ + .gitignore \ + .gitattributes \ + config-version.h.in \ PORTS \ - INSTALL-win32.txt \ - service-win32/msvc.mak + README.IPv6 TODO.IPv6 \ + README.polarssl \ + openvpn.sln \ + msvc-env.bat \ + msvc-dev.bat \ + msvc-build.bat -openvpn_SOURCES = \ - base64.c base64.h \ - basic.h \ - buffer.c buffer.h \ - circ_list.h \ - common.h \ - crypto.c crypto.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 \ - mroute.c mroute.h \ - mss.c mss.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 \ - openvpn.c openvpn.h \ - openvpn-plugin.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 \ - ieproxy.h ieproxy.c \ - 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 \ - status.c status.h \ - syshead.h \ - tun.c tun.h \ - win32.h win32.c \ - cryptoapi.h cryptoapi.c - -nodist_openvpn_SOURCES = configure.h -options.$(OBJEXT): configure.h - -configure.h: Makefile - awk -f $(srcdir)/configure_h.awk config.h > $@ - awk -f $(srcdir)/configure_log.awk config.log >> $@ +if WIN32 +dist_doc_DATA += INSTALL-win32.txt +else +dist_noinst_DATA += INSTALL-win32.txt +endif -dist-hook: - cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done +dist_noinst_HEADERS = \ + config-msvc.h \ + config-msvc-version.h.in if WIN32 -dist_noinst_DATA += openvpn.8 -nodist_html_DATA = openvpn.8.html -openvpn.8.html: $(srcdir)/openvpn.8 - $(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html -else -dist_man_MANS = openvpn.8 +rootdir=$(prefix) +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 + @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; \ + else \ + rm -f config-version.h.tmp; \ + fi diff --git a/Makefile.in b/Makefile.in index 87cabd4..288589e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -24,6 +24,7 @@ # # Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> # Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@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 @@ -41,7 +42,6 @@ # - VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -61,63 +61,33 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = openvpn$(EXEEXT) -@WIN32_TRUE@am__append_1 = openvpn.8 +@WIN32_TRUE@am__append_1 = INSTALL-win32.txt +@WIN32_FALSE@am__append_2 = INSTALL-win32.txt subdir = . -DIST_COMMON = README $(am__configure_deps) \ - $(am__dist_noinst_DATA_DIST) $(dist_doc_DATA) $(dist_man_MANS) \ - $(dist_noinst_SCRIPTS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(srcdir)/openvpn.spec.in $(srcdir)/t_client.sh.in \ +DIST_COMMON = README $(am__configure_deps) $(am__dist_doc_DATA_DIST) \ + $(am__dist_noinst_DATA_DIST) $(dist_noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(srcdir)/version.sh.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ - config.guess config.sub depcomp install-sh memcmp.c missing + config.guess config.sub depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac +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) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = t_client.sh openvpn.spec +CONFIG_CLEAN_FILES = version.sh CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" \ - "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" -PROGRAMS = $(sbin_PROGRAMS) -am_openvpn_OBJECTS = base64.$(OBJEXT) buffer.$(OBJEXT) \ - crypto.$(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) \ - mroute.$(OBJEXT) mss.$(OBJEXT) mtcp.$(OBJEXT) mtu.$(OBJEXT) \ - mudp.$(OBJEXT) multi.$(OBJEXT) ntlm.$(OBJEXT) occ.$(OBJEXT) \ - pkcs11.$(OBJEXT) openvpn.$(OBJEXT) options.$(OBJEXT) \ - otime.$(OBJEXT) packet_id.$(OBJEXT) perf.$(OBJEXT) \ - pf.$(OBJEXT) ping.$(OBJEXT) plugin.$(OBJEXT) pool.$(OBJEXT) \ - proto.$(OBJEXT) proxy.$(OBJEXT) ieproxy.$(OBJEXT) ps.$(OBJEXT) \ - push.$(OBJEXT) reliable.$(OBJEXT) route.$(OBJEXT) \ - schedule.$(OBJEXT) session_id.$(OBJEXT) shaper.$(OBJEXT) \ - sig.$(OBJEXT) socket.$(OBJEXT) socks.$(OBJEXT) ssl.$(OBJEXT) \ - status.$(OBJEXT) tun.$(OBJEXT) win32.$(OBJEXT) \ - cryptoapi.$(OBJEXT) -nodist_openvpn_OBJECTS = -openvpn_OBJECTS = $(am_openvpn_OBJECTS) $(nodist_openvpn_OBJECTS) -openvpn_LDADD = $(LDADD) -openvpn_DEPENDENCIES = @LIBOBJS@ -SCRIPTS = $(dist_noinst_SCRIPTS) -DEFAULT_INCLUDES = -I.@am__isrc@ -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) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(openvpn_SOURCES) $(nodist_openvpn_SOURCES) -DIST_SOURCES = $(openvpn_SOURCES) +SOURCES = +DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ @@ -125,6 +95,8 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive +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/||"`;; \ @@ -146,12 +118,13 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -man8dir = $(mandir)/man8 -NROFF = nroff -MANS = $(dist_man_MANS) -am__dist_noinst_DATA_DIST = openvpn.spec COPYRIGHT.GPL PORTS \ - INSTALL-win32.txt service-win32/msvc.mak openvpn.8 -DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(nodist_html_DATA) +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 \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -159,8 +132,6 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -200,6 +171,8 @@ distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -212,11 +185,17 @@ 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@ @@ -225,15 +204,40 @@ 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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ MAKEINFO = @MAKEINFO@ MAN2HTML = @MAN2HTML@ 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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -242,19 +246,35 @@ 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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ -TAP_ID = @TAP_ID@ -TAP_WIN32_MIN_MAJOR = @TAP_WIN32_MIN_MAJOR@ -TAP_WIN32_MIN_MINOR = @TAP_WIN32_MIN_MINOR@ +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@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ @@ -289,9 +309,11 @@ 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@ @@ -300,127 +322,48 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -win32datadir = @win32datadir@ -LDADD = @LIBOBJS@ # This option prevents autoreconf from overriding our COPYING and # INSTALL targets: -AUTOMAKE_OPTIONS = foreign +AUTOMAKE_OPTIONS = foreign 1.9 +ACLOCAL_AMFLAGS = -I m4 MAINTAINERCLEANFILES = \ config.log config.status \ $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \ $(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \ + $(srcdir)/m4/libtool.m4 $(srcdir)/m4/lt~obsolete.m4 \ + $(srcdir)/m4/ltoptions.m4 $(srcdir)/m4/ltsugar.m4 \ + $(srcdir)/m4/ltversion.m4 \ $(srcdir)/depcomp $(srcdir)/aclocal.m4 \ - $(srcdir)/config.guess $(srcdir)/config.sub \ - $(srcdir)/openvpn.spec + $(srcdir)/config.guess $(srcdir)/config.sub + +CLEANFILES = \ + config-version.h -CLEANFILES = openvpn.8.html configure.h EXTRA_DIST = \ - easy-rsa \ - sample-config-files \ - sample-keys \ - sample-scripts \ - suse \ - tap-win32 \ contrib \ - debug \ - plugin \ - win - -SUBDIRS = \ - images \ - service-win32 \ - install-win32 - -TESTS = t_client.sh t_lpback.sh t_cltsrv.sh -dist_doc_DATA = \ - management/management-notes.txt - -dist_noinst_SCRIPTS = \ - $(TESTS) \ - doclean \ - domake-win \ - t_cltsrv-down.sh \ - configure_h.awk configure_log.awk - -dist_noinst_DATA = openvpn.spec COPYRIGHT.GPL PORTS INSTALL-win32.txt \ - service-win32/msvc.mak $(am__append_1) -openvpn_SOURCES = \ - base64.c base64.h \ - basic.h \ - buffer.c buffer.h \ - circ_list.h \ - common.h \ - crypto.c crypto.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 \ - mroute.c mroute.h \ - mss.c mss.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 \ - openvpn.c openvpn.h \ - openvpn-plugin.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 \ - ieproxy.h ieproxy.c \ - 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 \ - status.c status.h \ - syshead.h \ - tun.c tun.h \ - win32.h win32.c \ - cryptoapi.h cryptoapi.c - -nodist_openvpn_SOURCES = configure.h -@WIN32_TRUE@nodist_html_DATA = openvpn.8.html -@WIN32_FALSE@dist_man_MANS = openvpn.8 -all: config.h + debug + +@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) +dist_noinst_HEADERS = \ + config-msvc.h \ + config-msvc-version.h.in + +@WIN32_TRUE@rootdir = $(prefix) +@WIN32_TRUE@root_DATA = version.sh +all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -.SUFFIXES: .c .o .obj am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @@ -472,166 +415,17 @@ $(srcdir)/config.h.in: $(am__configure_deps) distclean-hdr: -rm -f config.h stamp-h1 -t_client.sh: $(top_builddir)/config.status $(srcdir)/t_client.sh.in +version.sh: $(top_builddir)/config.status $(srcdir)/version.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ -openvpn.spec: $(top_builddir)/config.status $(srcdir)/openvpn.spec.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" - @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(sbindir)" && rm -f $$files - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) -openvpn$(EXEEXT): $(openvpn_OBJECTS) $(openvpn_DEPENDENCIES) - @rm -f openvpn$(EXEEXT) - $(LINK) $(openvpn_OBJECTS) $(openvpn_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memcmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cryptoapi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmisc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forward.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fragment.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gremlin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpdigest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ieproxy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lladdr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manage.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mroute.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtcp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mudp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occ.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet_id.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ping.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reliable.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_id.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shaper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.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@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` -install-man8: $(dist_man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" - @list=''; test -n "$(man8dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.8[a-z]*$$/p'; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ - done; } -uninstall-man8: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man8dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.8[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" @@ -652,26 +446,26 @@ uninstall-dist_docDATA: test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(docdir)" && rm -f $$files -install-nodist_htmlDATA: $(nodist_html_DATA) +install-rootDATA: $(root_DATA) @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" - @list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \ + test -z "$(rootdir)" || $(MKDIR_P) "$(DESTDIR)$(rootdir)" + @list='$(root_DATA)'; test -n "$(rootdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(rootdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(rootdir)" || exit $$?; \ done -uninstall-nodist_htmlDATA: +uninstall-rootDATA: @$(NORMAL_UNINSTALL) - @list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \ + @list='$(root_DATA)'; test -n "$(rootdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(htmldir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(htmldir)" && rm -f $$files + echo " ( cd '$(DESTDIR)$(rootdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(rootdir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. @@ -808,112 +602,7 @@ GTAGS: 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; 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 \ - echo "$$grn$$dashes"; \ - else \ - echo "$$red$$dashes"; \ - fi; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes$$std"; \ - test "$$failed" -eq 0; \ - else :; fi - distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -973,9 +662,6 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ @@ -1092,15 +778,16 @@ distcleancheck: distclean $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-recursive -all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) config.h +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(DATA) $(HEADERS) config.h installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)"; do \ + for dir in "$(DESTDIR)$(docdir)" "$(DESTDIR)$(rootdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-recursive +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive @@ -1126,17 +813,17 @@ distclean-generic: 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 "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-tags +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags dvi: dvi-recursive @@ -1150,14 +837,13 @@ info: info-recursive info-am: -install-data-am: install-dist_docDATA install-man \ - install-nodist_htmlDATA +install-data-am: install-dist_docDATA install-rootDATA install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-html: install-html-recursive @@ -1167,7 +853,7 @@ install-info: install-info-recursive install-info-am: -install-man: install-man8 +install-man: install-pdf: install-pdf-recursive @@ -1182,13 +868,12 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive -mostlyclean-am: mostlyclean-compile mostlyclean-generic +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive @@ -1198,45 +883,42 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-dist_docDATA uninstall-man \ - uninstall-nodist_htmlDATA uninstall-sbinPROGRAMS +uninstall-am: uninstall-dist_docDATA uninstall-rootDATA -uninstall-man: uninstall-man8 - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ - ctags-recursive install-am install-strip tags-recursive +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-TESTS check-am clean \ - clean-generic clean-sbinPROGRAMS ctags ctags-recursive dist \ - dist-all dist-bzip2 dist-gzip dist-hook dist-lzma dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dist_docDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man8 install-nodist_htmlDATA install-pdf \ - install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ - ps ps-am tags tags-recursive uninstall uninstall-am \ - uninstall-dist_docDATA uninstall-man uninstall-man8 \ - uninstall-nodist_htmlDATA uninstall-sbinPROGRAMS - -.PHONY: plugin -options.$(OBJEXT): configure.h - -configure.h: Makefile - awk -f $(srcdir)/configure_h.awk config.h > $@ - awk -f $(srcdir)/configure_log.awk config.log >> $@ - -dist-hook: - cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done -@WIN32_TRUE@openvpn.8.html: $(srcdir)/openvpn.8 -@WIN32_TRUE@ $(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-dist_docDATA 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-rootDATA 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-recursive uninstall uninstall-am \ + uninstall-dist_docDATA uninstall-rootDATA + + +.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 + @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; \ + else \ + rm -f config-version.h.tmp; \ + fi # 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/README.IPv6 b/README.IPv6 new file mode 100644 index 0000000..d504f4f --- /dev/null +++ b/README.IPv6 @@ -0,0 +1,97 @@ +IPv6 payload support +-------------------- + +Latest IPv6 payload support code and documentation can be found from here: + + http://www.greenie.net/ipv6/openvpn.html + +For TODO list, see TODO.IPv6. + +Gert Doering, 31.12.2009 + + + +IPv6 transport support +---------------------- + +[ Last updated: 25-Mar-2011. ] + +OpenVPN-2.1 over UDP6/TCP6 README for ipv6-0.4.x patch releases: +( --udp6 and --tcp6-{client,server} ) + +* Availability + Source code under GPLv2 from http://github.com/jjo/openvpn-ipv6 + + Distro ready repos/packages: + o Debian sid official repo, by Alberto Gonzalez Iniesta, + starting from openvpn_2.1~rc20-2 + o Gentoo official portage tree, by Marcel Pennewiss: + - https://bugs.gentoo.org/show_bug.cgi?id=287896 + o Ubuntu package, by Bernhard Schmidt: + - https://launchpad.net/~berni/+archive/ipv6/+packages + o Freetz.org, milestone freetz-1.2 + - http://trac.freetz.org/milestone/freetz-1.2 + +* Status: + o OK: + - upd6,tcp6: GNU/Linux, win32, openbsd-4.7, freebsd-8.1 + - udp4->upd6,tcp4->tcp6 (ipv4/6 mapped): GNU/Linux + (gives a warning on local!=remote proto matching) + o NOT: + - win32: tcp4->tcp6 (ipv4/6 mapped) fails w/connection refused + o NOT tested: + - mgmt console + +* Build setup: + ./configure --enable-ipv6 (by default) + +* Usage: + For IPv6 just specify "-p upd6" an proper IPv6 hostnames, adapting the example + from man page ... + + On may: + openvpn --proto udp6 --remote <june_IPv6_addr> --dev tun1 \ + --ifconfig 10.4.0.1 10.4.0.2 --verb 5 --secret key + + On june: + openvpn --proto udp6 --remote <may_IPv6_addr> --dev tun1 \ + --ifconfig 10.4.0.2 10.4.0.1 --verb 5 --secret key + + Same for --proto tcp6-client, tcp6-server. + +* Main code changes summary: + - socket.h: New struct openvpn_sockaddr type that holds sockaddrs and pktinfo, + (here I omitted #ifdef USE_PF_xxxx, see socket.h ) + + struct openvpn_sockaddr { + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } addr; + }; + + struct link_socket_addr + { + struct openvpn_sockaddr local; + struct openvpn_sockaddr remote; + struct openvpn_sockaddr actual; + }; + + PRO: allows simple type overloading: local.addr.sa, local.addr.in, local.addr.in6 ... etc + (also local.pi.in and local.pi.in6) + + - several function prototypes moved from sockaddr_in to openvpn_sockaddr + - several new sockaddr functions needed to "generalize" AF_xxxx operations: + addr_copy(), addr_zero(), ...etc + proto_is_udp(), proto_is_dgram(), proto_is_net() + +* For TODO list, see TODO.IPv6 + +-- +JuanJo Ciarlante jjo () google () com ............................ +: : +. Linux IP Aliasing author . +. Modular algo (AES et all) support for FreeSWAN/OpenSWAN author . +. OpenVPN over IPv6 support . +:...... plus other scattered free software bits in the wild ...: diff --git a/README.polarssl b/README.polarssl new file mode 100644 index 0000000..ab7c2d7 --- /dev/null +++ b/README.polarssl @@ -0,0 +1,28 @@ +This version of OpenVPN has PolarSSL support. To enable follow the following +instructions: + +To Build and Install, + + ./configure --with-crypto-library=polarssl + make + make install + +This version depends on at least PolarSSL v1.1. + +************************************************************************* + +Due to limitations in the PolarSSL library, the following features are missing +in the PolarSSL version of OpenVPN: + + * PKCS#12 file support + * --capath support - Loading certificate authorities from a directory + * Windows CryptoAPI support + * Management external key support + * X.509 alternative username fields (must be "CN") + +Plugin/Script features: + + * X.509 Serial number is in hex, not decimal as with OpenSSL + * X.509 subject line has a different format than the OpenSSL subject line + * X.509 certificate export does not work + * X.509 certificate tracking diff --git a/TODO.IPv6 b/TODO.IPv6 new file mode 100644 index 0000000..29d7554 --- /dev/null +++ b/TODO.IPv6 @@ -0,0 +1,209 @@ +TODO for IPv6 payload support +----------------------------- + +1.) "--topology subnet" doesn't work together with IPv6 payload on FreeBSD + (verified for FreeBSD server, Linux/ifconfig client, problems + with ICMP6 neighbor solicitations from BSD not being answered by Linux) + + * 2012-01-22 fixed in platform cleanup, commit 62c613d46dc495d74 + +2.) NetBSD IPv6 support doesn't work + ("connected" route is not auto-created, "route-ipv6" adding fails) + + * fixed, 3.1.10 * + +3.) route deletion for IPv6 routes is not yet done + + * fixed for configured routes, 3.1.10 * + * missing for manual-ifconfig-connected (NetBSD, Darwin, Win32) + + * 2012-06-10 - fixed somewhere in 2010 + +4.) do "ifconfig tun0 inet6 unplumb" or "ifconfig tun0 destroy" for + Solaris, *BSD, ... at program termination time, to clean up leftovers + (unless tunnel persistance is desired). + + For Solaris, only the "ipv6 tun0" is affected, for the *BSDs all tun0 + stay around. + + * 2012-06-10 - fixed in individual platform cleanups early-2012 + +4a.) deconfigure IPv6 on tun interface on session termination, otherwise + one could end up with something like this (on NetBSD): + +tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500 + inet 10.9.0.18 -> 10.9.0.17 netmask 0xffffffff + inet6 fe80::a00:20ff:fece:d299%tun0 -> prefixlen 64 scopeid 0x3 + inet6 2001:608:4:eff::2000:3 -> prefixlen 64 + inet6 2001:608:4:eff::1:3 -> prefixlen 64 + + (pool was changed, previous address still active on tun0, breakage) + + * semi-fixed for NetBSD, 28.2.10, always do tun0 destroy / tun0 create + before actual ifconfig -- tunnel still lingers after OpenVPN quits + + * 2011-09-16 fixed in platform cleanup, commit 8ca19c014c149cf69 + +4b.) verify this - on FreeBSD, tun0 is auto-destroyed if created by + opening /dev/tun (and lingers if created by "ifconfig tun0 create") + + -> use for persistant tunnels on not-linux? + + * 2012-06-10 tun interface behaviour is documented in "man tun(4)" + +5.) add new option "ifconfig-ipv6-push" + (per-client static IPv6 assignment, -> radiusplugin, etc) + + * implemented, 14.1.10 * + +6.) add new option "route-ipv6-gateway" + + * 2012-06-09 - decided there is no current need (but fairly trivial) + +7.) add "full" gateway handling for IPv6 in route.c + (right now, the routes are just sent down the tun interface, if the + operating system in questions supports that, without care for the + gateway address - which does not work for gateways that are supposed + to point elsewhere. Also, it doesn't work for TAP interfaces. + + * 2012-06-09 use "dev tun" for tun devices, "via $gateway" for tap + (and purposely do not support off-link routes) + +8.) full IPv6 support for TAP interfaces + (main issue should be routes+gateway - and testing :-) ) + + test 2010/09/24: TAP itself works on linux/ifconfig+iproute2, but + route-via-tap doesn't work at all (route points to "tap0" which fails) + +17:51:14.075412 fe:ab:6e:c5:53:71 > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2001:608:4:a053::1:0 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2001:608:4:a001::1, length 32 + + * 2012-06-09 missing gateway support implemented + +8a.) + how is iroute-via-tap supposed to work?? + + * 2012-06-10 - answer: not at all, OpenVPN doesn't do "iroute" in + tap mode - set up "route-ipv6" with gateway address = individual + client's tap0 address to get the per-client routes + + +9.) verify that iroute-ipv6 and route-ipv6 interact in the same way as + documented for iroute/route: + + A's subnet, OpenVPN must push this route to all clients + EXCEPT for A, since the subnet is already owned by A. + OpenVPN accomplishes this by not + not pushing a route to a client + if it matches one of the client's iroutes. + +10.) extend "ifconfig-ipv6" to handle specification of /netbits, pushing + of /netbits, and correctly ifconfig'ing this + (default, if not specified: /64) + + * done * 2012-02-03 + +11.) do not add ipv6-routes if tun-ipv6 is not set - complain instead + + * done * 12.1.10 + +12.) handle incoming [::] and [fe80:...] packets in tun-p2mp MULTI mode + (most likely those are DAD packets) + silently ignore DAD? + Or accept-and-forward iff (multicast && client2client)? + handle NS/NA + +13.) from Martin List-Petersen: + + One thing, and I guess this requires modifications in + network-manager-openvpn: It also works, BUT ignores "push + route-ipv6-gateway" and "push route-ipv6 ...." (obviously routes pushed + from the server) entirely. + +14.) from ##openvpn-discussion: + + new features should be #ifdef'ed + + (check whether this is feasible at all) + +15.) IPv6 related environment variables + + - document all of them in openvpn.8 + - make sure that all existing IPv4 stuff has IPv6 counterparts + +16.) OpenBSD + - implement ifconfig/route for IPv6 + - revert ifconfig/open_tun order to "normal" (separate commit!!!) + (openvpn-devel, Subject: OpenBSD) + - test + + * 2012-02-05 platform cleanup, commit 82d4e12068774b0a6ca + +17.) client-option (Elwood) + - ignore-v6-push-options yes/no + - ignore-v6-route-push ("as for IPv4 routes") + +18.) fail-save? "what if 'ip -6 addr add' fails" -> fail, or fallback to v4? + (-> recomment setting "ignore-v6-push-options yes") + +19.) safety check: if connecting over IPv6 (v6 transport) and the pushed + route-ipv6 network encompasses the server IPv6 address, make sure + we at least log a warning (until we can fiddle with external routing + to make this work correctly). + +20.) show "route add" / "route delete" commands for IPv6 in log file + (we show the "ifconfig" commands, so why not the routes?) + + 2010-08-07: this is a null-feature - it's already there, but with + different debug level (M_INFO vs. D_ROUTE) so user + didn't notice + +21.) enable ipv6-only server operations + - decouple ipv6 pool handling from ipv4 pool + - make sure Rest of OpenVPN doesn't assume "there will always be IPv4" + +22.) implement --learn-address for IPv6 + +23.) FreeBSD 8 seems to require explicit setting of the "ifconfig" IPv6 + route, while FreeBSD 6+7 don't --> more testing, and code fix + + workaround for the time being: just add + + server-ipv6 2001:608:4:a051::/64 + route-ipv6 2001:608:4:a051::/64 + + to the config + + (problem + workaround applies both to tun and tap style devices) + + * 2012-06-09 - this got fixed in one of the platform cleanups + + + + +TODO for IPv6 transport support +------------------------------- + +[ Last updated: 10-Jun-2012. ] + +* All platforms: + o mgmt console: as currently passes straight in_addr_t bits around + + 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 + + o use AI_PASSIVE + + o the getaddr()/getaddr6() interface is not prepared for handling socktype + "tagging", currently I abuse the sockflags bits for getting the ai_socktype + downstream. + + 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 + + +* 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 + diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index 185907f..0000000 --- a/acinclude.m4 +++ /dev/null @@ -1,127 +0,0 @@ -dnl Special Autoconf Macros for OpenVPN - -dnl OPENVPN_ADD_LIBS(LIB) -AC_DEFUN([OPENVPN_ADD_LIBS], [ - LIBS="$1 $LIBS" -]) - -dnl @synopsis AX_EMPTY_ARRAY -dnl -dnl Define EMPTY_ARRAY_SIZE to be either "0" -dnl or "" depending on which syntax the compiler -dnl prefers for empty arrays in structs. -dnl -dnl @version -dnl @author James Yonan <jim@yonan.net> - - -AC_DEFUN([AX_EMPTY_ARRAY], [ - AC_MSG_RESULT([checking for C compiler empty array support]) - AC_COMPILE_IFELSE( - [ - struct { int foo; int bar[[0]]; } mystruct; - ], [ - AC_DEFINE_UNQUOTED(EMPTY_ARRAY_SIZE, 0, [Dimension to use for empty array declaration]) - ], [ - AC_COMPILE_IFELSE( - [ - struct { int foo; int bar[[]]; } mystruct; - ], [ - AC_DEFINE_UNQUOTED(EMPTY_ARRAY_SIZE,, [Dimension to use for empty array declaration]) - ], [ - AC_MSG_ERROR([C compiler is unable to creaty empty arrays]) - ]) - ]) - ] -) - -dnl @synopsis AX_CPP_VARARG_MACRO_GCC -dnl -dnl Test if the preprocessor understands GNU GCC-style vararg macros. -dnl If it does, defines HAVE_CPP_VARARG_MACRO_GCC to 1. -dnl -dnl @version -dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de> -AC_DEFUN([AX_CPP_VARARG_MACRO_GCC], [dnl - AS_VAR_PUSHDEF([VAR],[ax_cv_cpp_vararg_macro_gcc])dnl - AC_CACHE_CHECK([for GNU GCC vararg macro support], VAR, [dnl - AC_COMPILE_IFELSE([ - #define macro(a, b...) func(a, b) - int func(int a, int b, int c); - int test() { return macro(1, 2, 3); } - ], [ VAR=yes ], [VAR=no])]) - if test $VAR = yes ; then - AC_DEFINE([HAVE_CPP_VARARG_MACRO_GCC], 1, - [Define to 1 if your compiler supports GNU GCC-style variadic macros]) - fi - AS_VAR_POPDEF([VAR])dnl -]) - -dnl @synopsis AX_CPP_VARARG_MACRO_ISO -dnl -dnl Test if the preprocessor understands ISO C 1999 vararg macros. -dnl If it does, defines HAVE_CPP_VARARG_MACRO_ISO to 1. -dnl -dnl @version -dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de> -AC_DEFUN([AX_CPP_VARARG_MACRO_ISO], [dnl - AS_VAR_PUSHDEF([VAR],[ax_cv_cpp_vararg_macro_iso])dnl - AC_CACHE_CHECK([for ISO C 1999 vararg macro support], VAR, [dnl - AC_COMPILE_IFELSE([ -#define macro(a, ...) func(a, __VA_ARGS__) - int func(int a, int b, int c); - int test() { return macro(1, 2, 3); } - ], [ VAR=yes ], [VAR=no])]) - if test $VAR = yes ; then - AC_DEFINE([HAVE_CPP_VARARG_MACRO_ISO], 1, - [Define to 1 if your compiler supports ISO C99 variadic macros]) - fi - AS_VAR_POPDEF([VAR])dnl -]) - -dnl -- The following is taken from curl's acinclude.m4 -- -dnl Check for socklen_t: historically on BSD it is an int, and in -dnl POSIX 1g it is a type of its own, but some platforms use different -dnl types for the argument to getsockopt, getpeername, etc. So we -dnl have to test to find something that will work. -AC_DEFUN([TYPE_SOCKLEN_T], -[ - AC_CHECK_TYPE([socklen_t], ,[ - AC_MSG_CHECKING([for socklen_t equivalent]) - AC_CACHE_VAL([curl_cv_socklen_t_equiv], - [ - case "$host" in - *-mingw*) curl_cv_socklen_t_equiv=int ;; - *) - # Systems have either "struct sockaddr *" or - # "void *" as the second argument to getpeername - curl_cv_socklen_t_equiv= - for arg2 in "struct sockaddr" void; do - for t in int size_t unsigned long "unsigned long"; do - AC_TRY_COMPILE([ - #include <sys/types.h> - #include <sys/socket.h> - - int getpeername (int, $arg2 *, $t *); - ],[ - $t len; - getpeername(0,0,&len); - ],[ - curl_cv_socklen_t_equiv="$t" - break - ]) - done - done - ;; - esac - - if test "x$curl_cv_socklen_t_equiv" = x; then - AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) - fi - ]) - AC_MSG_RESULT($curl_cv_socklen_t_equiv) - AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, - [type to use in place of socklen_t if not defined])], - [#include <sys/types.h> -#include <sys/socket.h>]) -]) @@ -961,4 +961,12 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([acinclude.m4]) +m4_include([m4/ax_emptyarray.m4]) +m4_include([m4/ax_socklen_t.m4]) +m4_include([m4/ax_varargs.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/pkg.m4]) diff --git a/build/Makefile.am b/build/Makefile.am new file mode 100644 index 0000000..b53ff52 --- /dev/null +++ b/build/Makefile.am @@ -0,0 +1,17 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + ltrc.inc + +SUBDIRS = msvc diff --git a/build/Makefile.in b/build/Makefile.in new file mode 100644 index 0000000..8490b03 --- /dev/null +++ b/build/Makefile.in @@ -0,0 +1,615 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# +VPATH = @srcdir@ +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 = build +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +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@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + ltrc.inc + +SUBDIRS = msvc +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) --gnu build/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu build/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. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive 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-recursive \ + 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/build/ltrc.inc b/build/ltrc.inc new file mode 100644 index 0000000..701f200 --- /dev/null +++ b/build/ltrc.inc @@ -0,0 +1,23 @@ +# +# 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) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +# Required to build Windows resource file + +RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) +LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) + +.rc.lo: + $(LTRCCOMPILE) -i "$<" -o "$@" + +.rc.o: + $(RCCOMPILE) -i "$<" -o "$@" + +.mc.rc: + $(WINDMC) "$<" diff --git a/build/msvc/Makefile.am b/build/msvc/Makefile.am new file mode 100644 index 0000000..7dc3def --- /dev/null +++ b/build/msvc/Makefile.am @@ -0,0 +1,15 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = msvc-generate diff --git a/build/msvc/Makefile.in b/build/msvc/Makefile.in new file mode 100644 index 0000000..fe42e2e --- /dev/null +++ b/build/msvc/Makefile.in @@ -0,0 +1,613 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +VPATH = @srcdir@ +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 = build/msvc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +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@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = msvc-generate +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) --gnu build/msvc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu build/msvc/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. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive 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-recursive \ + 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/build/msvc/msvc-generate/Makefile.am b/build/msvc/msvc-generate/Makefile.am new file mode 100644 index 0000000..539fb6c --- /dev/null +++ b/build/msvc/msvc-generate/Makefile.am @@ -0,0 +1,18 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + msvc-generate.vcxproj \ + Makefile.mak \ + msvc-generate.js diff --git a/build/msvc/msvc-generate/Makefile.in b/build/msvc/msvc-generate/Makefile.in new file mode 100644 index 0000000..3d70375 --- /dev/null +++ b/build/msvc/msvc-generate/Makefile.in @@ -0,0 +1,418 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +VPATH = @srcdir@ +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 = build/msvc/msvc-generate +DIST_COMMON = $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DATA = $(dist_noinst_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + msvc-generate.vcxproj \ + Makefile.mak \ + msvc-generate.js + +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) --gnu build/msvc/msvc-generate/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu build/msvc/msvc-generate/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 +TAGS: + +ctags: CTAGS +CTAGS: + + +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 $(DATA) +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +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 \ + 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 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/build/msvc/msvc-generate/Makefile.mak b/build/msvc/msvc-generate/Makefile.mak new file mode 100755 index 0000000..72415f1 --- /dev/null +++ b/build/msvc/msvc-generate/Makefile.mak @@ -0,0 +1,13 @@ +# 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) + +$(OUTPUT): $(INPUT) $(CONFIG) + cscript //nologo msvc-generate.js --config="$(CONFIG)" --input="$(INPUT)" --output="$(OUTPUT)" + +clean: + -del "$(OUTPUT)" diff --git a/build/msvc/msvc-generate/msvc-generate.js b/build/msvc/msvc-generate/msvc-generate.js new file mode 100644 index 0000000..d9564cf --- /dev/null +++ b/build/msvc/msvc-generate/msvc-generate.js @@ -0,0 +1,118 @@ +/* + * msvc-generate.js - string transformation + * + * Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> + * + * BSD License + * ============ + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * o 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. + * o Neither the name of the Alon Bar-Lev nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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. + * + */ + +var ForReading = 1; +var fso = new ActiveXObject("Scripting.FileSystemObject"); +var input = "nul"; +var output = "nul"; +var files = new Array(); +var env = new Array(); + +function initialize() { + for (var i=0;i<WScript.Arguments.length;i++) { + var arg = WScript.Arguments(i); + if (arg.match(/^--input=(.*)$/)) { + input=RegExp.$1; + } + else if (arg.match(/^--output=(.*)$/)) { + output=RegExp.$1; + } + else if (arg.match(/^--config=(.*)$/)) { + files.push(RegExp.$1); + } + else if (arg.match(/^--var=([^=]*)=(.*)$/)) { + env[RegExp.$1] = RegExp.$2; + } + } +} + +function process_config(vars, file) { + try { + var fin = fso.OpenTextFile(file, ForReading); + + while (!fin.AtEndOfStream) { + var content = fin.ReadLine(); + if (content.match(/^[ \t]*define\(\[(.*)\],[ \t]*\[(.*)\]\)[ \t]*/)) { + vars[RegExp.$1] = RegExp.$2; + } + } + } + catch(e) { + throw new Error(1, "Cannot process '" + file + "'."); + } +} + +function process_file(vars, input, output) { + var fin = fso.OpenTextFile(input, ForReading); + var fout = fso.CreateTextFile(output); + var content = fin.ReadAll(); + + for (var i in vars) { + content = content.replace(new RegExp("@"+i+"@", "g"), vars[i]); + } + + fout.Write(content); +} + +function build_vars() { + var vars = new Array(); + for (var f in files) { + process_config(vars, files[f]); + } + for (var e in env) { + vars[e] = env[e]; + } + return vars; +} + +function main() { + try { + initialize(); + + var vars = build_vars(); + + process_file( + vars, + input, + output + ); + + WScript.Quit(0); + } + catch(e) { + WScript.Echo("ERROR: when procssing " + output + ": " + e.description); + WScript.Quit(1); + } +} + +main(); diff --git a/build/msvc/msvc-generate/msvc-generate.vcxproj b/build/msvc/msvc-generate/msvc-generate.vcxproj new file mode 100644 index 0000000..8b7ec22 --- /dev/null +++ b/build/msvc/msvc-generate/msvc-generate.vcxproj @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{8598C2C8-34C4-47A1-99B0-7C295A890615}</ProjectGuid> + <RootNamespace>msvc-generate</RootNamespace> + <Keyword>MakeFileProj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Makefile</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake -f Makefile.mak all</NMakeBuildCommandLine> + <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake -f Makefile.mak clean all</NMakeReBuildCommandLine> + <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nmake -f Makefile.mak clean</NMakeCleanCommandLine> + <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">config-msvc-version.h</NMakeOutput> + <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> + <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> + <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> + <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> + <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake -f Makefile.mak all</NMakeBuildCommandLine> + <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake -f Makefile.mak clean all</NMakeReBuildCommandLine> + <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nmake -f Makefile.mak clean</NMakeCleanCommandLine> + <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">config-msvc-version.h</NMakeOutput> + <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> + <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath> + <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes> + <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath> + <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies> + </PropertyGroup> + <ItemDefinitionGroup> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="Makefile.mak" /> + <None Include="msc-generate.js" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/compat.m4 b/compat.m4 new file mode 100644 index 0000000..4c13254 --- /dev/null +++ b/compat.m4 @@ -0,0 +1,75 @@ +dnl OpenVPN -- An application to securely tunnel IP networks +dnl over a single UDP port, with support for SSL/TLS-based +dnl session authentication and key exchange, +dnl packet encryption, packet authentication, and +dnl packet compression. +dnl +dnl Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program (see the file COPYING included with this +dnl distribution); if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +dnl Compatibility layer for <autoconf-2.60 <automake-1.10 +dnl REMOVE THIS IN FUTURE! + +ifdef( + [AS_VAR_IF], + , + [ + AC_DEFUN([AS_VAR_IF], [dnl + if test "$$1" = "$2"; then + m4_ifval([$3], [$3], [:]) + else + m4_ifval([$4], [$4], [:]) + fi + ]) + ] +) +ifdef( + [AC_USE_SYSTEM_EXTENSIONS], + , + [AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS], [GNU_SOURCE])] +) +ifdef( + [AC_PROG_SED], + , + [AC_DEFUN([AC_PROG_SED], [AC_CHECK_PROGS([SED], [sed])])] +) +ifdef( + [AC_TYPE_INT8_T], + , + [ + AC_CHECK_HEADERS([inttypes.h stdint.h]) + test -z "${ac_cv_header_inttypes_h}${ac_cv_header_stdint_h}" && \ + AC_MSG_ERROR([Required inttypes.h stdint.h not found]) + + AC_DEFUN([AC_TYPE_INT8_T], []) + AC_DEFUN([AC_TYPE_INT16_T], []) + AC_DEFUN([AC_TYPE_INT32_T], []) + AC_DEFUN([AC_TYPE_INT64_T], []) + AC_DEFUN([AC_TYPE_UINT8_T], []) + AC_DEFUN([AC_TYPE_UINT16_T], []) + AC_DEFUN([AC_TYPE_UINT32_T], []) + AC_DEFUN([AC_TYPE_UINT64_T], []) + ] +) +if test -z "${docdir}"; then + docdir="\$(datadir)/doc/\$(PACKAGE_NAME)" + AC_SUBST([docdir]) +fi +if test -z "${htmldir}"; then + htmldir="\$(docdir)" + AC_SUBST([htmldir]) +fi diff --git a/config-msvc-version.h.in b/config-msvc-version.h.in new file mode 100644 index 0000000..4bc89e7 --- /dev/null +++ b/config-msvc-version.h.in @@ -0,0 +1,10 @@ +#define PACKAGE_NAME "@PRODUCT_NAME@" +#define PACKAGE_STRING "@PRODUCT_NAME@ @PRODUCT_VERSION@" +#define PACKAGE_TARNAME "@PRODUCT_TARNAME@" +#define PACKAGE "@PRODUCT_TARNAME@" +#define PACKAGE_VERSION "@PRODUCT_VERSION@" +#define PRODUCT_BUGREPORT "@PRODUCT_BUGREPORT@" +#define OPENVPN_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@ +#define TAP_WIN_COMPONENT_ID "@PRODUCT_TAP_WIN_COMPONENT_ID@" +#define TAP_WIN_MIN_MAJOR @PRODUCT_TAP_WIN_MIN_MAJOR@ +#define TAP_WIN_MIN_MINOR @PRODUCT_TAP_WIN_MIN_MINOR@ diff --git a/config-msvc.h b/config-msvc.h new file mode 100644 index 0000000..99c00f9 --- /dev/null +++ b/config-msvc.h @@ -0,0 +1,122 @@ +#include <config-msvc-version.h> + +#define CONFIGURE_DEFINES "N/A" + +#define ENABLE_DEF_AUTH 1 +#define ENABLE_PF 1 +#define ENABLE_CLIENT_SERVER 1 +#define ENABLE_CRYPTO 1 +#define ENABLE_CRYPTO_OPENSSL 1 +#define ENABLE_DEBUG 1 +#define ENABLE_EUREPHIA 1 +#define ENABLE_FRAGMENT 1 +#define ENABLE_HTTP_PROXY 1 +#define ENABLE_LZO 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 +#define HAVE_CTYPE_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRDUP 1 +#define HAVE_STRERROR 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_SYSTEM 1 +#define HAVE_TIME 1 +#define HAVE_TIME_H 1 +#define HAVE_UNLINK 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_WINDOWS_H 1 +#define HAVE_WINSOCK2_H 1 +#define HAVE_WS2TCPIP_H 1 +#define HAVE_IO_H 1 +#define HAVE_DIRECT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_LZO_LZO1X_H 1 +#define HAVE_LZO_LZOUTIL_H 1 + +#define HAVE_ACCESS 1 +#define HAVE_CHDIR 1 +#define HAVE_CHSIZE 1 +#define HAVE_CPP_VARARG_MACRO_ISO 1 +#define HAVE_CTIME 1 +#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1 +#define HAVE_IN_PKTINFO 1 +#define HAVE_MEMSET 1 +#define HAVE_PUTENV 1 +#define HAVE_STAT 1 + +#define HAVE_SOCKET 1 +#define HAVE_RECV 1 +#define HAVE_RECVFROM 1 +#define HAVE_SEND 1 +#define HAVE_SENDTO 1 +#define HAVE_LISTEN 1 +#define HAVE_ACCEPT 1 +#define HAVE_CONNECT 1 +#define HAVE_BIND 1 +#define HAVE_SELECT 1 +#define HAVE_GETHOSTBYNAME 1 +#define HAVE_INET_NTOA 1 +#define HAVE_SETSOCKOPT 1 +#define HAVE_GETSOCKOPT 1 +#define HAVE_GETSOCKNAME 1 +#define HAVE_POLL 1 + +#define HAVE_OPENSSL_ENGINE 1 + +#ifndef __cplusplus +#define inline __inline +#endif + +#define EMPTY_ARRAY_SIZE 0 +#define TARGET_WIN32 1 +#define TARGET_ALIAS "Windows-MSVC" + +#define HAVE_DECL_SO_MARK 0 + +#define strncasecmp strnicmp +#define strcasecmp _stricmp +#define snprintf _snprintf +#define strtoull strtoul + +#define in_addr_t uint32_t +#define ssize_t SSIZE_T + +#define S_IRUSR 0 +#define S_IWUSR 0 +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#define F_OK 0 + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGUSR1 10 +#define SIGUSR2 12 +#define SIGTERM 15 + +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int8 uint8_t; +typedef __int64 int64_t; +typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int8 int8_t; + +#ifdef HAVE_CONFIG_MSVC_LOCAL_H +#include <config-msvc-local.h> +#endif + diff --git a/config-version.h.in b/config-version.h.in new file mode 100644 index 0000000..27ee36a --- /dev/null +++ b/config-version.h.in @@ -0,0 +1 @@ +#define CONFIGURE_GIT_REVISION "@CONFIGURE_GIT_REVISION@" diff --git a/config.h.in b/config.h.in index 8b04c43..68fec17 100644 --- a/config.h.in +++ b/config.h.in @@ -1,13 +1,10 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* Enable deferred authentication */ -#undef CONFIGURE_DEF_AUTH +/* Configuration settings */ +#undef CONFIGURE_DEFINES -/* Enable internal packet filter */ -#undef CONFIGURE_PF - -/* enable iproute2 support */ -#undef CONFIG_FEATURE_IPROUTE +/* special build string */ +#undef CONFIGURE_SPECIAL_BUILD /* Use memory debugging function in OpenSSL */ #undef CRYPTO_MDEBUG @@ -24,18 +21,42 @@ /* Enable client/server capability */ #undef ENABLE_CLIENT_SERVER +/* Enable crypto library */ +#undef ENABLE_CRYPTO + +/* Use OpenSSL library */ +#undef ENABLE_CRYPTO_OPENSSL + +/* Use PolarSSL library */ +#undef ENABLE_CRYPTO_POLARSSL + /* Enable debugging support */ #undef ENABLE_DEBUG +/* Enable deferred authentication */ +#undef ENABLE_DEF_AUTH + /* Enable support for the eurephia plug-in */ #undef ENABLE_EUREPHIA +/* We have persist tun capability */ +#undef ENABLE_FEATURE_TUN_PERSIST + /* Enable internal fragmentation support */ #undef ENABLE_FRAGMENT /* Enable HTTP proxy support */ #undef ENABLE_HTTP_PROXY +/* enable iproute2 support */ +#undef ENABLE_IPROUTE + +/* Enable LZO compression library */ +#undef ENABLE_LZO + +/* Enable LZO stub capability */ +#undef ENABLE_LZO_STUB + /* Enable management server capability */ #undef ENABLE_MANAGEMENT @@ -45,24 +66,51 @@ /* Allow --askpass and --auth-user-pass passwords to be read from a file */ #undef ENABLE_PASSWORD_SAVE +/* Enable internal packet filter */ +#undef ENABLE_PF + +/* Enable PKCS11 */ +#undef ENABLE_PKCS11 + +/* Enable systemd support */ +#undef ENABLE_PLUGIN + /* Enable TCP Server port sharing */ #undef ENABLE_PORT_SHARE +/* SELinux support */ +#undef ENABLE_SELINUX + /* 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 + +/* Enable systemd support */ +#undef ENABLE_SYSTEMD + /* Enable --x509-username-field feature */ #undef ENABLE_X509ALTUSERNAME /* Define to 1 if you have the `accept' function. */ #undef HAVE_ACCEPT +/* Define to 1 if you have the `access' function. */ +#undef HAVE_ACCESS + /* Define to 1 if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H +/* Define to 1 if you have the `basename' function. */ +#undef HAVE_BASENAME + /* Define to 1 if you have the `bind' function. */ #undef HAVE_BIND @@ -78,6 +126,9 @@ /* struct cmsghdr needed for extended socket error support */ #undef HAVE_CMSGHDR +/* extra version available in config-version.h */ +#undef HAVE_CONFIG_VERSION_H + /* Define to 1 if you have the `connect' function. */ #undef HAVE_CONNECT @@ -96,6 +147,43 @@ /* Define to 1 if you have the `daemon' function. */ #undef HAVE_DAEMON +/* Define to 1 if you have the declaration of `SIGHUP', and to 0 if you don't. + */ +#undef HAVE_DECL_SIGHUP + +/* Define to 1 if you have the declaration of `SIGINT', and to 0 if you don't. + */ +#undef HAVE_DECL_SIGINT + +/* Define to 1 if you have the declaration of `SIGTERM', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGTERM + +/* Define to 1 if you have the declaration of `SIGUSR1', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGUSR1 + +/* Define to 1 if you have the declaration of `SIGUSR2', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGUSR2 + +/* Define to 1 if you have the declaration of `SO_MARK', and to 0 if you + don't. */ +#undef HAVE_DECL_SO_MARK + +/* Define to 1 if you have the declaration of `TUNSETPERSIST', and to 0 if you + don't. */ +#undef HAVE_DECL_TUNSETPERSIST + +/* Define to 1 if you have the <direct.h> header file. */ +#undef HAVE_DIRECT_H + +/* Define to 1 if you have the `dirname' function. */ +#undef HAVE_DIRNAME + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + /* Define to 1 if you have the `dup' function. */ #undef HAVE_DUP @@ -111,7 +199,7 @@ /* Define to 1 if you have the `ENGINE_register_all_complete' function. */ #undef HAVE_ENGINE_REGISTER_ALL_COMPLETE -/* epoll_create function is defined */ +/* Define to 1 if you have the `epoll_create' function. */ #undef HAVE_EPOLL_CREATE /* Define to 1 if you have the <errno.h> header file. */ @@ -174,20 +262,38 @@ /* Define to 1 if you have the `inet_ntoa' function. */ #undef HAVE_INET_NTOA +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if the system has the type `in_addr_t'. */ +#undef HAVE_IN_ADDR_T + /* struct in_pktinfo needed for IP_PKTINFO support */ #undef HAVE_IN_PKTINFO /* struct iovec needed for IPv6 support */ #undef HAVE_IOVEC +/* Define to 1 if you have the <io.h> header file. */ +#undef HAVE_IO_H + /* struct iphdr needed for IPv6 support */ #undef HAVE_IPHDR -/* Define to 1 if you have the <linux/errqueue.h> header file. */ -#undef HAVE_LINUX_ERRQUEUE_H +/* 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 /* Define to 1 if you have the <linux/if_tun.h> header file. */ #undef HAVE_LINUX_IF_TUN_H @@ -201,6 +307,18 @@ /* Define to 1 if you have the `listen' function. */ #undef HAVE_LISTEN +/* Define to 1 if you have the <lzo1x.h> header file. */ +#undef HAVE_LZO1X_H + +/* Define to 1 if you have the <lzoutil.h> header file. */ +#undef HAVE_LZOUTIL_H + +/* Define to 1 if you have the <lzo/lzo1x.h> header file. */ +#undef HAVE_LZO_LZO1X_H + +/* Define to 1 if you have the <lzo/lzoutil.h> header file. */ +#undef HAVE_LZO_LZOUTIL_H + /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H @@ -246,8 +364,8 @@ /* Define to 1 if you have the `openlog' function. */ #undef HAVE_OPENLOG -/* Define to 1 if you have the <openssl/engine.h> header file. */ -#undef HAVE_OPENSSL_ENGINE_H +/* Use crypto library */ +#undef HAVE_OPENSSL_ENGINE /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL @@ -273,7 +391,7 @@ /* Define to 1 if you have the <resolv.h> header file. */ #undef HAVE_RESOLV_H -/* Indicates if res_init is available */ +/* Define to 1 if you have the `res_init' function. */ #undef HAVE_RES_INIT /* Define to 1 if you have the `select' function. */ @@ -288,9 +406,6 @@ /* Define to 1 if you have the `sendto' function. */ #undef HAVE_SENDTO -/* SELinux support */ -#undef HAVE_SETCON - /* Define to 1 if you have the `setgid' function. */ #undef HAVE_SETGID @@ -321,6 +436,9 @@ /* Define to 1 if you have the <stdarg.h> header file. */ #undef HAVE_STDARG_H +/* Define to 1 if you have the <stdbool.h> header file. */ +#undef HAVE_STDBOOL_H + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -390,14 +508,17 @@ /* Define to 1 if you have the <sys/un.h> header file. */ #undef HAVE_SYS_UN_H -/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +/* Define to 1 if you have the <sys/wait.h> header file. */ #undef HAVE_SYS_WAIT_H +/* Define to 1 if you have the <tap-windows.h> header file. */ +#undef HAVE_TAP_WINDOWS_H + /* Define to 1 if you have the `time' function. */ #undef HAVE_TIME -/* struct tun_pi needed for IPv6 support */ -#undef HAVE_TUN_PI +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H /* Define to 1 if you have the `umask' function. */ #undef HAVE_UMASK @@ -417,6 +538,12 @@ /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF +/* Define to 1 if you have the <windows.h> header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the <winsock2.h> header file. */ +#undef HAVE_WINSOCK2_H + /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK @@ -426,20 +553,21 @@ /* Define to 1 if you have the `writev' function. */ #undef HAVE_WRITEV +/* Define to 1 if you have the <ws2tcpip.h> header file. */ +#undef HAVE_WS2TCPIP_H + /* Path to ifconfig tool */ #undef IFCONFIG_PATH /* Path to iproute tool */ #undef IPROUTE_PATH -/* Use lzo/ directory prefix for LZO header files (for LZO 2.0) */ -#undef LZO_HEADER_DIR - -/* LZO version number */ -#undef LZO_VERSION_NUM +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR -/* Path to netstat tool */ -#undef NETSTAT_PATH +/* Version in windows resource format */ +#undef OPENVPN_VERSION_RESOURCE /* Name of package */ #undef PACKAGE @@ -462,12 +590,33 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Path separator */ +#undef PATH_SEPARATOR + +/* Path separator */ +#undef PATH_SEPARATOR_STR + /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Path to route tool */ #undef ROUTE_PATH +/* SIGHUP replacement */ +#undef SIGHUP + +/* SIGINT replacement */ +#undef SIGINT + +/* SIGTERM replacement */ +#undef SIGTERM + +/* SIGUSR1 replacement */ +#undef SIGUSR1 + +/* SIGUSR2 replacement */ +#undef SIGUSR2 + /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT @@ -477,17 +626,14 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Enable strict options check between peers */ -#undef STRICT_OPTIONS_CHECK +/* The tap-windows id */ +#undef TAP_WIN_COMPONENT_ID -/* The TAP-Win32 id defined in tap-win32/SOURCES */ -#undef TAP_ID +/* The tap-windows version number is required for OpenVPN */ +#undef TAP_WIN_MIN_MAJOR -/* The TAP-Win32 version number is defined in tap-win32/SOURCES */ -#undef TAP_WIN32_MIN_MAJOR - -/* The TAP-Win32 version number is defined in tap-win32/SOURCES */ -#undef TAP_WIN32_MIN_MINOR +/* The tap-windows version number is required for OpenVPN */ +#undef TAP_WIN_MIN_MINOR /* A string representing our host */ #undef TARGET_ALIAS @@ -510,32 +656,17 @@ /* Are we running on OpenBSD? */ #undef TARGET_OPENBSD +/* Target prefix */ +#undef TARGET_PREFIX + /* Are we running on Solaris? */ #undef TARGET_SOLARIS /* Are we running WIN32? */ #undef TARGET_WIN32 -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#undef TIME_WITH_SYS_TIME - -/* Use OpenSSL crypto library */ -#undef USE_CRYPTO - -/* Use libdl for dynamic library loading */ -#undef USE_LIBDL - -/* Use LoadLibrary to load DLLs on Windows */ -#undef USE_LOAD_LIBRARY - -/* Use LZO compression library */ -#undef USE_LZO - -/* Enable PKCS11 capability */ -#undef USE_PKCS11 - -/* Use OpenSSL SSL library */ -#undef USE_SSL +/* dlopen libpam */ +#undef USE_PAM_DLOPEN /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE @@ -575,13 +706,28 @@ /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if <sys/types.h> doesn't define. */ #undef gid_t -/* Some systems don't define in_addr_t */ +/* Workaround missing in_addr_t */ #undef in_addr_t /* Define to `__inline__' or `__inline' if that's what the C compiler @@ -590,6 +736,22 @@ #undef inline #endif +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef int16_t + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#undef int8_t + /* Define to `long int' if <sys/types.h> does not define. */ #undef off_t @@ -605,13 +767,20 @@ /* Define to `int' if <sys/types.h> doesn't define. */ #undef uid_t -/* 16-bit unsigned type */ +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ #undef uint16_t -/* 32-bit unsigned type */ +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ #undef uint32_t -/* 8-bit unsigned type */ +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ #undef uint8_t /* Define as `fork' if `vfork' does not work. */ @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.66 for OpenVPN 2.2.1. +# Generated by GNU Autoconf 2.66 for OpenVPN 2.3_rc1. # # Report bugs to <openvpn-users@lists.sourceforge.net>. # @@ -173,7 +173,15 @@ test x\$exitcode = x0 || exit 1" as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else @@ -230,11 +238,11 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: openvpn-users@lists.sourceforge.net about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." + $as_echo "$0: Please tell bug-autoconf@gnu.org and openvpn-users@lists.sourceforge.net +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." fi exit 1 fi @@ -528,6 +536,8 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +SHELL=${CONFIG_SHELL-/bin/sh} + test -n "$DJDIR" || exec 7<&0 </dev/null exec 6>&1 @@ -552,12 +562,12 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OpenVPN' PACKAGE_TARNAME='openvpn' -PACKAGE_VERSION='2.2.1' -PACKAGE_STRING='OpenVPN 2.2.1' +PACKAGE_VERSION='2.3_rc1' +PACKAGE_STRING='OpenVPN 2.3_rc1' PACKAGE_BUGREPORT='openvpn-users@lists.sourceforge.net' PACKAGE_URL='' -ac_unique_file="syshead.h" +ac_unique_file="src/openvpn/syshead.h" # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> @@ -597,14 +607,74 @@ ac_includes_default="\ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS +LIBOBJS +sampledir +plugindir +ENABLE_PLUGIN_DOWN_ROOT_FALSE +ENABLE_PLUGIN_DOWN_ROOT_TRUE +ENABLE_PLUGIN_AUTH_PAM_FALSE +ENABLE_PLUGIN_AUTH_PAM_TRUE +GIT_CHECKOUT_FALSE +GIT_CHECKOUT_TRUE WIN32_FALSE WIN32_TRUE -win32datadir -TAP_WIN32_MIN_MINOR -TAP_WIN32_MIN_MAJOR -TAP_ID -LIBOBJS +PLUGIN_AUTH_PAM_LIBS +PLUGIN_AUTH_PAM_CFLAGS +OPTIONAL_PKCS11_HELPER_LIBS +OPTIONAL_PKCS11_HELPER_CFLAGS +OPTIONAL_LZO_LIBS +OPTIONAL_LZO_CFLAGS +OPTIONAL_CRYPTO_LIBS +OPTIONAL_CRYPTO_CFLAGS +OPTIONAL_SELINUX_LIBS +OPTIONAL_DL_LIBS +TAP_WIN_MIN_MINOR +TAP_WIN_MIN_MAJOR +TAP_WIN_COMPONENT_ID +PKCS11_HELPER_LIBS +PKCS11_HELPER_CFLAGS +LZO_LIBS +LZO_CFLAGS +POLARSSL_LIBS +POLARSSL_CFLAGS +OPENSSL_SSL_LIBS +OPENSSL_SSL_CFLAGS +OPENSSL_CRYPTO_LIBS +OPENSSL_CRYPTO_CFLAGS +LIBPAM_LIBS +LIBPAM_CFLAGS +SELINUX_LIBS +TAP_CFLAGS +SOCKETS_LIBS +DL_LIBS +RC +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +RANLIB +AR +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +LIBTOOL +OBJDUMP +DLLTOOL +AS +GIT MAN2HTML +NETSTAT +IPROUTE +ROUTE +IFCONFIG +SED +LN_S +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG EGREP GREP CPP @@ -624,10 +694,14 @@ CPPFLAGS LDFLAGS CFLAGS CC -NETSTAT -ROUTE -IPROUTE -IFCONFIG +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build am__untar am__tar AMTAR @@ -651,14 +725,6 @@ am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build target_alias host_alias build_alias @@ -700,8 +766,9 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -with_cygwin_native +enable_dependency_tracking enable_lzo +enable_lzo_stub enable_crypto enable_ssl enable_x509_alt_username @@ -712,7 +779,7 @@ enable_eurephia enable_management enable_pkcs11 enable_socks -enable_http +enable_http_proxy enable_fragment enable_multihome enable_port_share @@ -722,23 +789,24 @@ enable_password_save enable_iproute2 enable_def_auth enable_pf +enable_plugin_auth_pam +enable_plugin_down_root +enable_pam_dlopen enable_strict enable_pedantic -enable_profiling enable_strict_options enable_selinux -with_ssl_headers -with_ssl_lib -with_lzo_headers -with_lzo_lib -with_pkcs11_helper_headers -with_pkcs11_helper_lib -with_ifconfig_path -with_iproute_path -with_route_path -with_netstat_path +enable_systemd +with_special_build with_mem_check -enable_dependency_tracking +with_crypto_library +with_plugindir +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock ' ac_precious_vars='build_alias host_alias @@ -749,7 +817,28 @@ LDFLAGS LIBS CPPFLAGS CPP -MAN2HTML' +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +IFCONFIG +ROUTE +IPROUTE +NETSTAT +MAN2HTML +GIT +TAP_CFLAGS +LIBPAM_CFLAGS +LIBPAM_LIBS +OPENSSL_CRYPTO_CFLAGS +OPENSSL_CRYPTO_LIBS +OPENSSL_SSL_CFLAGS +OPENSSL_SSL_LIBS +POLARSSL_CFLAGS +POLARSSL_LIBS +LZO_CFLAGS +LZO_LIBS +PKCS11_HELPER_CFLAGS +PKCS11_HELPER_LIBS' # Initialize some variables set by options. @@ -1291,7 +1380,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.2.1 to adapt to many kinds of systems. +\`configure' configures OpenVPN 2.3_rc1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1361,7 +1450,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenVPN 2.2.1:";; + short | recursive ) echo "Configuration of OpenVPN 2.3_rc1:";; esac cat <<\_ACEOF @@ -1369,50 +1458,77 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-lzo Disable LZO compression support - --disable-crypto Disable OpenSSL crypto support - --disable-ssl Disable OpenSSL SSL support for TLS-based key exchange - --enable-x509-alt-username Enable the --x509-username-field feature - --disable-multi Disable client/server support (--mode server + client mode) - --disable-server Disable server support only (but retain client support) - --disable-plugins Disable plug-in support - --disable-eurephia Disable support for the eurephia plug-in - --disable-management Disable management server support - --disable-pkcs11 Disable pkcs11 support - --disable-socks Disable Socks support - --disable-http Disable HTTP proxy support - --disable-fragment Disable internal fragmentation support (--fragment) - --disable-multihome Disable multi-homed UDP server support (--multihome) - --disable-port-share Disable TCP server port-share support (--port-share) - --disable-debug Disable debugging support (disable gremlin and verb 7+ messages) - --enable-small Enable smaller executable size (disable OCC, usage message, and verb 4 parm list) - --enable-password-save Allow --askpass and --auth-user-pass passwords to be read from a file - --enable-iproute2 Enable support for iproute2 - --disable-def-auth Disable deferred authentication - --disable-pf Disable internal packet filter - --enable-strict Enable strict compiler warnings (debugging option) - --enable-pedantic Enable pedantic compiler warnings, will not generate a working executable (debugging option) - --enable-profiling Enable profiling (debugging option) - --enable-strict-options Enable strict options check between peers (debugging option) - --disable-selinux Disable SELinux support --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors + --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-crypto disable crypto support [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] + --disable-multi disable client/server support (--mode server + + client mode) [default=yes] + --disable-server disable server support only (but retain client + support) [default=yes] + --disable-plugins disable plug-in support [default=yes] + --disable-eurephia disable support for the eurephia plug-in + [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) + [default=yes] + --disable-port-share disable TCP server port-share support (--port-share) + [default=yes] + --disable-debug disable debugging support (disable gremlin and verb + 7+ messages) [default=yes] + --enable-small enable smaller executable size (disable OCC, usage + message, and verb 4 parm list) [default=yes] + --enable-password-save allow --askpass and --auth-user-pass passwords to be + read from a file [default=yes] + --enable-iproute2 enable support for iproute2 [default=no] + --disable-def-auth disable deferred authentication [default=yes] + --disable-pf disable internal packet filter [default=yes] + --disable-plugin-auth-pam + disable auth-pam plugin [default=platform specific] + --disable-plugin-down-root + disable down-root plugin [default=platform specific] + --enable-pam-dlopen dlopen libpam [default=no] + --enable-strict enable strict compiler warnings (debugging option) + [default=no] + --enable-pedantic enable pedantic compiler warnings, will not generate + a working executable (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-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-cygwin-native Compile native win32 - --with-ssl-headers=DIR Crypto/SSL Include files location - --with-ssl-lib=DIR Crypto/SSL Library location - --with-lzo-headers=DIR LZO Include files location - --with-lzo-lib=DIR LZO Library location - --with-pkcs11-helper-headers=DIR pkcs11-helper Include files location - --with-pkcs11-helper-lib=DIR pkcs11-helper Library location - --with-ifconfig-path=PATH Path to ifconfig tool - --with-iproute-path=PATH Path to iproute tool - --with-route-path=PATH Path to route tool - --with-netstat-path=PATH Path to netstat tool - --with-mem-check=TYPE Build with debug memory checking, TYPE = dmalloc or valgrind + --with-special-build=STRING + specify special build string + --with-mem-check=TYPE build with debug memory checking, + TYPE=no|dmalloc|valgrind|ssl [default=no] + --with-crypto-library=library + build with the given crypto library, + TYPE=openssl|polarssl [default=openssl] + --with-plugindir plugin directory [default=LIBDIR/openvpn] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] Some influential environment variables: CC C compiler command @@ -1423,7 +1539,39 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor - MAN2HTML man2html utility + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + IFCONFIG full path to ipconfig utility + ROUTE full path to route utility + IPROUTE full path to ip utility + NETSTAT path to netstat utility + MAN2HTML path to man2html utility + GIT path to git utility + TAP_CFLAGS C compiler flags for tap + LIBPAM_CFLAGS + C compiler flags for libpam + LIBPAM_LIBS linker flags for libpam + 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 + LZO_CFLAGS C compiler flags for lzo + LZO_LIBS linker flags for lzo + PKCS11_HELPER_CFLAGS + C compiler flags for PKCS11_HELPER, overriding pkg-config + PKCS11_HELPER_LIBS + linker flags for PKCS11_HELPER, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1491,7 +1639,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenVPN configure 2.2.1 +OpenVPN configure 2.3_rc1 generated by GNU Autoconf 2.66 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1744,6 +1892,119 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_header_compile +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* 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 $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -1798,8 +2059,135 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_type -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_find_uintX_t + +# ac_fn_c_compute_int LINENO EXPR ax_cv_socklen_t_equiv INCLUDES +# -------------------------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed @@ -1976,123 +2364,56 @@ rm -f conftest.val } # ac_fn_c_compute_int -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () +# ac_fn_c_check_decl LINENO SYMBOL ax_cv_socklen_t_equiv INCLUDES +# --------------------------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* 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. */ +$4 +int +main () +{ +#ifndef $as_decl_name #ifdef __cplusplus -extern "C" + (void) $as_decl_use; +#else + (void) $as_decl_name; #endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me #endif -int -main () -{ -return $2 (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} -} # ac_fn_c_check_func +} # ac_fn_c_check_decl 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.2.1, which was +It was created by OpenVPN $as_me 2.3_rc1, which was generated by GNU Autoconf 2.66. Invocation command line was $ $0 $@ @@ -2440,12 +2761,27 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_config_headers="$ac_config_headers config.h" + + + +if test -z "${docdir}"; then + docdir="\$(datadir)/doc/\$(PACKAGE_NAME)" + +fi +if test -z "${htmldir}"; then + htmldir="\$(docdir)" + +fi + + +$as_echo "#define OPENVPN_VERSION_RESOURCE 2,3,0,0" >>confdefs.h + + ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do +for ac_dir in . "$srcdir"/.; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" @@ -2461,7 +2797,7 @@ for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do fi done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2473,75 +2809,8 @@ 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. -# 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 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi +ac_config_headers="$ac_config_headers config.h" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac am__api_version='1.11' @@ -2981,8 +3250,8 @@ fi # Define the identity of the package. - PACKAGE=openvpn - VERSION=$PACKAGE_VERSION + PACKAGE='openvpn' + VERSION='2.3_rc1' cat >>confdefs.h <<_ACEOF @@ -3022,637 +3291,138 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' +# 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 - -# Check whether --with-cygwin-native was given. -if test "${with_cygwin_native+set}" = set; then : - withval=$with_cygwin_native; CYGWIN_NATIVE="${withval}" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 else - CYGWIN_NATIVE="no" + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi - - -WIN32="no" -CYGWIN="no" -case "${host}" in - *-mingw*) - WIN32="yes" - cross_compiling="yes" - ;; - *-*-cygwin*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking cygwin mode to use" >&5 -$as_echo_n "checking cygwin mode to use... " >&6; } - if test "${CYGWIN_NATIVE}" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using native win32" >&5 -$as_echo "Using native win32" >&6; } - CFLAGS="${CFLAGS} -mno-cygwin" - CYGWIN="yes" - WIN32="yes" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using cygwin" >&5 -$as_echo "Using cygwin" >&6; } - fi - ;; - *) - ;; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac - -# Check whether --enable-lzo was given. -if test "${enable_lzo+set}" = set; then : - enableval=$enable_lzo; LZO="$enableval" -else - LZO="yes" - -fi - - -# Check whether --enable-crypto was given. -if test "${enable_crypto+set}" = set; then : - enableval=$enable_crypto; CRYPTO="$enableval" -else - CRYPTO="yes" - -fi - - -# Check whether --enable-ssl was given. -if test "${enable_ssl+set}" = set; then : - enableval=$enable_ssl; SSL="$enableval" -else - 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; X509ALTUSERNAME="$enableval" -else - X509ALTUSERNAME="no" - -fi - - -# Check whether --enable-multi was given. -if test "${enable_multi+set}" = set; then : - enableval=$enable_multi; MULTI="$enableval" -else - MULTI="yes" - -fi - - -# Check whether --enable-server was given. -if test "${enable_server+set}" = set; then : - enableval=$enable_server; MULTI_SERVER="$enableval" -else - MULTI_SERVER="yes" - -fi - - -# Check whether --enable-plugins was given. -if test "${enable_plugins+set}" = set; then : - enableval=$enable_plugins; PLUGINS="$enableval" -else - PLUGINS="yes" - -fi - - -# Check whether --enable-eurephia was given. -if test "${enable_eurephia+set}" = set; then : - enableval=$enable_eurephia; EUREPHIA="$enableval" -else - EUREPHIA="yes" - -fi - - -# Check whether --enable-management was given. -if test "${enable_management+set}" = set; then : - enableval=$enable_management; MANAGEMENT="$enableval" -else - MANAGEMENT="yes" - -fi - - -# Check whether --enable-pkcs11 was given. -if test "${enable_pkcs11+set}" = set; then : - enableval=$enable_pkcs11; PKCS11="$enableval" -else - PKCS11="yes" - -fi - - -# Check whether --enable-socks was given. -if test "${enable_socks+set}" = set; then : - enableval=$enable_socks; SOCKS="$enableval" -else - SOCKS="yes" - -fi - - -# Check whether --enable-http was given. -if test "${enable_http+set}" = set; then : - enableval=$enable_http; HTTP_PROXY="$enableval" -else - HTTP_PROXY="yes" - -fi - - -# Check whether --enable-fragment was given. -if test "${enable_fragment+set}" = set; then : - enableval=$enable_fragment; FRAGMENT="$enableval" -else - FRAGMENT="yes" - -fi - - -# Check whether --enable-multihome was given. -if test "${enable_multihome+set}" = set; then : - enableval=$enable_multihome; MULTIHOME="$enableval" -else - MULTIHOME="yes" - -fi - - -# Check whether --enable-port-share was given. -if test "${enable_port_share+set}" = set; then : - enableval=$enable_port_share; PORT_SHARE="$enableval" -else - PORT_SHARE="yes" - -fi - - -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; DEBUG="$enableval" -else - DEBUG="yes" - -fi - - -# Check whether --enable-small was given. -if test "${enable_small+set}" = set; then : - enableval=$enable_small; SMALL="$enableval" -else - SMALL="no" - -fi - - -# Check whether --enable-password-save was given. -if test "${enable_password_save+set}" = set; then : - enableval=$enable_password_save; PASSWORD_SAVE="$enableval" -else - PASSWORD_SAVE="no" - -fi - - -# Check whether --enable-iproute2 was given. -if test "${enable_iproute2+set}" = set; then : - enableval=$enable_iproute2; test $enableval = "yes" && -$as_echo "#define CONFIG_FEATURE_IPROUTE 1" >>confdefs.h - - -fi - - -# Check whether --enable-def-auth was given. -if test "${enable_def_auth+set}" = set; then : - enableval=$enable_def_auth; DEF_AUTH="$enableval" -else - DEF_AUTH="yes" - -fi - - -# Check whether --enable-pf was given. -if test "${enable_pf+set}" = set; then : - enableval=$enable_pf; PF="$enableval" -else - PF="yes" - -fi - - -# Check whether --enable-strict was given. -if test "${enable_strict+set}" = set; then : - enableval=$enable_strict; STRICT="$enableval" -else - STRICT="no" - -fi - - -# Check whether --enable-pedantic was given. -if test "${enable_pedantic+set}" = set; then : - enableval=$enable_pedantic; PEDANTIC="$enableval" -else - PEDANTIC="no" - -fi - - -# Check whether --enable-profiling was given. -if test "${enable_profiling+set}" = set; then : - enableval=$enable_profiling; PROFILE="$enableval" -else - PROFILE="no" - -fi - - -# Check whether --enable-strict-options was given. -if test "${enable_strict_options+set}" = set; then : - enableval=$enable_strict_options; STRICT_OPTIONS="$enableval" -else - STRICT_OPTIONS="no" - -fi - - -# Check whether --enable-selinux was given. -if test "${enable_selinux+set}" = set; then : - enableval=$enable_selinux; SELINUX="$enableval" -else - SELINUX="yes" - -fi - - - -# Check whether --with-ssl-headers was given. -if test "${with_ssl_headers+set}" = set; then : - withval=$with_ssl_headers; CS_HDR_DIR="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-ssl-lib was given. -if test "${with_ssl_lib+set}" = set; then : - withval=$with_ssl_lib; LDFLAGS="$LDFLAGS -L$withval" - -fi - - - -# Check whether --with-lzo-headers was given. -if test "${with_lzo_headers+set}" = set; then : - withval=$with_lzo_headers; LZO_HDR_DIR="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-lzo-lib was given. -if test "${with_lzo_lib+set}" = set; then : - withval=$with_lzo_lib; LDFLAGS="$LDFLAGS -L$withval" - -fi - - - -# Check whether --with-pkcs11-helper-headers was given. -if test "${with_pkcs11_helper_headers+set}" = set; then : - withval=$with_pkcs11_helper_headers; PKCS11_HELPER_HDR_DIR="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-pkcs11-helper-lib was given. -if test "${with_pkcs11_helper_lib+set}" = set; then : - withval=$with_pkcs11_helper_lib; LDFLAGS="$LDFLAGS -L$withval" - -fi - +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac -# Check whether --with-ifconfig-path was given. -if test "${with_ifconfig_path+set}" = set; then : - withval=$with_ifconfig_path; IFCONFIG="$withval" -else - # Extract the first word of "ifconfig", so it can be a program name with args. -set dummy ifconfig; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_IFCONFIG+set}" = set; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else - case $IFCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_IFCONFIG="$IFCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_IFCONFIG="$as_dir/$ac_word$ac_exec_ext" - $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 - - test -z "$ac_cv_path_IFCONFIG" && ac_cv_path_IFCONFIG="ifconfig" - ;; -esac -fi -IFCONFIG=$ac_cv_path_IFCONFIG -if test -n "$IFCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IFCONFIG" >&5 -$as_echo "$IFCONFIG" >&6; } + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi - - fi - - -cat >>confdefs.h <<_ACEOF -#define IFCONFIG_PATH "$IFCONFIG" -_ACEOF - - - -# Check whether --with-iproute-path was given. -if test "${with_iproute_path+set}" = set; then : - withval=$with_iproute_path; IPROUTE="$withval" -else - # Extract the first word of "ip", so it can be a program name with args. -set dummy ip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_IPROUTE+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - case $IPROUTE in - [\\/]* | ?:[\\/]*) - ac_cv_path_IPROUTE="$IPROUTE" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_IPROUTE="$as_dir/$ac_word$ac_exec_ext" - $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 - - test -z "$ac_cv_path_IPROUTE" && ac_cv_path_IPROUTE="ip" - ;; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac -fi -IPROUTE=$ac_cv_path_IPROUTE -if test -n "$IPROUTE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IPROUTE" >&5 -$as_echo "$IPROUTE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -fi - - -cat >>confdefs.h <<_ACEOF -#define IPROUTE_PATH "$IPROUTE" -_ACEOF +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac +DEPDIR="${am__leading_dot}deps" +ac_config_commands="$ac_config_commands depfiles" -# Check whether --with-route-path was given. -if test "${with_route_path+set}" = set; then : - withval=$with_route_path; ROUTE="$withval" -else - # Extract the first word of "route", so it can be a program name with args. -set dummy route; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ROUTE+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - case $ROUTE in - [\\/]* | ?:[\\/]*) - ac_cv_path_ROUTE="$ROUTE" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_ROUTE="$as_dir/$ac_word$ac_exec_ext" - $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 - test -z "$ac_cv_path_ROUTE" && ac_cv_path_ROUTE="route" +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU ;; esac -fi -ROUTE=$ac_cv_path_ROUTE -if test -n "$ROUTE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ROUTE" >&5 -$as_echo "$ROUTE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; fi - -cat >>confdefs.h <<_ACEOF -#define ROUTE_PATH "$ROUTE" -_ACEOF - - - -# Check whether --with-netstat-path was given. -if test "${with_netstat_path+set}" = set; then : - withval=$with_netstat_path; NETSTAT="$withval" -else - # Extract the first word of "netstat", so it can be a program name with args. -set dummy netstat; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_NETSTAT+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - case $NETSTAT in - [\\/]* | ?:[\\/]*) - ac_cv_path_NETSTAT="$NETSTAT" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin:/etc" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_NETSTAT="$as_dir/$ac_word$ac_exec_ext" - $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 - - test -z "$ac_cv_path_NETSTAT" && ac_cv_path_NETSTAT="netstat" - ;; -esac +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' fi -NETSTAT=$ac_cv_path_NETSTAT -if test -n "$NETSTAT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETSTAT" >&5 -$as_echo "$NETSTAT" >&6; } + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -fi - - -cat >>confdefs.h <<_ACEOF -#define NETSTAT_PATH "$NETSTAT" -_ACEOF - - - -# Check whether --with-mem-check was given. -if test "${with_mem_check+set}" = set; then : - withval=$with_mem_check; MEMCHECK="$withval" - -fi - - -CPPFLAGS="$CPPFLAGS -I${srcdir}" - -openvpn_host=$host -if test $host_alias; then - openvpn_host=$host_alias + AMDEP_TRUE='#' + AMDEP_FALSE= fi -cat >>confdefs.h <<_ACEOF -#define TARGET_ALIAS "$openvpn_host" -_ACEOF - -case "$host" in -*-*-linux*) - -$as_echo "#define TARGET_LINUX 1" >>confdefs.h - - if test -z $CS_HDR_DIR && test "$CRYPTO" = "yes"; then - CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl 2>/dev/null)" - fi - ;; -*-*-solaris*) - -$as_echo "#define TARGET_SOLARIS 1" >>confdefs.h - - ;; -*-*-openbsd*) - -$as_echo "#define TARGET_OPENBSD 1" >>confdefs.h - - ;; -*-*-freebsd*) - -$as_echo "#define TARGET_FREEBSD 1" >>confdefs.h - - ;; -*-*-netbsd*) - -$as_echo "#define TARGET_NETBSD 1" >>confdefs.h - - ;; -*-*-darwin*) - -$as_echo "#define TARGET_DARWIN 1" >>confdefs.h - - CPPFLAGS="$CPPFLAGS -no-cpp-precomp" - ;; -*-mingw*) - -$as_echo "#define TARGET_WIN32 1" >>confdefs.h - - CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" - - LIBS="-lgdi32 $LIBS" - - - LIBS="-lws2_32 $LIBS" - - - LIBS="-lwininet $LIBS" - - - LIBS="-lcrypt32 $LIBS" - - - LIBS="-liphlpapi $LIBS" - - - LIBS="-lwinmm $LIBS" - - ;; -*-*-dragonfly*) - -$as_echo "#define TARGET_DRAGONFLY 1" >>confdefs.h - - ;; - -esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -4443,68 +4213,6 @@ 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 -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - depcc="$CC" am_compiler_list= @@ -4634,7 +4342,6 @@ fi - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4903,48 +4610,6 @@ $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" -if test $ac_cv_c_compiler_gnu = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 -$as_echo_n "checking whether $CC needs -traditional... " >&6; } -if test "${ac_cv_prog_gcc_traditional+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_pattern="Autoconf.*'x'" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sgtty.h> -Autoconf TIOCGETP -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes -else - ac_cv_prog_gcc_traditional=no -fi -rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <termio.h> -Autoconf TCGETA -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 -$as_echo "$ac_cv_prog_gcc_traditional" >&6; } - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : @@ -5136,10 +4801,1000 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } +# Check whether --enable-lzo was given. +if test "${enable_lzo+set}" = set; then : + enableval=$enable_lzo; +else + enable_lzo="yes" -if test "${WIN32}" = "yes"; then +fi + + +# Check whether --enable-lzo-stub was given. +if test "${enable_lzo_stub+set}" = set; then : + enableval=$enable_lzo_stub; +else + enable_lzo_stub="no" + +fi + + +# Check whether --enable-crypto was given. +if test "${enable_crypto+set}" = set; then : + enableval=$enable_crypto; +else + enable_crypto="yes" + +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; +else + enable_x509_alt_username="no" + +fi + + +# Check whether --enable-multi was given. +if test "${enable_multi+set}" = set; then : + enableval=$enable_multi; +else + enable_multi="yes" + +fi + + +# Check whether --enable-server was given. +if test "${enable_server+set}" = set; then : + enableval=$enable_server; +else + enable_server="yes" + +fi + + +# Check whether --enable-plugins was given. +if test "${enable_plugins+set}" = set; then : + enableval=$enable_plugins; +else + enable_plugins="yes" + +fi + + +# Check whether --enable-eurephia was given. +if test "${enable_eurephia+set}" = set; then : + enableval=$enable_eurephia; +else + enable_eurephia="yes" + +fi + + +# Check whether --enable-management was given. +if test "${enable_management+set}" = set; then : + enableval=$enable_management; +else + enable_management="yes" + +fi + + +# Check whether --enable-pkcs11 was given. +if test "${enable_pkcs11+set}" = set; then : + enableval=$enable_pkcs11; +else + enable_pkcs11="no" + +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; +else + enable_fragment="yes" + +fi + + +# Check whether --enable-multihome was given. +if test "${enable_multihome+set}" = set; then : + enableval=$enable_multihome; +else + enable_multihome="yes" + +fi + + +# Check whether --enable-port-share was given. +if test "${enable_port_share+set}" = set; then : + enableval=$enable_port_share; +else + enable_port_share="yes" + +fi + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug="yes" + +fi + + +# Check whether --enable-small was given. +if test "${enable_small+set}" = set; then : + enableval=$enable_small; +else + enable_small="no" + +fi + + +# Check whether --enable-password-save was given. +if test "${enable_password_save+set}" = set; then : + enableval=$enable_password_save; +else + enable_password_save="no" + +fi + + +# Check whether --enable-iproute2 was given. +if test "${enable_iproute2+set}" = set; then : + enableval=$enable_iproute2; +else + enable_iproute2="no" + +fi + + +# Check whether --enable-def-auth was given. +if test "${enable_def_auth+set}" = set; then : + enableval=$enable_def_auth; +else + enable_def_auth="yes" + +fi + + +# Check whether --enable-pf was given. +if test "${enable_pf+set}" = set; then : + enableval=$enable_pf; +else + enable_pf="yes" + +fi + + +# Check whether --enable-plugin-auth-pam was given. +if test "${enable_plugin_auth_pam+set}" = set; then : + enableval=$enable_plugin_auth_pam; +else + + case "$host" in + *-*-openbsd*) enable_plugin_auth_pam="no";; + *-mingw*) enable_plugin_auth_pam="no";; + *) enable_plugin_auth_pam="yes";; + esac + + +fi + + +# Check whether --enable-plugin-down-root was given. +if test "${enable_plugin_down_root+set}" = set; then : + enableval=$enable_plugin_down_root; +else + + case "$host" in + *-mingw*) enable_plugin_down_root="no";; + *) enable_plugin_down_root="yes";; + esac + + +fi + + +# Check whether --enable-pam-dlopen was given. +if test "${enable_pam_dlopen+set}" = set; then : + enableval=$enable_pam_dlopen; +else + enable_pam_dlopen="no" + +fi + + +# Check whether --enable-strict was given. +if test "${enable_strict+set}" = set; then : + enableval=$enable_strict; +else + enable_strict="no" + +fi + + +# Check whether --enable-pedantic was given. +if test "${enable_pedantic+set}" = set; then : + enableval=$enable_pedantic; +else + enable_pedantic="no" + +fi + + +# Check whether --enable-strict-options was given. +if test "${enable_strict_options+set}" = set; then : + enableval=$enable_strict_options; +else + enable_strict_options="no" + +fi + + +# Check whether --enable-selinux was given. +if test "${enable_selinux+set}" = set; then : + enableval=$enable_selinux; +else + enable_selinux="no" + +fi + + +# Check whether --enable-systemd was given. +if test "${enable_systemd+set}" = set; then : + enableval=$enable_systemd; +else + enable_systemd="no" + +fi + + + +# Check whether --with-special-build was given. +if test "${with_special_build+set}" = set; then : + withval=$with_special_build; test -n "${withval}" && +cat >>confdefs.h <<_ACEOF +#define CONFIGURE_SPECIAL_BUILD "${withval}" +_ACEOF + + +fi + + + +# Check whether --with-mem-check was given. +if test "${with_mem_check+set}" = set; then : + withval=$with_mem_check; + case "${withval}" in + dmalloc|valgrind|ssl|no) ;; + *) as_fn_error $? "bad value ${withval} for --mem-check" "$LINENO" 5 ;; + esac + +else + with_mem_check="no" + +fi + + + +# Check whether --with-crypto-library was given. +if test "${with_crypto_library+set}" = set; then : + withval=$with_crypto_library; + case "${withval}" in + openssl|polarssl) ;; + *) as_fn_error $? "bad value ${withval} for --with-crypto-library" "$LINENO" 5 ;; + esac + +else + with_crypto_library="openssl" + +fi + + + +# Check whether --with-plugindir was given. +if test "${with_plugindir+set}" = set; then : + withval=$with_plugindir; +else + with_plugindir="\$(libdir)/openvpn/plugins" + +fi + + + + +cat >>confdefs.h <<_ACEOF +#define TARGET_ALIAS "${host}" +_ACEOF + +case "$host" in + *-*-linux*) + +$as_echo "#define TARGET_LINUX 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "L" +_ACEOF + + ;; + *-*-solaris*) + +$as_echo "#define TARGET_SOLARIS 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "S" +_ACEOF + + ;; + *-*-openbsd*) + +$as_echo "#define TARGET_OPENBSD 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "O" +_ACEOF + + ;; + *-*-freebsd*) + +$as_echo "#define TARGET_FREEBSD 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "F" +_ACEOF + + ;; + *-*-netbsd*) + +$as_echo "#define TARGET_NETBSD 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "N" +_ACEOF + + ;; + *-*-darwin*) + +$as_echo "#define TARGET_DARWIN 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "M" +_ACEOF + + have_tap_header="yes" + CPPFLAGS="$CPPFLAGS -no-cpp-precomp" + ;; + *-mingw*) + +$as_echo "#define TARGET_WIN32 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "W" +_ACEOF + + CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" + CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_WINXP -D_WIN32_WINNT=_WIN32_WINNT_WINXP" + WIN32=yes + ;; + *-*-dragonfly*) + +$as_echo "#define TARGET_DRAGONFLY 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "D" +_ACEOF + + ;; + *) + +cat >>confdefs.h <<_ACEOF +#define TARGET_PREFIX "X" +_ACEOF + + have_tap_header="yes" + ;; +esac + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +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 + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_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 sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + + + + + # tests + + +for ac_prog in ifconfig +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 test "${ac_cv_path_IFCONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $IFCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_IFCONFIG="$IFCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_IFCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +IFCONFIG=$ac_cv_path_IFCONFIG +if test -n "$IFCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IFCONFIG" >&5 +$as_echo "$IFCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$IFCONFIG" && break +done + +for ac_prog in route +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 test "${ac_cv_path_ROUTE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ROUTE in + [\\/]* | ?:[\\/]*) + ac_cv_path_ROUTE="$ROUTE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ROUTE="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +ROUTE=$ac_cv_path_ROUTE +if test -n "$ROUTE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ROUTE" >&5 +$as_echo "$ROUTE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ROUTE" && break +done + +for ac_prog in ip +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 test "${ac_cv_path_IPROUTE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $IPROUTE in + [\\/]* | ?:[\\/]*) + ac_cv_path_IPROUTE="$IPROUTE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_IPROUTE="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +IPROUTE=$ac_cv_path_IPROUTE +if test -n "$IPROUTE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IPROUTE" >&5 +$as_echo "$IPROUTE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi - for ac_prog in man2html + + test -n "$IPROUTE" && break +done + +for ac_prog in netstat +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 test "${ac_cv_prog_NETSTAT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NETSTAT"; then + ac_cv_prog_NETSTAT="$NETSTAT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/local/sbin:/usr/sbin:/sbin:/etc" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NETSTAT="$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 +NETSTAT=$ac_cv_prog_NETSTAT +if test -n "$NETSTAT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETSTAT" >&5 +$as_echo "$NETSTAT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$NETSTAT" && break +done +test -n "$NETSTAT" || NETSTAT="netstat" + # tests +for ac_prog in man2html do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -5181,20 +5836,1953 @@ fi test -n "$MAN2HTML" && break done - test -z "${MAN2HTML}" && as_fn_error $? "man2html is required for win32" "$LINENO" 5 +for ac_prog in git +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 test "${ac_cv_prog_GIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GIT"; then + ac_cv_prog_GIT="$GIT" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_GIT="$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 +GIT=$ac_cv_prog_GIT +if test -n "$GIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GIT" >&5 +$as_echo "$GIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : + + test -n "$GIT" && break +done + # optional + +cat >>confdefs.h <<_ACEOF +#define IFCONFIG_PATH "$IFCONFIG" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define IPROUTE_PATH "$IPROUTE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define ROUTE_PATH "$ROUTE" +_ACEOF + + +# +# Libtool +# + + case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.10' +macro_revision='1.3175' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`print -r -- -n 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +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 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_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 sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_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$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +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 "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +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 + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + 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" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + 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" + # 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 "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + 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 + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + 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 + # Check to see if the nm accepts a BSD-compat flag. + # 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 + 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 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + 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 "$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 + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$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 test "${ac_cv_prog_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$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 +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +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 test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$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 +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + 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` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + 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` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + 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 + 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"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${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"}, \ + = c,a/b,, \ + && 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 + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + 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 + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $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 +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $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 +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +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. +# '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 +# 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]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +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. + # 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 + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +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)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $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 +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $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 +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $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 +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $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 +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $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 +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $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 +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# 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 -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 -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= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # 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 + # 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};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {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'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + 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 + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + 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 + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +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 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 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # 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 "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # 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 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + 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; } +if test "${lt_cv_cc_needs_belf+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + 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 + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> int main () @@ -5204,98 +7792,4989 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes else - ac_cv_header_stdc=no + lt_cv_cc_needs_belf=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + 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 -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +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 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" + fi + ;; +sparc*-*solaris*) + # 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 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $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 +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $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 +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $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 +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $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 +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $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 +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $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 +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $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 +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $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 +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $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 +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $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 +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + 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 + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <string.h> +int +main () +{ + + ; + return 0; +} _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if test "${lt_cv_ld_force_load+set}" = set; then : + $as_echo_n "(cached) " >&6 else - ac_cv_header_stdc=no + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _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' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + 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}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + 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 +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + fi -rm -f conftest* +done + + + + + +# Set options +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AS+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $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 +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AS+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AS="as" + $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 +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DLLTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $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 +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $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 +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $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 +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $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 +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + 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," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# 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" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +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 +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + 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 + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + 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 -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" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +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; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + 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 + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + 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 -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" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +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; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +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 + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : + $as_echo_n "(cached) " >&6 +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" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +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 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 + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + 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'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + 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' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + 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) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +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" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +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 x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + 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 + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + 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 x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +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; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + 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 "$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 + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # 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'. + 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 + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # 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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # 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 "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + 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' + # 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' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + 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 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + 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_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + 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' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _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' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + 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 (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' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + 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' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + 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 "$tmp_diet" = no + then + tmp_addflag= + 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' + 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' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--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' + 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' + 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' + + 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' + fi + + case $cc_basename in + 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= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + 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' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + 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' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + 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 + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** 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 +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # 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' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + 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 + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + 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 + fi + ;; + + aix[4-9]*) + 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="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + 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 + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + 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` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + 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_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. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <stdlib.h> +int +main () +{ + + ; + return 0; +} _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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 "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 "$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" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + 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 "$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' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # 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 + ;; + + amigaos*) + 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_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + 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. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + 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" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + 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}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${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 $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + 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' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + 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 + fi + ;; + + hpux11*) + 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' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${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' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if test "${lt_cv_prog_compiler__b+set}" = set; then : + $as_echo_n "(cached) " >&6 else - ac_cv_header_stdc=no + lt_cv_prog_compiler__b=no + 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 + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + fi -rm -f conftest* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } +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 -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + 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 + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $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. + 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) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $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 +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + 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' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + 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_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + 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__`" || 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' + else + 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 + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + 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 "$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' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_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_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' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${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 ${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_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' + ;; + *) + 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' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + 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 is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + 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 + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + 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' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + 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' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # 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' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + 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' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : + $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + $RM conftest* + echo "$lt_simple_compile_test_code" > 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; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + 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" ;; + 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 + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # 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` + 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" + 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; + 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; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # 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'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + 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' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + 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}' + 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 + # 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 + : + else + can_build_shared=no + fi + ;; + esac + # 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. + 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}' + 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' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + 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}' + ;; + 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%'\''`; 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}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + 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' + 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" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + 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'\''`~ + 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_overrides_runpath=yes + + 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}' + + 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}' + ;; + 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}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + 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' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + 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 + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + 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' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + 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 + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + 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' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + 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 "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + 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' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + 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' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + 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' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + 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}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + 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}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + 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' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # 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 + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # 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 + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + 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' + 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' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + 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 + ;; + +*nto* | *qnx*) + 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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # 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 + 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' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + 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}' + 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" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + 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=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + 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 "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + 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) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + 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=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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + 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' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + 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 + ;; + +uts4*) + version_type=linux + 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 + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +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 "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$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 "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + 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 "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + 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_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # 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 test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = x""yes; then : + 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; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $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 shl_load (); int main () { - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; +return shl_load (); + ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=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_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : + 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" = x""yes; then : + 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; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes else - ac_cv_header_stdc=no + ac_cv_lib_dl_dlopen=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +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_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + 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; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=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_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then +{ $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" = x""yes; then : + 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; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $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 dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=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_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + 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 "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + 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} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + 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 test "${lt_cv_dlopen_self_static+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + 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} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # 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 +$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 "$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 "$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 "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$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 "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +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 + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RC"; then + ac_cv_prog_RC="$RC" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RC="${ac_tool_prefix}windres" + $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 +RC=$ac_cv_prog_RC +if test -n "$RC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5 +$as_echo "$RC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RC"; then + ac_ct_RC=$RC + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RC"; then + ac_cv_prog_ac_ct_RC="$ac_ct_RC" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RC="windres" + $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 +ac_ct_RC=$ac_cv_prog_ac_ct_RC +if test -n "$ac_ct_RC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5 +$as_echo "$ac_ct_RC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RC" = x; then + RC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RC=$ac_ct_RC + fi +else + RC="$ac_cv_prog_RC" +fi + + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +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" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +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 + +if test -n "$compiler"; then + : + -$as_echo "#define STDC_HEADERS 1" >>confdefs.h fi +GCC=$lt_save_GCC +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 + +CC="$lt_save_CC" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } @@ -5516,551 +12995,346 @@ $as_echo "#define gid_t int" >>confdefs.h fi +ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" +case $ac_cv_c_int8_t in #( + no|yes) ;; #( + *) - ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h> -#include <sys/socket.h> -" -if test "x$ac_cv_type_socklen_t" = x""yes; then : +cat >>confdefs.h <<_ACEOF +#define int8_t $ac_cv_c_int8_t +_ACEOF +;; +esac -else +ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" +case $ac_cv_c_int16_t in #( + no|yes) ;; #( + *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 -$as_echo_n "checking for socklen_t equivalent... " >&6; } - if test "${curl_cv_socklen_t_equiv+set}" = set; then : - $as_echo_n "(cached) " >&6 -else +cat >>confdefs.h <<_ACEOF +#define int16_t $ac_cv_c_int16_t +_ACEOF +;; +esac - case "$host" in - *-mingw*) curl_cv_socklen_t_equiv=int ;; - *) - # Systems have either "struct sockaddr *" or - # "void *" as the second argument to getpeername - curl_cv_socklen_t_equiv= - for arg2 in "struct sockaddr" void; do - for t in int size_t unsigned long "unsigned long"; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" +case $ac_cv_c_int32_t in #( + no|yes) ;; #( + *) - #include <sys/types.h> - #include <sys/socket.h> +cat >>confdefs.h <<_ACEOF +#define int32_t $ac_cv_c_int32_t +_ACEOF +;; +esac - int getpeername (int, $arg2 *, $t *); +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) -int -main () -{ +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac - $t len; - getpeername(0,0,&len); +ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" +case $ac_cv_c_uint8_t in #( + no|yes) ;; #( + *) - ; - return 0; -} +$as_echo "#define _UINT8_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint8_t $ac_cv_c_uint8_t _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +;; + esac - curl_cv_socklen_t_equiv="$t" - break +ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" +case $ac_cv_c_uint16_t in #( + no|yes) ;; #( + *) -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done - done - ;; - esac - if test "x$curl_cv_socklen_t_equiv" = x; then - as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5 - fi +cat >>confdefs.h <<_ACEOF +#define uint16_t $ac_cv_c_uint16_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) -fi +$as_echo "#define _UINT32_T 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $curl_cv_socklen_t_equiv" >&5 -$as_echo "$curl_cv_socklen_t_equiv" >&6; } cat >>confdefs.h <<_ACEOF -#define socklen_t $curl_cv_socklen_t_equiv +#define uint32_t $ac_cv_c_uint32_t _ACEOF +;; + esac -fi +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if test "${ac_cv_header_time+set}" = set; then : +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if test "${ac_cv_type_signal+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> -#include <sys/time.h> -#include <time.h> +#include <signal.h> int main () { -if ((struct tm *) 0) -return 0; +return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes + ac_cv_type_signal=int else - ac_cv_header_time=no + ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ISO C 1999 vararg macro support" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ISO C 1999 vararg macro support" >&5 $as_echo_n "checking for ISO C 1999 vararg macro support... " >&6; } if test "${ax_cv_cpp_vararg_macro_iso+set}" = set; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define macro(a, ...) func(a, __VA_ARGS__) - int func(int a, int b, int c); - int test() { return macro(1, 2, 3); } +int func(int a, int b, int c); + +int +main () +{ + +int i = macro(1, 2, 3); + + ; + return 0; +} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_cpp_vararg_macro_iso=yes + ax_cv_cpp_vararg_macro_iso=yes else ax_cv_cpp_vararg_macro_iso=no + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cpp_vararg_macro_iso" >&5 $as_echo "$ax_cv_cpp_vararg_macro_iso" >&6; } - if test $ax_cv_cpp_vararg_macro_iso = yes ; then + if test "x$ax_cv_cpp_vararg_macro_iso" = x""yes; then : $as_echo "#define HAVE_CPP_VARARG_MACRO_ISO 1" >>confdefs.h - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU GCC vararg macro support" >&5 +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU GCC vararg macro support" >&5 $as_echo_n "checking for GNU GCC vararg macro support... " >&6; } if test "${ax_cv_cpp_vararg_macro_gcc+set}" = set; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #define macro(a, b...) func(a, b) - int func(int a, int b, int c); - int test() { return macro(1, 2, 3); } +#define macro(a, b...) func(a, b) +int func(int a, int b, int c); +int +main () +{ + +int i = macro(1, 2, 3); + + + ; + return 0; +} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_cpp_vararg_macro_gcc=yes + ax_cv_cpp_vararg_macro_gcc=yes else ax_cv_cpp_vararg_macro_gcc=no + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cpp_vararg_macro_gcc" >&5 $as_echo "$ax_cv_cpp_vararg_macro_gcc" >&6; } - if test $ax_cv_cpp_vararg_macro_gcc = yes ; then + if test "x$ax_cv_cpp_vararg_macro_gcc" = x""yes; then : $as_echo "#define HAVE_CPP_VARARG_MACRO_GCC 1" >>confdefs.h - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for C compiler empty array support" >&5 -$as_echo "checking for C compiler empty array support" >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - struct { int foo; int bar[0]; } mystruct; +fi -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : + ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " +#include <sys/types.h> +#ifdef WIN32 +#include <ws2tcpip.h> +#else +#include <sys/socket.h> +#endif -cat >>confdefs.h <<_ACEOF -#define EMPTY_ARRAY_SIZE 0 -_ACEOF +" +if test "x$ac_cv_type_socklen_t" = x""yes; then : +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 +$as_echo_n "checking for socklen_t equivalent... " >&6; } +if test "${ax_cv_socklen_t_equiv+set}" = set; then : + $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + #AS_CASE is not supported on <autoconf-2.60 + case "${host}" in + *-mingw*) ax_cv_socklen_t_equiv=int ;; + *) + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long"; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - struct { int foo; int bar[]; } mystruct; +#include <sys/types.h> +#include <sys/socket.h> +int getpeername (int, $arg2 *, $t *); -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +int +main () +{ +$t len; +getpeername(0,0,&len); -cat >>confdefs.h <<_ACEOF -#define EMPTY_ARRAY_SIZE /**/ + + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_socklen_t_equiv="$t"; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + test -n "$ax_cv_socklen_t_equiv" && break + done + ;; + esac + if test "x$ax_cv_socklen_t_equiv" = x""; then : + as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5 else - as_fn_error $? "C compiler is unable to creaty empty arrays" "$LINENO" 5 +cat >>confdefs.h <<_ACEOF +#define socklen_t $ax_cv_socklen_t_equiv +_ACEOF -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - -for ac_header in fcntl.h stdlib.h stdarg.h stdio.h string.h strings.h ctype.h errno.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_socklen_t_equiv" >&5 +$as_echo "$ax_cv_socklen_t_equiv" >&6; } fi -done -if test "${WIN32}" != "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 -$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } -if test "${ac_cv_header_sys_wait_h+set}" = set; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler empty array size" >&5 +$as_echo_n "checking for C compiler empty array size... " >&6; } +if test "${ax_cv_c_empty_array+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <sys/types.h> -#include <sys/wait.h> -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif int main () { - int s; - wait (&s); - s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + +struct { int foo; int bar[0]; } mystruct; + + ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_sys_wait_h=yes + ax_cv_c_empty_array=0 else - ac_cv_header_sys_wait_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 -$as_echo "$ac_cv_header_sys_wait_h" >&6; } -if test $ac_cv_header_sys_wait_h = yes; then - -$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h - -fi - - for ac_header in sys/time.h sys/socket.h sys/un.h sys/ioctl.h sys/stat.h sys/mman.h fcntl.h sys/file.h stdlib.h stdint.h stdarg.h unistd.h signal.h stdio.h string.h strings.h ctype.h errno.h syslog.h pwd.h grp.h net/if_tun.h net/tun/if_tun.h stropts.h sys/sockio.h netinet/in.h netinet/in_systm.h netinet/tcp.h arpa/inet.h netdb.h sys/uio.h linux/if_tun.h linux/sockios.h linux/types.h sys/poll.h sys/epoll.h err.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - for ac_header in net/if.h -do : - ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_SYS_SOCKET_H - # include <sys/socket.h> - #endif - -" -if test "x$ac_cv_header_net_if_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NET_IF_H 1 -_ACEOF - -fi - -done - - for ac_header in netinet/ip.h -do : - ac_fn_c_check_header_compile "$LINENO" "netinet/ip.h" "ac_cv_header_netinet_ip_h" "#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - #ifdef HAVE_NETINET_IN_SYSTM_H - # include <netinet/in_systm.h> - #endif - -" -if test "x$ac_cv_header_netinet_ip_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NETINET_IP_H 1 -_ACEOF - -fi - -done - - for ac_header in netinet/if_ether.h -do : - ac_fn_c_check_header_compile "$LINENO" "netinet/if_ether.h" "ac_cv_header_netinet_if_ether_h" "#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_SYS_SOCKET_H - # include <sys/socket.h> - #endif - #ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - -" -if test "x$ac_cv_header_netinet_if_ether_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NETINET_IF_ETHER_H 1 -_ACEOF - -fi - -done - - for ac_header in resolv.h -do : - ac_fn_c_check_header_compile "$LINENO" "resolv.h" "ac_cv_header_resolv_h" "#ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - -" -if test "x$ac_cv_header_resolv_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_RESOLV_H 1 -_ACEOF - -fi - -done - - for ac_header in linux/errqueue.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/errqueue.h" "ac_cv_header_linux_errqueue_h" "#ifdef HAVE_LINUX_TYPES_H - # include <linux/types.h> - #endif - -" -if test "x$ac_cv_header_linux_errqueue_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_ERRQUEUE_H 1 -_ACEOF - -fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -done +int +main () +{ -fi +struct { int foo; int bar[]; } mystruct; -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. + ; + return 0; +} _ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#include \"syshead.h\" -" -if test "x$ac_cv_type_in_addr_t" = x""yes; then : - -else - -$as_echo "#define in_addr_t uint32_t" >>confdefs.h - -fi - - -ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "#include \"syshead.h\" -" -if test "x$ac_cv_type_uint8_t" = x""yes; then : - -else - -$as_echo "#define uint8_t unsigned char" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "#include \"syshead.h\" -" -if test "x$ac_cv_type_uint16_t" = x""yes; then : - -else - -$as_echo "#define uint16_t unsigned char" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include \"syshead.h\" -" -if test "x$ac_cv_type_uint32_t" = x""yes; then : - +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_c_empty_array= else - -$as_echo "#define uint32_t unsigned long" >>confdefs.h - -fi - - -ac_fn_c_check_type "$LINENO" "struct tun_pi" "ac_cv_type_struct_tun_pi" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_tun_pi" = x""yes; then : - -$as_echo "#define HAVE_TUN_PI 1" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "struct iphdr" "ac_cv_type_struct_iphdr" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_iphdr" = x""yes; then : - -$as_echo "#define HAVE_IPHDR 1" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "struct iovec" "ac_cv_type_struct_iovec" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_iovec" = x""yes; then : - -$as_echo "#define HAVE_IOVEC 1" >>confdefs.h + as_fn_error $? "C compiler is unable to creaty empty arrays" "$LINENO" 5 fi - - -ac_fn_c_check_type "$LINENO" "struct sock_extended_err" "ac_cv_type_struct_sock_extended_err" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_sock_extended_err" = x""yes; then : - -$as_echo "#define HAVE_SOCK_EXTENDED_ERR 1" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "struct msghdr" "ac_cv_type_struct_msghdr" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_msghdr" = x""yes; then : - -$as_echo "#define HAVE_MSGHDR 1" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "struct cmsghdr" "ac_cv_type_struct_cmsghdr" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_cmsghdr" = x""yes; then : - -$as_echo "#define HAVE_CMSGHDR 1" >>confdefs.h +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - -ac_fn_c_check_type "$LINENO" "struct in_pktinfo" "ac_cv_type_struct_in_pktinfo" "#include \"syshead.h\" -" -if test "x$ac_cv_type_struct_in_pktinfo" = x""yes; then : - -$as_echo "#define HAVE_IN_PKTINFO 1" >>confdefs.h +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_empty_array" >&5 +$as_echo "$ax_cv_c_empty_array" >&6; } +cat >>confdefs.h <<_ACEOF +#define EMPTY_ARRAY_SIZE $ax_cv_c_empty_array +_ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects @@ -6128,376 +13402,300 @@ cat >>confdefs.h <<_ACEOF _ACEOF +for ac_header in \ + stdio.h stdarg.h stdbool.h limits.h \ + time.h errno.h fcntl.h io.h direct.h \ + ctype.h sys/types.h sys/socket.h \ + signal.h unistd.h dlfcn.h \ + netinet/in.h netinet/in_systm.h \ + netinet/tcp.h arpa/inet.h netdb.h \ + windows.h winsock2.h ws2tcpip.h \ -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi fi -rm -f confcache -for ac_func in ctime memset vsnprintf strdup +done + +for ac_header in \ + sys/time.h sys/ioctl.h sys/stat.h \ + sys/mman.h sys/file.h sys/wait.h \ + unistd.h signal.h libgen.h stropts.h \ + syslog.h pwd.h grp.h \ + sys/sockio.h sys/uio.h linux/sockios.h \ + linux/types.h sys/poll.h sys/epoll.h err.h \ + 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 : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF -else - as_fn_error $? "Required library function not found" "$LINENO" 5 fi + done -for ac_func in daemon chroot getpwnam setuid nice system getpid dup dup2 getpass strerror syslog openlog mlockall getgrnam setgid setgroups stat flock readv writev time setsid chdir putenv getpeername unlink chsize ftruncate execve getpeereid umask + +SOCKET_INCLUDES=" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif +#ifdef HAVE_NETINET_IP_H +#include <netinet/ip.h> +#endif +" + +for ac_header in net/if.h netinet/ip.h netinet/if_ether.h resolv.h sys/un.h 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 : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "${SOCKET_INCLUDES} + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi + done -# Windows use stdcall for winsock so we cannot auto detect these +ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "${SOCKET_INCLUDES} +" +if test "x$ac_cv_type_in_addr_t" = x""yes; then : +cat >>confdefs.h <<_ACEOF +#define HAVE_IN_ADDR_T 1 +_ACEOF -if test "${WIN32}" = "yes"; then +else -$as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h +$as_echo "#define in_addr_t uint32_t" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct iphdr" "ac_cv_type_struct_iphdr" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_SOCKET 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_iphdr" = x""yes; then : +$as_echo "#define HAVE_IPHDR 1" >>confdefs.h -$as_echo "#define HAVE_RECV 1" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct sock_extended_err" "ac_cv_type_struct_sock_extended_err" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_RECVFROM 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_sock_extended_err" = x""yes; then : +$as_echo "#define HAVE_SOCK_EXTENDED_ERR 1" >>confdefs.h -$as_echo "#define HAVE_SEND 1" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct msghdr" "ac_cv_type_struct_msghdr" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_SENDTO 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_msghdr" = x""yes; then : +$as_echo "#define HAVE_MSGHDR 1" >>confdefs.h -$as_echo "#define HAVE_LISTEN 1" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct cmsghdr" "ac_cv_type_struct_cmsghdr" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_ACCEPT 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_cmsghdr" = x""yes; then : +$as_echo "#define HAVE_CMSGHDR 1" >>confdefs.h -$as_echo "#define HAVE_CONNECT 1" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct in_pktinfo" "ac_cv_type_struct_in_pktinfo" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_BIND 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_in_pktinfo" = x""yes; then : +$as_echo "#define HAVE_IN_PKTINFO 1" >>confdefs.h -$as_echo "#define HAVE_SELECT 1" >>confdefs.h +fi +ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "${SOCKET_INCLUDES} -$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h +" +if test "x$ac_cv_type_struct_sockaddr_in6" = x""yes; then : +else + as_fn_error $? "struct sockaddr_in6 not found, needed for ipv6 transport support." "$LINENO" 5 +fi -$as_echo "#define HAVE_INET_NTOA 1" >>confdefs.h +ac_fn_c_check_decl "$LINENO" "SO_MARK" "ac_cv_have_decl_SO_MARK" "${SOCKET_INCLUDES} +" +if test "x$ac_cv_have_decl_SO_MARK" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi -$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SO_MARK $ac_have_decl +_ACEOF -$as_echo "#define HAVE_GETSOCKOPT 1" >>confdefs.h +ac_fn_c_check_decl "$LINENO" "SIGHUP" "ac_cv_have_decl_SIGHUP" " + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif -$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h +" +if test "x$ac_cv_have_decl_SIGHUP" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGHUP $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : -$as_echo "#define HAVE_POLL 1" >>confdefs.h +else +$as_echo "#define SIGHUP 1" >>confdefs.h -else +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 -$as_echo_n "checking return type of signal handlers... " >&6; } -if test "${ac_cv_type_signal+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <signal.h> +ac_fn_c_check_decl "$LINENO" "SIGINT" "ac_cv_have_decl_SIGINT" " + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_type_signal=int + +" +if test "x$ac_cv_have_decl_SIGINT" = x""yes; then : + ac_have_decl=1 else - ac_cv_type_signal=void + ac_have_decl=0 fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 -$as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal +#define HAVE_DECL_SIGINT $ac_have_decl _ACEOF +if test $ac_have_decl = 1; then : + +else + +$as_echo "#define SIGINT 2" >>confdefs.h +fi +ac_fn_c_check_decl "$LINENO" "SIGUSR1" "ac_cv_have_decl_SIGUSR1" " + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 -$as_echo_n "checking for library containing socket... " >&6; } -if test "${ac_cv_search_socket+set}" = set; then : - $as_echo_n "(cached) " >&6 + +" +if test "x$ac_cv_have_decl_SIGUSR1" = x""yes; then : + ac_have_decl=1 else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ac_have_decl=0 +fi -/* 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 socket (); -int -main () -{ -return socket (); - ; - return 0; -} +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGUSR1 $ac_have_decl _ACEOF -for ac_lib in '' socket; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_socket=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_socket+set}" = set; then : - break -fi -done -if test "${ac_cv_search_socket+set}" = set; then : +if test $ac_have_decl = 1; then : else - ac_cv_search_socket=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 -$as_echo "$ac_cv_search_socket" >&6; } -ac_res=$ac_cv_search_socket -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define SIGUSR1 10" >>confdefs.h fi +ac_fn_c_check_decl "$LINENO" "SIGUSR2" "ac_cv_have_decl_SIGUSR2" " + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntoa" >&5 -$as_echo_n "checking for library containing inet_ntoa... " >&6; } -if test "${ac_cv_search_inet_ntoa+set}" = set; then : - $as_echo_n "(cached) " >&6 + +" +if test "x$ac_cv_have_decl_SIGUSR2" = x""yes; then : + ac_have_decl=1 else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ac_have_decl=0 +fi -/* 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 inet_ntoa (); -int -main () -{ -return inet_ntoa (); - ; - return 0; -} +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGUSR2 $ac_have_decl _ACEOF -for ac_lib in '' nsl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_inet_ntoa=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_inet_ntoa+set}" = set; then : - break -fi -done -if test "${ac_cv_search_inet_ntoa+set}" = set; then : +if test $ac_have_decl = 1; then : else - ac_cv_search_inet_ntoa=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntoa" >&5 -$as_echo "$ac_cv_search_inet_ntoa" >&6; } -ac_res=$ac_cv_search_inet_ntoa -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define SIGUSR2 12" >>confdefs.h fi +ac_fn_c_check_decl "$LINENO" "SIGTERM" "ac_cv_have_decl_SIGTERM" " + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 -$as_echo_n "checking for library containing gethostbyname... " >&6; } -if test "${ac_cv_search_gethostbyname+set}" = set; then : - $as_echo_n "(cached) " >&6 + +" +if test "x$ac_cv_have_decl_SIGTERM" = x""yes; then : + ac_have_decl=1 else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ac_have_decl=0 +fi -/* 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 gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGTERM $ac_have_decl _ACEOF -for ac_lib in '' resolv nsl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_gethostbyname=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_gethostbyname+set}" = set; then : - break -fi -done -if test "${ac_cv_search_gethostbyname+set}" = set; then : +if test $ac_have_decl = 1; then : else - ac_cv_search_gethostbyname=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 -$as_echo "$ac_cv_search_gethostbyname" >&6; } -ac_res=$ac_cv_search_gethostbyname -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define SIGTERM 15" >>confdefs.h fi - for ac_header in vfork.h +for ac_header in vfork.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" if test "x$ac_cv_header_vfork_h" = x""yes; then : @@ -6711,19 +13909,291 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h fi - for ac_func in gettimeofday +for ac_func in \ + daemon chroot getpwnam setuid nice system getpid dup dup2 \ + getpass strerror syslog openlog mlockall getgrnam setgid \ + setgroups stat flock readv writev time gettimeofday \ + ctime memset vsnprintf strdup \ + setsid chdir putenv getpeername unlink \ + chsize ftruncate execve getpeereid umask basename dirname access \ + epoll_create \ + +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 + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + DL_LIBS="-ldl" + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnsl" >&5 +$as_echo_n "checking for inet_ntoa in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $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 inet_ntoa (); +int +main () +{ +return inet_ntoa (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_inet_ntoa=yes +else + ac_cv_lib_nsl_inet_ntoa=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_nsl_inet_ntoa" >&5 +$as_echo "$ac_cv_lib_nsl_inet_ntoa" >&6; } +if test "x$ac_cv_lib_nsl_inet_ntoa" = x""yes; then : + SOCKETS_LIBS="${SOCKETS_LIBS} -lnsl" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_socket+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $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 socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=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_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = x""yes; then : + SOCKETS_LIBS="${SOCKETS_LIBS} -lsocket" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lresolv" >&5 +$as_echo_n "checking for gethostbyname in -lresolv... " >&6; } +if test "${ac_cv_lib_resolv_gethostbyname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $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 gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_resolv_gethostbyname=yes +else + ac_cv_lib_resolv_gethostbyname=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_resolv_gethostbyname" >&5 +$as_echo "$ac_cv_lib_resolv_gethostbyname" >&6; } +if test "x$ac_cv_lib_resolv_gethostbyname" = x""yes; then : + SOCKETS_LIBS="${SOCKETS_LIBS} -lresolv" + +fi + + + +old_LIBS="${LIBS}" +LIBS="${LIBS} ${SOCKETS_LIBS}" +for ac_func in sendmsg recvmsg 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 res_init do : - ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" -if test "x$ac_cv_func_gettimeofday" = x""yes; then : + ac_fn_c_check_func "$LINENO" "res_init" "ac_cv_func_res_init" +if test "x$ac_cv_func_res_init" = x""yes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_GETTIMEOFDAY 1 +#define HAVE_RES_INIT 1 _ACEOF fi done +# Windows use stdcall for winsock so we cannot auto detect these + + +if test "${WIN32}" = "yes"; then + + +$as_echo "#define HAVE_SOCKET 1" >>confdefs.h + + + +$as_echo "#define HAVE_RECV 1" >>confdefs.h + + + +$as_echo "#define HAVE_RECVFROM 1" >>confdefs.h + + + +$as_echo "#define HAVE_SEND 1" >>confdefs.h + + + +$as_echo "#define HAVE_SENDTO 1" >>confdefs.h + + + +$as_echo "#define HAVE_LISTEN 1" >>confdefs.h + + + +$as_echo "#define HAVE_ACCEPT 1" >>confdefs.h + + + +$as_echo "#define HAVE_CONNECT 1" >>confdefs.h + + + +$as_echo "#define HAVE_BIND 1" >>confdefs.h + + + +$as_echo "#define HAVE_SELECT 1" >>confdefs.h + + + +$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + + + +$as_echo "#define HAVE_INET_NTOA 1" >>confdefs.h + + + +$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h + + + +$as_echo "#define HAVE_GETSOCKOPT 1" >>confdefs.h + + + +$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h + + + +$as_echo "#define HAVE_POLL 1" >>confdefs.h + - for ac_func in socket recv recvfrom send sendto listen accept connect bind select gethostbyname inet_ntoa +else + 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` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6734,10 +14204,11 @@ _ACEOF else as_fn_error $? "Required library function not found" "$LINENO" 5 + fi done - for ac_func in setsockopt getsockopt getsockname poll sendmsg recvmsg + for ac_func in setsockopt getsockopt getsockname poll 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" @@ -6749,129 +14220,153 @@ _ACEOF fi done +fi +LIBS="${old_LIBS}" + + +old_CFLAGS="${CFLAGS}" +CFLAGS="${CFLAGS} ${TAP_CFLAGS}" +for ac_header in \ + net/if_tun.h net/tun/if_tun.h \ + linux/if_tun.h \ + tap-windows.h \ + +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + have_tap_header="yes" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 -$as_echo_n "checking for working memcmp... " >&6; } -if test "${ac_cv_func_memcmp_working+set}" = set; then : - $as_echo_n "(cached) " >&6 +done + +ac_fn_c_check_decl "$LINENO" "TUNSETPERSIST" "ac_cv_have_decl_TUNSETPERSIST" " + #ifdef HAVE_LINUX_IF_TUN_H + #include <linux/if_tun.h> + #endif + + +" +if test "x$ac_cv_have_decl_TUNSETPERSIST" = x""yes; then : + ac_have_decl=1 else - if test "$cross_compiling" = yes; then : - ac_cv_func_memcmp_working=no + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TUNSETPERSIST $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + +$as_echo "#define ENABLE_FEATURE_TUN_PERSIST 1" >>confdefs.h + +fi + +CFLAGS="${old_CFLAGS}" +test "${have_tap_header}" = "yes" || as_fn_error $? "no tap header could be found" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setcon in -lselinux" >&5 +$as_echo_n "checking for setcon in -lselinux... " >&6; } +if test "${ac_cv_lib_selinux_setcon+set}" = set; then : + $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$ac_includes_default + +/* 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 setcon (); int main () { - - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = '\100', c1 = '\200', c2 = '\201'; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - return 1; - - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - return 1; - } - return 0; - } - +return setcon (); ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_memcmp_working=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_selinux_setcon=yes else - ac_cv_func_memcmp_working=no + ac_cv_lib_selinux_setcon=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +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_selinux_setcon" >&5 +$as_echo "$ac_cv_lib_selinux_setcon" >&6; } +if test "x$ac_cv_lib_selinux_setcon" = x""yes; then : + SELINUX_LIBS="-lselinux" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 -$as_echo "$ac_cv_func_memcmp_working" >&6; } -test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" - ;; -esac + + +if test -z "${LIBPAM_LIBS}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 +$as_echo_n "checking for pam_start in -lpam... " >&6; } +if test "${ac_cv_lib_pam_pam_start+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include <resolv.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 pam_start (); int main () { - - res_init (); - +return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: res_init DEFINED" >&5 -$as_echo "res_init DEFINED" >&6; } - -$as_echo "#define HAVE_RES_INIT 1" >>confdefs.h - - + ac_cv_lib_pam_pam_start=yes else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: res_init UNDEFINED" >&5 -$as_echo "res_init UNDEFINED" >&6; } - + ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working epoll implementation..." >&5 -$as_echo "$as_me: checking for working epoll implementation..." >&6;} -OLDLDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -Wl,--fatal-warnings" -ac_fn_c_check_func "$LINENO" "epoll_create" "ac_cv_func_epoll_create" -if test "x$ac_cv_func_epoll_create" = x""yes; then : - -$as_echo "#define HAVE_EPOLL_CREATE 1" >>confdefs.h - +LIBS=$ac_check_lib_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 +$as_echo "$ac_cv_lib_pam_pam_start" >&6; } +if test "x$ac_cv_lib_pam_pam_start" = x""yes; then : + LIBPAM_LIBS="-lpam" -LDFLAGS="$OLDLDFLAGS" +fi +fi -if test "$MEMCHECK" = "valgrind"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for valgrind tool and Header files..." >&5 -$as_echo "$as_me: checking for valgrind tool and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default" +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" if test "x$ac_cv_header_valgrind_memcheck_h" = x""yes; then : + CFLAGS="${CFLAGS} -g -fno-inline" $as_echo "#define USE_VALGRIND 1" >>confdefs.h - CFLAGS="-g -fno-inline" else as_fn_error $? "valgrind headers not found." "$LINENO" 5 @@ -6879,13 +14374,9 @@ else fi -fi - - -if test "$MEMCHECK" = "dmalloc"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dmalloc Library and Header files..." >&5 -$as_echo "$as_me: checking for dmalloc Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "dmalloc.h" "ac_cv_header_dmalloc_h" "$ac_includes_default" + ;; + dmalloc) + 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" = x""yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -ldmalloc" >&5 $as_echo_n "checking for malloc in -ldmalloc... " >&6; } @@ -6925,9 +14416,7 @@ fi $as_echo "$ac_cv_lib_dmalloc_malloc" >&6; } if test "x$ac_cv_lib_dmalloc_malloc" = x""yes; then : - - LIBS="-ldmalloc $LIBS" - + LIBS="${LIBS} -ldmalloc" $as_echo "#define DMALLOC 1" >>confdefs.h @@ -6943,27 +14432,15 @@ else fi -fi - -if test "${WIN32}" != "yes"; then - if test "$PLUGINS" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdl Library and Header files..." >&5 -$as_echo "$as_me: checking for libdl Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" -if test "x$ac_cv_header_dlfcn_h" = x""yes; then : - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = x""yes; then : - -$as_echo "#define USE_LIBDL 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + ;; + ssl) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_mem_ctrl in -lssl" >&5 +$as_echo_n "checking for CRYPTO_mem_ctrl in -lssl... " >&6; } +if test "${ac_cv_lib_ssl_CRYPTO_mem_ctrl+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" +LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6973,131 +14450,156 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char dlopen (); +char CRYPTO_mem_ctrl (); int main () { -return dlopen (); +return CRYPTO_mem_ctrl (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes + ac_cv_lib_ssl_CRYPTO_mem_ctrl=yes else - ac_cv_lib_dl_dlopen=no + ac_cv_lib_ssl_CRYPTO_mem_ctrl=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_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : - - - LIBS="-ldl $LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_CRYPTO_mem_ctrl" >&5 +$as_echo "$ac_cv_lib_ssl_CRYPTO_mem_ctrl" >&6; } +if test "x$ac_cv_lib_ssl_CRYPTO_mem_ctrl" = x""yes; then : -$as_echo "#define USE_LIBDL 1" >>confdefs.h +$as_echo "#define CRYPTO_MDEBUG 1" >>confdefs.h + { $as_echo "$as_me:${as_lineno-$LINENO}: NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG" >&5 +$as_echo "$as_me: NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG" >&6;} else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libdl library not found." >&5 -$as_echo "libdl library not found." >&6; } + as_fn_error $? "Memory Debugging function in OpenSSL library not found." "$LINENO" 5 fi -fi + ;; +esac -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libdl headers not found." >&5 -$as_echo "libdl headers not found." >&6; } +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 "$EUREPHIA" = "yes"; then -$as_echo "#define ENABLE_EUREPHIA 1" >>confdefs.h +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } - fi - fi +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 -if test "${WIN32}" = "yes"; then - if test "$PLUGINS" = "yes"; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { $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 test "${ac_cv_lib_crypto_RSA_new+set}" = set; 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. */ - #include <windows.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 () { - - LoadLibrary (NULL); - +return RSA_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LoadLibrary DEFINED" >&5 -$as_echo "LoadLibrary DEFINED" >&6; } - -$as_echo "#define USE_LOAD_LIBRARY 1" >>confdefs.h - - + ac_cv_lib_crypto_RSA_new=yes else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LoadLibrary UNDEFINED" >&5 -$as_echo "LoadLibrary UNDEFINED" >&6; } - + ac_cv_lib_crypto_RSA_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - fi -fi - - -if test "$LZO" = "yes"; then - LZO_H="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZO Library and Header files..." >&5 -$as_echo "$as_me: checking for LZO Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzo1x.h" "ac_cv_header_lzo_lzo1x_h" "$ac_includes_default" -if test "x$ac_cv_header_lzo_lzo1x_h" = x""yes; then : - LZO_H="2" - lzolibs="lzo2 lzo" - -$as_echo "#define LZO_HEADER_DIR 1" >>confdefs.h - - -else - ac_fn_c_check_header_mongrel "$LINENO" "lzo1x.h" "ac_cv_header_lzo1x_h" "$ac_includes_default" -if test "x$ac_cv_header_lzo1x_h" = x""yes; then : - LZO_H="1" ; lzolibs=lzo +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" = x""yes; then : + have_openssl_crypto="yes" + OPENSSL_CRYPTO_LIBS="-lcrypto" fi - - if test -n "$LZO_H"; then - havelzolib=0 - for i in $lzolibs ; do - if test $havelzolib = 1 ; then break ; fi - as_ac_Lib=`$as_echo "ac_cv_lib_$i''_lzo1x_1_15_compress" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_15_compress in -l$i" >&5 -$as_echo_n "checking for lzo1x_1_15_compress in -l$i... " >&6; } -if eval "test \"\${$as_ac_Lib+set}\"" = set; then : +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 test "${ac_cv_lib_crypto_RSA_new+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-l$i $LIBS" +LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7107,80 +14609,109 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char lzo1x_1_15_compress (); +char RSA_new (); int main () { -return lzo1x_1_15_compress (); +return RSA_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_lib_crypto_RSA_new=yes else - eval "$as_ac_Lib=no" + 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 -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $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" = x""yes; then : + have_openssl_crypto="yes" + OPENSSL_CRYPTO_LIBS="-lcrypto" - LIBS="-l$i $LIBS" - -$as_echo "#define USE_LZO 1" >>confdefs.h +fi -cat >>confdefs.h <<_ACEOF -#define LZO_VERSION_NUM "$LZO_H" -_ACEOF +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 - havelzolib=1 +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_SSL" >&5 +$as_echo_n "checking for OPENSSL_SSL... " >&6; } +if test -n "$OPENSSL_SSL_CFLAGS"; then + pkg_cv_OPENSSL_SSL_CFLAGS="$OPENSSL_SSL_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 + 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` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes fi - - done - if test $havelzolib = 0 ; then - as_fn_error $? "LZO headers were found but LZO library was not found" "$LINENO" 5 - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZO headers were not found" >&5 -$as_echo "LZO headers were not found" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZO library available from http://www.oberhumer.com/opensource/lzo/" >&5 -$as_echo "LZO library available from http://www.oberhumer.com/opensource/lzo/" >&6; } - as_fn_error $? "Or try ./configure --disable-lzo" "$LINENO" 5 - fi + else + pkg_failed=untried +fi +if test -n "$OPENSSL_SSL_LIBS"; then + pkg_cv_OPENSSL_SSL_LIBS="$OPENSSL_SSL_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 + 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` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi -if test "$CRYPTO" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL Crypto Library and Header files..." >&5 -$as_echo "$as_me: checking for OpenSSL Crypto Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_evp_h" = x""yes; then : +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 - as_fn_error $? "OpenSSL Crypto headers not found." "$LINENO" 5 + _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` + else + OPENSSL_SSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libssl >= 0.9.6" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$OPENSSL_SSL_PKG_ERRORS" >&5 - - - for lib in crypto eay32; do - as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_EVP_CIPHER_CTX_init" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_init in -l$lib" >&5 -$as_echo_n "checking for EVP_CIPHER_CTX_init in -l$lib... " >&6; } -if eval "test \"\${$as_ac_Lib+set}\"" = set; then : + { $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 test "${ac_cv_lib_ssl_SSL_CTX_new+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-l$lib $LIBS" +LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7190,148 +14721,144 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char EVP_CIPHER_CTX_init (); +char SSL_CTX_new (); int main () { -return EVP_CIPHER_CTX_init (); +return SSL_CTX_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_lib_ssl_SSL_CTX_new=yes else - eval "$as_ac_Lib=no" + 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 -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : - - cryptofound=1 - - LIBS="-l$lib $LIBS" +{ $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" = x""yes; then : + have_openssl_ssl="yes" + OPENSSL_SSL_LIBS="-lssl" fi - done - - test -n "$cryptofound" || as_fn_error $? "OpenSSL Crypto library not found." "$LINENO" 5 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking that OpenSSL Library is at least version 0.9.6" >&5 -$as_echo_n "checking that OpenSSL Library is at least version 0.9.6... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +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 test "${ac_cv_lib_ssl_SSL_CTX_new+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include <openssl/evp.h> - #if SSLEAY_VERSION_NUMBER >= 0x00906000L - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define USE_CRYPTO 1" >>confdefs.h - - for ac_func in 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" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1 +/* 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 -done +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" = x""yes; then : + have_openssl_ssl="yes" + OPENSSL_SSL_LIBS="-lssl" - for ac_header in openssl/engine.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_engine_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_ENGINE_H 1 -_ACEOF fi -done - - for ac_func in ENGINE_load_builtin_engines -do : - ac_fn_c_check_func "$LINENO" "ENGINE_load_builtin_engines" "ac_cv_func_ENGINE_load_builtin_engines" -if test "x$ac_cv_func_ENGINE_load_builtin_engines" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 -_ACEOF +else + OPENSSL_SSL_CFLAGS=$pkg_cv_OPENSSL_SSL_CFLAGS + OPENSSL_SSL_LIBS=$pkg_cv_OPENSSL_SSL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_openssl_ssl="yes" fi -done - for ac_func in ENGINE_register_all_complete +if test "${have_openssl_crypto}" = "yes"; then + 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 do : - ac_fn_c_check_func "$LINENO" "ENGINE_register_all_complete" "ac_cv_func_ENGINE_register_all_complete" -if test "x$ac_cv_func_ENGINE_register_all_complete" = x""yes; then : + 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" = x""yes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_ENGINE_REGISTER_ALL_COMPLETE 1 +#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1 _ACEOF fi done - for ac_func in ENGINE_cleanup + have_openssl_engine="yes" + for ac_func in \ + ENGINE_load_builtin_engines \ + ENGINE_register_all_complete \ + ENGINE_cleanup \ + do : - ac_fn_c_check_func "$LINENO" "ENGINE_cleanup" "ac_cv_func_ENGINE_cleanup" -if test "x$ac_cv_func_ENGINE_cleanup" = x""yes; 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_ENGINE_CLEANUP 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF -fi -done - - else - as_fn_error $? "OpenSSL crypto Library is too old." "$LINENO" 5 + have_openssl_engine="no"; break fi -rm -f conftest* - - +done - if test "$SSL" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL SSL Library and Header files..." >&5 -$as_echo "$as_me: checking for OpenSSL SSL Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_ssl_h" = x""yes; then : - -else - as_fn_error $? "OpenSSL SSL headers not found." "$LINENO" 5 + CFLAGS="${saved_CFLAGS}" + LIBS="${saved_LIBS}" fi - for lib in ssl ssl32; do - as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_SSL_CTX_new" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -l$lib" >&5 -$as_echo_n "checking for SSL_CTX_new in -l$lib... " >&6; } -if eval "test \"\${$as_ac_Lib+set}\"" = set; then : +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 test "${ac_cv_lib_polarssl_ssl_init+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-l$lib $LIBS" +LIBS="-lpolarssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7341,51 +14868,38 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char SSL_CTX_new (); +char ssl_init (); int main () { -return SSL_CTX_new (); +return ssl_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_lib_polarssl_ssl_init=yes else - eval "$as_ac_Lib=no" + 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 -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : - - sslfound=1 - - LIBS="-l$lib $LIBS" - - - -fi - - done - - test -n "${sslfound}" || as_fn_error $? "OpenSSL SSL library not found." "$LINENO" 5 +{ $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" = x""yes; then : + POLARSSL_LIBS="-lpolarssl" +else - if test "$MEMCHECK" = "ssl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Memory Debugging Capabilities in OpenSSL Library..." >&5 -$as_echo "$as_me: checking for Memory Debugging Capabilities in OpenSSL Library..." >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_mem_ctrl in -lssl" >&5 -$as_echo_n "checking for CRYPTO_mem_ctrl in -lssl... " >&6; } -if test "${ac_cv_lib_ssl_CRYPTO_mem_ctrl+set}" = set; then : + 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 test "${ac_cv_lib_polarssl_aes_crypt_cbc+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl $LIBS" +LIBS="-lpolarssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7395,65 +14909,128 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char CRYPTO_mem_ctrl (); +char aes_crypt_cbc (); int main () { -return CRYPTO_mem_ctrl (); +return aes_crypt_cbc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_CRYPTO_mem_ctrl=yes + ac_cv_lib_polarssl_aes_crypt_cbc=yes else - ac_cv_lib_ssl_CRYPTO_mem_ctrl=no + ac_cv_lib_polarssl_aes_crypt_cbc=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_CRYPTO_mem_ctrl" >&5 -$as_echo "$ac_cv_lib_ssl_CRYPTO_mem_ctrl" >&6; } -if test "x$ac_cv_lib_ssl_CRYPTO_mem_ctrl" = x""yes; then : - - -$as_echo "#define CRYPTO_MDEBUG 1" >>confdefs.h +{ $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" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPOLARSSL 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG" >&5 -$as_echo "NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG" >&6; } + LIBS="-lpolarssl $LIBS" else - as_fn_error $? "Memory Debugging function in OpenSSL library not found." "$LINENO" 5 + have_polarssl_crypto="no" fi - fi -$as_echo "#define USE_SSL 1" >>confdefs.h +fi - fi fi -if test "$X509ALTUSERNAME" = "yes"; then +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}" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <polarssl/version.h> + +int +main () +{ + +#if POLARSSL_VERSION_NUMBER < 0x01010000 +#error invalid version +#endif -$as_echo "#define ENABLE_X509ALTUSERNAME 1" >>confdefs.h + + ; + return 0; +} +_ACEOF +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 $? "invalid polarssl version" "$LINENO" 5 fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="${old_CFLAGS}" +fi + + + +have_lzo="yes" +if test -z "${LZO_LIBS}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_15_compress in -llzo2" >&5 +$as_echo_n "checking for lzo1x_1_15_compress in -llzo2... " >&6; } +if test "${ac_cv_lib_lzo2_lzo1x_1_15_compress+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzo2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -if test "$PKCS11" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pkcs11-helper Library and Header files..." >&5 -$as_echo "$as_me: checking for pkcs11-helper Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "pkcs11-helper-1.0/pkcs11h-core.h" "ac_cv_header_pkcs11_helper_1_0_pkcs11h_core_h" "$ac_includes_default" -if test "x$ac_cv_header_pkcs11_helper_1_0_pkcs11h_core_h" = x""yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pkcs11h_initialize in -lpkcs11-helper" >&5 -$as_echo_n "checking for pkcs11h_initialize in -lpkcs11-helper... " >&6; } -if test "${ac_cv_lib_pkcs11_helper_pkcs11h_initialize+set}" = set; then : +/* 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 lzo1x_1_15_compress (); +int +main () +{ +return lzo1x_1_15_compress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lzo2_lzo1x_1_15_compress=yes +else + ac_cv_lib_lzo2_lzo1x_1_15_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_lzo2_lzo1x_1_15_compress" >&5 +$as_echo "$ac_cv_lib_lzo2_lzo1x_1_15_compress" >&6; } +if test "x$ac_cv_lib_lzo2_lzo1x_1_15_compress" = x""yes; then : + LZO_LIBS="-llzo2" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_15_compress in -llzo" >&5 +$as_echo_n "checking for lzo1x_1_15_compress in -llzo... " >&6; } +if test "${ac_cv_lib_lzo_lzo1x_1_15_compress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lpkcs11-helper $LIBS" +LIBS="-llzo $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7463,234 +15040,442 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char pkcs11h_initialize (); +char lzo1x_1_15_compress (); int main () { -return pkcs11h_initialize (); +return lzo1x_1_15_compress (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pkcs11_helper_pkcs11h_initialize=yes + ac_cv_lib_lzo_lzo1x_1_15_compress=yes else - ac_cv_lib_pkcs11_helper_pkcs11h_initialize=no + ac_cv_lib_lzo_lzo1x_1_15_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_pkcs11_helper_pkcs11h_initialize" >&5 -$as_echo "$ac_cv_lib_pkcs11_helper_pkcs11h_initialize" >&6; } -if test "x$ac_cv_lib_pkcs11_helper_pkcs11h_initialize" = x""yes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzo_lzo1x_1_15_compress" >&5 +$as_echo "$ac_cv_lib_lzo_lzo1x_1_15_compress" >&6; } +if test "x$ac_cv_lib_lzo_lzo1x_1_15_compress" = x""yes; then : + LZO_LIBS="-llzo" +else + have_lzo="no" +fi -$as_echo "#define USE_PKCS11 1" >>confdefs.h +fi - LIBS="-lpkcs11-helper $LIBS" +fi +if test "${have_lzo}" = "yes"; then + saved_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${LZO_CFLAGS}" + for ac_header in lzo/lzoutil.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzoutil.h" "ac_cv_header_lzo_lzoutil_h" "$ac_includes_default" +if test "x$ac_cv_header_lzo_lzoutil_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZO_LZOUTIL_H 1 +_ACEOF +else + for ac_header in lzoutil.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lzoutil.h" "ac_cv_header_lzoutil_h" "$ac_includes_default" +if test "x$ac_cv_header_lzoutil_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZOUTIL_H 1 +_ACEOF else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: pkcs11-helper library not found." >&5 -$as_echo "pkcs11-helper library not found." >&6; } + as_fn_error $? "lzoutil.h is missing" "$LINENO" 5 fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: pkcs11-helper headers not found." >&5 -$as_echo "pkcs11-helper headers not found." >&6; } +done + fi +done -fi + for ac_header in lzo/lzo1x.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzo1x.h" "ac_cv_header_lzo_lzo1x_h" "$ac_includes_default" +if test "x$ac_cv_header_lzo_lzo1x_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZO_LZO1X_H 1 +_ACEOF -if test "$MULTI" = "yes"; then +else + for ac_header in lzo1x.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lzo1x.h" "ac_cv_header_lzo1x_h" "$ac_includes_default" +if test "x$ac_cv_header_lzo1x_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZO1X_H 1 +_ACEOF -$as_echo "#define ENABLE_CLIENT_SERVER 1" >>confdefs.h +else + as_fn_error $? "lzo1x.h is missing" "$LINENO" 5 fi -if test "$MULTI_SERVER" = "no"; then +done -$as_echo "#define ENABLE_CLIENT_ONLY 1" >>confdefs.h fi -if test "$MANAGEMENT" = "yes"; then - -$as_echo "#define ENABLE_MANAGEMENT 1" >>confdefs.h +done + CFLAGS="${saved_CFLAGS}" fi -if test "$SOCKS" = "yes"; then -$as_echo "#define ENABLE_SOCKS 1" >>confdefs.h +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS11_HELPER" >&5 +$as_echo_n "checking for PKCS11_HELPER... " >&6; } +if test -n "$PKCS11_HELPER_CFLAGS"; then + pkg_cv_PKCS11_HELPER_CFLAGS="$PKCS11_HELPER_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpkcs11-helper-1 >= 1.02\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpkcs11-helper-1 >= 1.02") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PKCS11_HELPER_CFLAGS=`$PKG_CONFIG --cflags "libpkcs11-helper-1 >= 1.02" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PKCS11_HELPER_LIBS"; then + pkg_cv_PKCS11_HELPER_LIBS="$PKCS11_HELPER_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpkcs11-helper-1 >= 1.02\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpkcs11-helper-1 >= 1.02") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PKCS11_HELPER_LIBS=`$PKG_CONFIG --libs "libpkcs11-helper-1 >= 1.02" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi -if test "$HTTP_PROXY" = "yes"; then -$as_echo "#define ENABLE_HTTP_PROXY 1" >>confdefs.h +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 + PKCS11_HELPER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpkcs11-helper-1 >= 1.02" 2>&1` + else + PKCS11_HELPER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpkcs11-helper-1 >= 1.02" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PKCS11_HELPER_PKG_ERRORS" >&5 -if test "$MULTIHOME" = "yes"; then -$as_echo "#define ENABLE_MULTIHOME 1" >>confdefs.h +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + +else + PKCS11_HELPER_CFLAGS=$pkg_cv_PKCS11_HELPER_CFLAGS + PKCS11_HELPER_LIBS=$pkg_cv_PKCS11_HELPER_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_pkcs11_helper="yes" fi -if test "$DEBUG" = "yes"; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking git checkout" >&5 +$as_echo_n "checking git checkout... " >&6; } +GIT_CHECKOUT="no" +if test -n "${GIT}" -a -d "${srcdir}/.git"; then -$as_echo "#define ENABLE_DEBUG 1" >>confdefs.h +$as_echo "#define HAVE_CONFIG_VERSION_H 1" >>confdefs.h + GIT_CHECKOUT="yes" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${GIT_CHECKOUT}" >&5 +$as_echo "${GIT_CHECKOUT}" >&6; } -if test "$SMALL" = "yes"; then +if test -n "${SP_PLATFORM_WINDOWS}"; then -$as_echo "#define ENABLE_SMALL 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define PATH_SEPARATOR '\\\\' +_ACEOF + #" + +cat >>confdefs.h <<_ACEOF +#define PATH_SEPARATOR_STR "\\\\" +_ACEOF + #" +else + +cat >>confdefs.h <<_ACEOF +#define PATH_SEPARATOR '/' +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PATH_SEPARATOR_STR "/" +_ACEOF fi -if test "$FRAGMENT" = "yes"; then +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 + fi -$as_echo "#define ENABLE_FRAGMENT 1" >>confdefs.h + +$as_echo "#define ENABLE_X509ALTUSERNAME 1" >>confdefs.h fi -if test "$PORT_SHARE" = "yes"; then +test "${ac_cv_header_sys_uio_h}" = "yes" && +$as_echo "#define HAVE_IOVEC 1" >>confdefs.h + +test "${enable_multi}" = "yes" && +$as_echo "#define ENABLE_CLIENT_SERVER 1" >>confdefs.h + +test "${enable_server}" = "no" && +$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 + +test "${enable_debug}" = "yes" && +$as_echo "#define ENABLE_DEBUG 1" >>confdefs.h + +test "${enable_small}" = "yes" && +$as_echo "#define ENABLE_SMALL 1" >>confdefs.h +test "${enable_fragment}" = "yes" && +$as_echo "#define ENABLE_FRAGMENT 1" >>confdefs.h + +test "${enable_port_share}" = "yes" && $as_echo "#define ENABLE_PORT_SHARE 1" >>confdefs.h -fi +test "${enable_def_auth}" = "yes" && +$as_echo "#define ENABLE_DEF_AUTH 1" >>confdefs.h -if test "$DEF_AUTH" = "yes"; then +test "${enable_pf}" = "yes" && +$as_echo "#define ENABLE_PF 1" >>confdefs.h -$as_echo "#define CONFIGURE_DEF_AUTH 1" >>confdefs.h +test "${enable_strict_options}" = "yes" && +$as_echo "#define ENABLE_STRICT_OPTIONS_CHECK 1" >>confdefs.h -fi +test "${enable_password_save}" = "yes" && +$as_echo "#define ENABLE_PASSWORD_SAVE 1" >>confdefs.h -if test "$PF" = "yes"; then +test "${enable_systemd}" = "yes" && +$as_echo "#define ENABLE_SYSTEMD 1" >>confdefs.h -$as_echo "#define CONFIGURE_PF 1" >>confdefs.h -fi +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}" -if test "$STRICT" = "yes"; then - CFLAGS="$CFLAGS -Wall -Wno-unused-parameter -Wno-unused-function" -fi +$as_echo "#define ENABLE_CRYPTO_OPENSSL 1" >>confdefs.h -if test "$PEDANTIC" = "yes"; then - CFLAGS="$CFLAGS -ansi -pedantic" -fi + test "${have_openssl_engine}" = "yes" && +$as_echo "#define HAVE_OPENSSL_ENGINE 1" >>confdefs.h -if test "$PROFILE" = "yes"; then - CFLAGS="$CFLAGS -pg -DENABLE_PROFILING" -fi + ;; + polarssl) + have_crypto_crypto="${have_polarssl_crypto}" + have_crypto_ssl="${have_polarssl_ssl}" + CRYPTO_CRYPTO_CFLAGS="${POLARSSL_CFLAGS}" + CRYPTO_CRYPTO_LIBS="${POLARSSL_LIBS}" -if test "$STRICT_OPTIONS" = "yes"; then +$as_echo "#define ENABLE_CRYPTO_POLARSSL 1" >>confdefs.h + + ;; +esac -$as_echo "#define STRICT_OPTIONS_CHECK 1" >>confdefs.h +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 "$PASSWORD_SAVE" = "yes"; then +if test "${enable_crypto}" = "yes"; then + test "${have_crypto_crypto}" != "yes" && as_fn_error $? "${with_crypto_library} crytpo is required but missing" "$LINENO" 5 + OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}" + OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}" -$as_echo "#define ENABLE_PASSWORD_SAVE 1" >>confdefs.h +$as_echo "#define ENABLE_CRYPTO 1" >>confdefs.h fi -if test "$SELINUX" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libselinux Library and Header files..." >&5 -$as_echo "$as_me: checking for libselinux Library and Header files..." >&6;} - ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" -if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setcon in -lselinux" >&5 -$as_echo_n "checking for setcon in -lselinux... " >&6; } -if test "${ac_cv_lib_selinux_setcon+set}" = set; then : - $as_echo_n "(cached) " >&6 +if test "${enable_plugins}" = "yes"; then + OPTIONAL_DL_LIBS="${DL_LIBS}" + +$as_echo "#define ENABLE_PLUGIN 1" >>confdefs.h + + test "${enable_eurephia}" = "yes" && +$as_echo "#define ENABLE_EUREPHIA 1" >>confdefs.h + else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lselinux $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + enable_plugin_auth_pam="no" + enable_plugin_down_root="no" +fi + +if test "${enable_iproute2}" = "yes"; then + test -z "${IPROUTE}" && as_fn_error $? "ip utility is required but missing" "$LINENO" 5 + +$as_echo "#define ENABLE_IPROUTE 1" >>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 setcon (); -int -main () -{ -return setcon (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_selinux_setcon=yes else - ac_cv_lib_selinux_setcon=no + if test "${WIN32}" != "yes"; then + test -z "${ROUTE}" && as_fn_error $? "route utility is required but missing" "$LINENO" 5 + test -z "${IFCONFIG}" && as_fn_error $? "ifconfig utility is required but missing" "$LINENO" 5 + fi fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + +if test "${enable_selinux}" = "yes"; then + test -z "${SELINUX_LIBS}" && as_fn_error $? "libselinux required but missing" "$LINENO" 5 + OPTIONAL_SELINUX_LIBS="${SELINUX_LIBS}" + +$as_echo "#define ENABLE_SELINUX 1" >>confdefs.h + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_setcon" >&5 -$as_echo "$ac_cv_lib_selinux_setcon" >&6; } -if test "x$ac_cv_lib_selinux_setcon" = x""yes; then : +if test "${enable_lzo}" = "yes"; then + test "${have_lzo}" != "yes" && as_fn_error $? "lzo enabled but missing" "$LINENO" 5 + OPTIONAL_LZO_CFLAGS="${LZO_CFLAGS}" + OPTIONAL_LZO_LIBS="${LZO_LIBS}" - LIBS="-lselinux $LIBS" +$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 HAVE_SETCON 1" >>confdefs.h +$as_echo "#define ENABLE_LZO_STUB 1" >>confdefs.h -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: SELinux library not found." >&5 -$as_echo "SELinux library not found." >&6; } +$as_echo "#define ENABLE_LZO 1" >>confdefs.h fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: SELinux headers not found." >&5 -$as_echo "SELinux headers not found." >&6; } +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 + OPTIONAL_PKCS11_HELPER_CFLAGS="${PKCS11_HELPER_CFLAGS}" + OPTIONAL_PKCS11_HELPER_LIBS="${PKCS11_HELPER_LIBS}" + +$as_echo "#define ENABLE_PKCS11 1" >>confdefs.h fi +if test "${enable_pedantic}" = "yes"; then + enable_strict="yes" + CFLAGS="${CFLAGS} -pedantic" + test "${WIN32}" != "yes" && CFLAGS="${CFLAGS} -ansi" +fi +if test "${enable_strict}" = "yes"; then + CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function" +fi +if test "${WIN32}" = "yes"; then + test -z "${MAN2HTML}" && as_fn_error $? "man2html is required for win32" "$LINENO" 5 fi -TAP_ID="tap0901" -TAP_WIN32_MIN_MAJOR="9" -TAP_WIN32_MIN_MINOR="8" +if test "${enable_plugin_auth_pam}" = "yes"; then + PLUGIN_AUTH_PAM_CFLAGS="${LIBPAM_CFLAGS}" + if test "${enable_pam_dlopen}" = "yes"; then + +$as_echo "#define USE_PAM_DLOPEN 1" >>confdefs.h + + PLUGIN_AUTH_PAM_LIBS="${DL_LIBS}" + else + test -z "${LIBPAM_LIBS}" && as_fn_error $? "libpam required but missing" "$LINENO" 5 + PLUGIN_AUTH_PAM_LIBS="${LIBPAM_LIBS}" + fi +fi + +CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`" + +cat >>confdefs.h <<_ACEOF +#define CONFIGURE_DEFINES "`echo ${CONFIGURE_DEFINES}`" +_ACEOF + + +TAP_WIN_COMPONENT_ID="tap0901" +TAP_WIN_MIN_MAJOR="9" +TAP_WIN_MIN_MINOR="9" cat >>confdefs.h <<_ACEOF -#define TAP_ID "${TAP_ID}" +#define TAP_WIN_COMPONENT_ID "${TAP_WIN_COMPONENT_ID}" _ACEOF cat >>confdefs.h <<_ACEOF -#define TAP_WIN32_MIN_MAJOR ${TAP_WIN32_MIN_MAJOR} +#define TAP_WIN_MIN_MAJOR ${TAP_WIN_MIN_MAJOR} _ACEOF cat >>confdefs.h <<_ACEOF -#define TAP_WIN32_MIN_MINOR ${TAP_WIN32_MIN_MINOR} +#define TAP_WIN_MIN_MINOR ${TAP_WIN_MIN_MINOR} _ACEOF -win32datadir="\${datadir}/${PACKAGE}-win32" + + + + + + + + + + + if test "${WIN32}" = "yes"; then WIN32_TRUE= @@ -7700,21 +15485,39 @@ else WIN32_FALSE= fi + if test "${GIT_CHECKOUT}" = "yes"; then + GIT_CHECKOUT_TRUE= + GIT_CHECKOUT_FALSE='#' +else + GIT_CHECKOUT_TRUE='#' + GIT_CHECKOUT_FALSE= +fi -# workaround for <autoconf-2.60 -if test -z "${docdir}"; then - docdir="\$(datadir)/doc/\$(PACKAGE_NAME)" - + if test "${enable_plugin_auth_pam}" = "yes"; then + ENABLE_PLUGIN_AUTH_PAM_TRUE= + ENABLE_PLUGIN_AUTH_PAM_FALSE='#' +else + ENABLE_PLUGIN_AUTH_PAM_TRUE='#' + ENABLE_PLUGIN_AUTH_PAM_FALSE= fi -if test -z "${htmldir}"; then - htmldir="\$(docdir)" + if test "${enable_plugin_down_root}" = "yes"; then + ENABLE_PLUGIN_DOWN_ROOT_TRUE= + ENABLE_PLUGIN_DOWN_ROOT_FALSE='#' +else + ENABLE_PLUGIN_DOWN_ROOT_TRUE='#' + ENABLE_PLUGIN_DOWN_ROOT_FALSE= fi -# end workaround -ac_config_files="$ac_config_files t_client.sh" -ac_config_files="$ac_config_files Makefile openvpn.spec images/Makefile service-win32/Makefile install-win32/Makefile install-win32/settings" +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" + +ac_config_files="$ac_config_files tests/t_client.sh" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -7834,6 +15637,18 @@ 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 fi +if test -z "${GIT_CHECKOUT_TRUE}" && test -z "${GIT_CHECKOUT_FALSE}"; then + as_fn_error $? "conditional \"GIT_CHECKOUT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_PLUGIN_AUTH_PAM_TRUE}" && test -z "${ENABLE_PLUGIN_AUTH_PAM_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_PLUGIN_AUTH_PAM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_PLUGIN_DOWN_ROOT_TRUE}" && test -z "${ENABLE_PLUGIN_DOWN_ROOT_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_PLUGIN_DOWN_ROOT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 @@ -8016,16 +15831,16 @@ as_fn_exit () exit $1 } # as_fn_exit -# as_fn_unset VAR -# --------------- +# as_fn_unset ax_cv_socklen_t_equiv +# --------------------------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- +# as_fn_append ax_cv_socklen_t_equiv VALUE +# ---------------------------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive @@ -8242,7 +16057,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.2.1, which was +This file was extended by OpenVPN $as_me 2.3_rc1, which was generated by GNU Autoconf 2.66. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8308,7 +16123,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.2.1 +OpenVPN config.status 2.3_rc1 configured by $0, generated by GNU Autoconf 2.66, with options \\"\$ac_cs_config\\" @@ -8423,6 +16238,346 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +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"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +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_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"`' +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"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +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"`' +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"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +LD_RC='`$ECHO "$LD_RC" | $SED "$delay_single_quote_subst"`' +reload_flag_RC='`$ECHO "$reload_flag_RC" | $SED "$delay_single_quote_subst"`' +reload_cmds_RC='`$ECHO "$reload_cmds_RC" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_RC='`$ECHO "$old_archive_cmds_RC" | $SED "$delay_single_quote_subst"`' +compiler_RC='`$ECHO "$compiler_RC" | $SED "$delay_single_quote_subst"`' +GCC_RC='`$ECHO "$GCC_RC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_RC='`$ECHO "$lt_prog_compiler_no_builtin_flag_RC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_RC='`$ECHO "$lt_prog_compiler_wl_RC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_RC='`$ECHO "$lt_prog_compiler_pic_RC" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_RC='`$ECHO "$lt_prog_compiler_static_RC" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_RC='`$ECHO "$lt_cv_prog_compiler_c_o_RC" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_RC='`$ECHO "$archive_cmds_need_lc_RC" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_RC='`$ECHO "$enable_shared_with_static_runtimes_RC" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_RC='`$ECHO "$export_dynamic_flag_spec_RC" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_RC='`$ECHO "$whole_archive_flag_spec_RC" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_RC='`$ECHO "$compiler_needs_object_RC" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_RC='`$ECHO "$old_archive_from_new_cmds_RC" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_RC='`$ECHO "$old_archive_from_expsyms_cmds_RC" | $SED "$delay_single_quote_subst"`' +archive_cmds_RC='`$ECHO "$archive_cmds_RC" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_RC='`$ECHO "$archive_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' +module_cmds_RC='`$ECHO "$module_cmds_RC" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_RC='`$ECHO "$module_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_RC='`$ECHO "$with_gnu_ld_RC" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_RC='`$ECHO "$allow_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_RC='`$ECHO "$no_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_RC='`$ECHO "$hardcode_libdir_flag_spec_RC" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_RC='`$ECHO "$hardcode_libdir_flag_spec_ld_RC" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_RC='`$ECHO "$hardcode_libdir_separator_RC" | $SED "$delay_single_quote_subst"`' +hardcode_direct_RC='`$ECHO "$hardcode_direct_RC" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_RC='`$ECHO "$hardcode_direct_absolute_RC" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_RC='`$ECHO "$hardcode_minus_L_RC" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_RC='`$ECHO "$hardcode_shlibpath_var_RC" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_RC='`$ECHO "$hardcode_automatic_RC" | $SED "$delay_single_quote_subst"`' +inherit_rpath_RC='`$ECHO "$inherit_rpath_RC" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_RC='`$ECHO "$link_all_deplibs_RC" | $SED "$delay_single_quote_subst"`' +fix_srcfile_path_RC='`$ECHO "$fix_srcfile_path_RC" | $SED "$delay_single_quote_subst"`' +always_export_symbols_RC='`$ECHO "$always_export_symbols_RC" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_RC='`$ECHO "$export_symbols_cmds_RC" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_RC='`$ECHO "$exclude_expsyms_RC" | $SED "$delay_single_quote_subst"`' +include_expsyms_RC='`$ECHO "$include_expsyms_RC" | $SED "$delay_single_quote_subst"`' +prelink_cmds_RC='`$ECHO "$prelink_cmds_RC" | $SED "$delay_single_quote_subst"`' +file_list_spec_RC='`$ECHO "$file_list_spec_RC" | $SED "$delay_single_quote_subst"`' +hardcode_action_RC='`$ECHO "$hardcode_action_RC" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +LD_RC \ +reload_flag_RC \ +compiler_RC \ +lt_prog_compiler_no_builtin_flag_RC \ +lt_prog_compiler_wl_RC \ +lt_prog_compiler_pic_RC \ +lt_prog_compiler_static_RC \ +lt_cv_prog_compiler_c_o_RC \ +export_dynamic_flag_spec_RC \ +whole_archive_flag_spec_RC \ +compiler_needs_object_RC \ +with_gnu_ld_RC \ +allow_undefined_flag_RC \ +no_undefined_flag_RC \ +hardcode_libdir_flag_spec_RC \ +hardcode_libdir_flag_spec_ld_RC \ +hardcode_libdir_separator_RC \ +fix_srcfile_path_RC \ +exclude_expsyms_RC \ +include_expsyms_RC \ +file_list_spec_RC; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_RC \ +old_archive_cmds_RC \ +old_archive_from_new_cmds_RC \ +old_archive_from_expsyms_cmds_RC \ +archive_cmds_RC \ +archive_expsym_cmds_RC \ +module_cmds_RC \ +module_expsym_cmds_RC \ +export_symbols_cmds_RC \ +prelink_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\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +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 which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 @@ -8433,13 +16588,27 @@ do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "t_client.sh") CONFIG_FILES="$CONFIG_FILES t_client.sh" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "version.sh") CONFIG_FILES="$CONFIG_FILES version.sh" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "openvpn.spec") CONFIG_FILES="$CONFIG_FILES openvpn.spec" ;; - "images/Makefile") CONFIG_FILES="$CONFIG_FILES images/Makefile" ;; - "service-win32/Makefile") CONFIG_FILES="$CONFIG_FILES service-win32/Makefile" ;; - "install-win32/Makefile") CONFIG_FILES="$CONFIG_FILES install-win32/Makefile" ;; - "install-win32/settings") CONFIG_FILES="$CONFIG_FILES install-win32/settings" ;; + "build/Makefile") CONFIG_FILES="$CONFIG_FILES build/Makefile" ;; + "build/msvc/Makefile") CONFIG_FILES="$CONFIG_FILES build/msvc/Makefile" ;; + "build/msvc/msvc-generate/Makefile") CONFIG_FILES="$CONFIG_FILES build/msvc/msvc-generate/Makefile" ;; + "distro/Makefile") CONFIG_FILES="$CONFIG_FILES distro/Makefile" ;; + "distro/rpm/Makefile") CONFIG_FILES="$CONFIG_FILES distro/rpm/Makefile" ;; + "distro/rpm/openvpn.spec") CONFIG_FILES="$CONFIG_FILES distro/rpm/openvpn.spec" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/compat/Makefile") CONFIG_FILES="$CONFIG_FILES src/compat/Makefile" ;; + "src/openvpn/Makefile") CONFIG_FILES="$CONFIG_FILES src/openvpn/Makefile" ;; + "src/openvpnserv/Makefile") CONFIG_FILES="$CONFIG_FILES src/openvpnserv/Makefile" ;; + "src/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/Makefile" ;; + "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" ;; + "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" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -9127,7 +17296,796 @@ $as_echo X"$file" | done } ;; - "t_client.sh":F) chmod +x t_client.sh ;; + "libtool":C) + + # 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 + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$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. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 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. +# +# 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 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 " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +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 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 of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# 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 + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# 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 +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# 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 +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# 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 () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# 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 () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# 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_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}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# 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 () +{ + # Extract subdirectory from the argument. + 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_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} + + +# 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 +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: RC + +# The linker used to build libraries. +LD=$lt_LD_RC + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_RC +reload_cmds=$lt_reload_cmds_RC + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_RC + +# A language specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU compiler? +with_gcc=$GCC_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_RC + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_RC + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_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 +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_RC + +# 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 +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_RC + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_RC + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_RC + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_RC + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_RC + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_RC + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# ### END LIBTOOL TAG CONFIG: RC +_LT_EOF + + ;; + "tests/t_client.sh":F) chmod +x tests/t_client.sh ;; esac done # for ac_tag diff --git a/configure.ac b/configure.ac index e0847bc..d3d974d 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ dnl packet encryption, packet authentication, and dnl packet compression. dnl dnl Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +dnl Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by @@ -23,333 +24,365 @@ dnl 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl Process this file with autoconf to produce a configure script. -AC_PREREQ(2.50) +AC_PREREQ(2.59) m4_include(version.m4) -AC_INIT([OpenVPN], [PRODUCT_VERSION], [openvpn-users@lists.sourceforge.net], [openvpn]) -AM_CONFIG_HEADER(config.h) -AC_CONFIG_SRCDIR(syshead.h) - -dnl Guess host type. +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_CONFIG_AUX_DIR([.]) +AM_CONFIG_HEADER([config.h]) +AC_CONFIG_SRCDIR([src/openvpn/syshead.h]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(openvpn, [$PACKAGE_VERSION]) - -AC_ARG_WITH(cygwin-native, - [ --with-cygwin-native Compile native win32], - [CYGWIN_NATIVE="${withval}"], - [CYGWIN_NATIVE="no"] -) - -WIN32="no" -CYGWIN="no" -case "${host}" in - *-mingw*) - WIN32="yes" - cross_compiling="yes" - ;; - *-*-cygwin*) - AC_MSG_CHECKING([cygwin mode to use]) - if test "${CYGWIN_NATIVE}" = "yes"; then - AC_MSG_RESULT([Using native win32]) - CFLAGS="${CFLAGS} -mno-cygwin" - CYGWIN="yes" - WIN32="yes" - else - AC_MSG_RESULT([Using cygwin]) - fi - ;; - *) - ;; -esac - -AC_ARG_ENABLE(lzo, - [ --disable-lzo Disable LZO compression support], - [LZO="$enableval"], - [LZO="yes"] -) +AC_USE_SYSTEM_EXTENSIONS -AC_ARG_ENABLE(crypto, - [ --disable-crypto Disable OpenSSL crypto support], - [CRYPTO="$enableval"], - [CRYPTO="yes"] +AC_ARG_ENABLE( + [lzo], + [AS_HELP_STRING([--disable-lzo], [disable LZO compression support @<:@default=yes@:>@])], + , + [enable_lzo="yes"] ) -AC_ARG_ENABLE(ssl, - [ --disable-ssl Disable OpenSSL SSL support for TLS-based key exchange], - [SSL="$enableval"], - [SSL="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(x509-alt-username, - [ --enable-x509-alt-username Enable the --x509-username-field feature], - [X509ALTUSERNAME="$enableval"], - [X509ALTUSERNAME="no"] +AC_ARG_ENABLE( + [crypto], + [AS_HELP_STRING([--disable-crypto], [disable crypto support @<:@default=yes@:>@])], + , + [enable_crypto="yes"] ) -AC_ARG_ENABLE(multi, - [ --disable-multi Disable client/server support (--mode server + client mode)], - [MULTI="$enableval"], - [MULTI="yes"] +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(server, - [ --disable-server Disable server support only (but retain client support)], - [MULTI_SERVER="$enableval"], - [MULTI_SERVER="yes"] +AC_ARG_ENABLE( + [x509-alt-username], + [AS_HELP_STRING([--enable-x509-alt-username], [enable the --x509-username-field feature @<:@default=no@:>@])], + , + [enable_x509_alt_username="no"] ) -AC_ARG_ENABLE(plugins, - [ --disable-plugins Disable plug-in support], - [PLUGINS="$enableval"], - [PLUGINS="yes"] +AC_ARG_ENABLE( + [multi], + [AS_HELP_STRING([--disable-multi], [disable client/server support (--mode server + client mode) @<:@default=yes@:>@])], + , + [enable_multi="yes"] ) -AC_ARG_ENABLE(eurephia, - [ --disable-eurephia Disable support for the eurephia plug-in], - [EUREPHIA="$enableval"], - [EUREPHIA="yes"] +AC_ARG_ENABLE( + [server], + [AS_HELP_STRING([--disable-server], [disable server support only (but retain client support) @<:@default=yes@:>@])], + , + [enable_server="yes"] ) -AC_ARG_ENABLE(management, - [ --disable-management Disable management server support], - [MANAGEMENT="$enableval"], - [MANAGEMENT="yes"] +AC_ARG_ENABLE( + [plugins], + [AS_HELP_STRING([--disable-plugins], [disable plug-in support @<:@default=yes@:>@])], + , + [enable_plugins="yes"] ) -AC_ARG_ENABLE(pkcs11, - [ --disable-pkcs11 Disable pkcs11 support], - [PKCS11="$enableval"], - [PKCS11="yes"] +AC_ARG_ENABLE( + [eurephia], + [AS_HELP_STRING([--disable-eurephia], [disable support for the eurephia plug-in @<:@default=yes@:>@])], + , + [enable_eurephia="yes"] ) -AC_ARG_ENABLE(socks, - [ --disable-socks Disable Socks support], - [SOCKS="$enableval"], - [SOCKS="yes"] +AC_ARG_ENABLE( + [management], + [AS_HELP_STRING([--disable-management], [disable management server support @<:@default=yes@:>@])], + , + [enable_management="yes"] ) -AC_ARG_ENABLE(http, - [ --disable-http Disable HTTP proxy support], - [HTTP_PROXY="$enableval"], - [HTTP_PROXY="yes"] +AC_ARG_ENABLE( + [pkcs11], + [AS_HELP_STRING([--enable-pkcs11], [enable pkcs11 support @<:@default=no@:>@])], + , + [enable_pkcs11="no"] ) -AC_ARG_ENABLE(fragment, - [ --disable-fragment Disable internal fragmentation support (--fragment)], - [FRAGMENT="$enableval"], - [FRAGMENT="yes"] +AC_ARG_ENABLE( + [socks], + [AS_HELP_STRING([--disable-socks], [disable Socks support @<:@default=yes@:>@])], + , + [enable_socks="yes"] ) -AC_ARG_ENABLE(multihome, - [ --disable-multihome Disable multi-homed UDP server support (--multihome)], - [MULTIHOME="$enableval"], - [MULTIHOME="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(port-share, - [ --disable-port-share Disable TCP server port-share support (--port-share)], - [PORT_SHARE="$enableval"], - [PORT_SHARE="yes"] +AC_ARG_ENABLE( + [fragment], + [AS_HELP_STRING([--disable-fragment], [disable internal fragmentation support (--fragment) @<:@default=yes@:>@])], + , + [enable_fragment="yes"] ) -AC_ARG_ENABLE(debug, - [ --disable-debug Disable debugging support (disable gremlin and verb 7+ messages)], - [DEBUG="$enableval"], - [DEBUG="yes"] +AC_ARG_ENABLE( + [multihome], + [AS_HELP_STRING([--disable-multihome], [disable multi-homed UDP server support (--multihome) @<:@default=yes@:>@])], + , + [enable_multihome="yes"] ) -AC_ARG_ENABLE(small, - [ --enable-small Enable smaller executable size (disable OCC, usage message, and verb 4 parm list)], - [SMALL="$enableval"], - [SMALL="no"] +AC_ARG_ENABLE( + [port-share], + [AS_HELP_STRING([--disable-port-share], [disable TCP server port-share support (--port-share) @<:@default=yes@:>@])], + , + [enable_port_share="yes"] ) -AC_ARG_ENABLE(password-save, - [ --enable-password-save Allow --askpass and --auth-user-pass passwords to be read from a file], - [PASSWORD_SAVE="$enableval"], - [PASSWORD_SAVE="no"] +AC_ARG_ENABLE( + [debug], + [AS_HELP_STRING([--disable-debug], [disable debugging support (disable gremlin and verb 7+ messages) @<:@default=yes@:>@])], + , + [enable_debug="yes"] ) -AC_ARG_ENABLE(iproute2, - [ --enable-iproute2 Enable support for iproute2], - test $enableval = "yes" && AC_DEFINE(CONFIG_FEATURE_IPROUTE, 1, [enable iproute2 support]) +AC_ARG_ENABLE( + [small], + [AS_HELP_STRING([--enable-small], [enable smaller executable size (disable OCC, usage message, and verb 4 parm list) @<:@default=yes@:>@])], + , + [enable_small="no"] ) -AC_ARG_ENABLE(def-auth, - [ --disable-def-auth Disable deferred authentication], - [DEF_AUTH="$enableval"], - [DEF_AUTH="yes"] +AC_ARG_ENABLE( + [password-save], + [AS_HELP_STRING([--enable-password-save], [allow --askpass and --auth-user-pass passwords to be read from a file @<:@default=yes@:>@])], + , + [enable_password_save="no"] ) -AC_ARG_ENABLE(pf, - [ --disable-pf Disable internal packet filter], - [PF="$enableval"], - [PF="yes"] +AC_ARG_ENABLE( + [iproute2], + [AS_HELP_STRING([--enable-iproute2], [enable support for iproute2 @<:@default=no@:>@])], + , + [enable_iproute2="no"] ) -AC_ARG_ENABLE(strict, - [ --enable-strict Enable strict compiler warnings (debugging option)], - [STRICT="$enableval"], - [STRICT="no"] +AC_ARG_ENABLE( + [def-auth], + [AS_HELP_STRING([--disable-def-auth], [disable deferred authentication @<:@default=yes@:>@])], + , + [enable_def_auth="yes"] ) -AC_ARG_ENABLE(pedantic, - [ --enable-pedantic Enable pedantic compiler warnings, will not generate a working executable (debugging option)], - [PEDANTIC="$enableval"], - [PEDANTIC="no"] +AC_ARG_ENABLE( + [pf], + [AS_HELP_STRING([--disable-pf], [disable internal packet filter @<:@default=yes@:>@])], + , + [enable_pf="yes"] ) -AC_ARG_ENABLE(profiling, - [ --enable-profiling Enable profiling (debugging option)], - [PROFILE="$enableval"], - [PROFILE="no"] +AC_ARG_ENABLE( + [plugin-auth-pam], + [AS_HELP_STRING([--disable-plugin-auth-pam], [disable auth-pam plugin @<:@default=platform specific@:>@])], + , + [ + case "$host" in + *-*-openbsd*) enable_plugin_auth_pam="no";; + *-mingw*) enable_plugin_auth_pam="no";; + *) enable_plugin_auth_pam="yes";; + esac + ] ) -AC_ARG_ENABLE(strict-options, - [ --enable-strict-options Enable strict options check between peers (debugging option)], - [STRICT_OPTIONS="$enableval"], - [STRICT_OPTIONS="no"] +AC_ARG_ENABLE( + [plugin-down-root], + [AS_HELP_STRING([--disable-plugin-down-root], [disable down-root plugin @<:@default=platform specific@:>@])], + , + [ + case "$host" in + *-mingw*) enable_plugin_down_root="no";; + *) enable_plugin_down_root="yes";; + esac + ] ) -AC_ARG_ENABLE(selinux, - [ --disable-selinux Disable SELinux support], - [SELINUX="$enableval"], - [SELINUX="yes"] +AC_ARG_ENABLE( + [pam-dlopen], + [AS_HELP_STRING([--enable-pam-dlopen], [dlopen libpam @<:@default=no@:>@])], + , + [enable_pam_dlopen="no"] ) -AC_ARG_WITH(ssl-headers, - [ --with-ssl-headers=DIR Crypto/SSL Include files location], - [CS_HDR_DIR="$withval"] - [CPPFLAGS="$CPPFLAGS -I$withval"] +AC_ARG_ENABLE( + [strict], + [AS_HELP_STRING([--enable-strict], [enable strict compiler warnings (debugging option) @<:@default=no@:>@])], + , + [enable_strict="no"] ) -AC_ARG_WITH(ssl-lib, - [ --with-ssl-lib=DIR Crypto/SSL Library location], - [LDFLAGS="$LDFLAGS -L$withval"] +AC_ARG_ENABLE( + [pedantic], + [AS_HELP_STRING([--enable-pedantic], [enable pedantic compiler warnings, will not generate a working executable (debugging option) @<:@default=no@:>@])], + , + [enable_pedantic="no"] ) -AC_ARG_WITH(lzo-headers, - [ --with-lzo-headers=DIR LZO Include files location], - [LZO_HDR_DIR="$withval"] - [CPPFLAGS="$CPPFLAGS -I$withval"] +AC_ARG_ENABLE( + [strict-options], + [AS_HELP_STRING([--enable-strict-options], [enable strict options check between peers (debugging option) @<:@default=no@:>@])], + , + [enable_strict_options="no"] ) -AC_ARG_WITH(lzo-lib, - [ --with-lzo-lib=DIR LZO Library location], - [LDFLAGS="$LDFLAGS -L$withval"] +AC_ARG_ENABLE( + [selinux], + [AS_HELP_STRING([--enable-selinux], [enable SELinux support @<:@default=no@:>@])], + , + [enable_selinux="no"] ) -AC_ARG_WITH(pkcs11-helper-headers, - [ --with-pkcs11-helper-headers=DIR pkcs11-helper Include files location], - [PKCS11_HELPER_HDR_DIR="$withval"] - [CPPFLAGS="$CPPFLAGS -I$withval"] +AC_ARG_ENABLE( + [systemd], + [AS_HELP_STRING([--enable-systemd], [enable systemd suppport @<:@default=no@:>@])], + , + [enable_systemd="no"] ) -AC_ARG_WITH(pkcs11-helper-lib, - [ --with-pkcs11-helper-lib=DIR pkcs11-helper Library location], - [LDFLAGS="$LDFLAGS -L$withval"] +AC_ARG_WITH( + [special-build], + [AS_HELP_STRING([--with-special-build=STRING], [specify special build string])], + [test -n "${withval}" && AC_DEFINE_UNQUOTED([CONFIGURE_SPECIAL_BUILD], ["${withval}"], [special build string])] ) -AC_ARG_WITH(ifconfig-path, - [ --with-ifconfig-path=PATH Path to ifconfig tool], - [IFCONFIG="$withval"], - [AC_PATH_PROG([IFCONFIG], [ifconfig], [ifconfig], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])] -) -AC_DEFINE_UNQUOTED(IFCONFIG_PATH, "$IFCONFIG", [Path to ifconfig tool]) - -AC_ARG_WITH(iproute-path, - [ --with-iproute-path=PATH Path to iproute tool], - [IPROUTE="$withval"], - [AC_PATH_PROG([IPROUTE], [ip], [ip], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])] -) -AC_DEFINE_UNQUOTED(IPROUTE_PATH, "$IPROUTE", [Path to iproute tool]) - - -AC_ARG_WITH(route-path, - [ --with-route-path=PATH Path to route tool], - [ROUTE="$withval"], - [AC_PATH_PROG([ROUTE], [route], [route], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])] +AC_ARG_WITH( + [mem-check], + [AS_HELP_STRING([--with-mem-check=TYPE], [build with debug memory checking, TYPE=no|dmalloc|valgrind|ssl @<:@default=no@:>@])], + [ + case "${withval}" in + dmalloc|valgrind|ssl|no) ;; + *) AC_MSG_ERROR([bad value ${withval} for --mem-check]) ;; + esac + ], + [with_mem_check="no"] ) -AC_DEFINE_UNQUOTED(ROUTE_PATH, "$ROUTE", [Path to route tool]) -AC_ARG_WITH(netstat-path, - [ --with-netstat-path=PATH Path to netstat tool], - [NETSTAT="$withval"], - [AC_PATH_PROG([NETSTAT], [netstat], [netstat], [$PATH:/usr/local/sbin:/usr/sbin:/sbin:/etc])] +AC_ARG_WITH( + [crypto-library], + [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|polarssl @<:@default=openssl@:>@])], + [ + case "${withval}" in + openssl|polarssl) ;; + *) AC_MSG_ERROR([bad value ${withval} for --with-crypto-library]) ;; + esac + ], + [with_crypto_library="openssl"] ) -AC_DEFINE_UNQUOTED(NETSTAT_PATH, "$NETSTAT", [Path to netstat tool]) -AC_ARG_WITH(mem-check, - [ --with-mem-check=TYPE Build with debug memory checking, TYPE = dmalloc or valgrind], - [MEMCHECK="$withval"] +AC_ARG_WITH( + [plugindir], + [AS_HELP_STRING([--with-plugindir], [plugin directory @<:@default=LIBDIR/openvpn@:>@])], + , + [with_plugindir="\$(libdir)/openvpn/plugins"] ) -dnl fix search path, to allow compilers to find syshead.h -CPPFLAGS="$CPPFLAGS -I${srcdir}" -dnl check host OS -openvpn_host=$host -if test $host_alias; then - openvpn_host=$host_alias -fi -AC_DEFINE_UNQUOTED(TARGET_ALIAS, "$openvpn_host", [A string representing our host]) +AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host]) case "$host" in -*-*-linux*) - AC_DEFINE(TARGET_LINUX, 1, [Are we running on Linux?]) - dnl RH9 SSL headers workaround - if test -z $CS_HDR_DIR && test "$CRYPTO" = "yes"; then - CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl 2>/dev/null)" - fi - ;; -*-*-solaris*) - AC_DEFINE(TARGET_SOLARIS, 1, [Are we running on Solaris?]) - ;; -*-*-openbsd*) - AC_DEFINE(TARGET_OPENBSD, 1, [Are we running on OpenBSD?]) - ;; -*-*-freebsd*) - AC_DEFINE(TARGET_FREEBSD, 1, [Are we running on FreeBSD?]) - ;; -*-*-netbsd*) - AC_DEFINE(TARGET_NETBSD, 1, [Are we running NetBSD?]) - ;; -*-*-darwin*) - dnl some Mac OS X tendering (we use vararg macros...) - AC_DEFINE(TARGET_DARWIN, 1, [Are we running on Mac OS X?]) - CPPFLAGS="$CPPFLAGS -no-cpp-precomp" - ;; -*-mingw*) - AC_DEFINE(TARGET_WIN32, 1, [Are we running WIN32?]) - CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" - OPENVPN_ADD_LIBS(-lgdi32) - OPENVPN_ADD_LIBS(-lws2_32) - OPENVPN_ADD_LIBS(-lwininet) - OPENVPN_ADD_LIBS(-lcrypt32) - OPENVPN_ADD_LIBS(-liphlpapi) - OPENVPN_ADD_LIBS(-lwinmm) - ;; -*-*-dragonfly*) - AC_DEFINE(TARGET_DRAGONFLY, 1, [Are we running on DragonFlyBSD?]) - ;; - + *-*-linux*) + AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["L"], [Target prefix]) + ;; + *-*-solaris*) + AC_DEFINE([TARGET_SOLARIS], [1], [Are we running on Solaris?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["S"], [Target prefix]) + ;; + *-*-openbsd*) + AC_DEFINE([TARGET_OPENBSD], [1], [Are we running on OpenBSD?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["O"], [Target prefix]) + ;; + *-*-freebsd*) + AC_DEFINE([TARGET_FREEBSD], [1], [Are we running on FreeBSD?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["F"], [Target prefix]) + ;; + *-*-netbsd*) + AC_DEFINE([TARGET_NETBSD], [1], [Are we running NetBSD?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["N"], [Target prefix]) + ;; + *-*-darwin*) + AC_DEFINE([TARGET_DARWIN], [1], [Are we running on Mac OS X?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["M"], [Target prefix]) + have_tap_header="yes" + dnl some Mac OS X tendering (we use vararg macros...) + CPPFLAGS="$CPPFLAGS -no-cpp-precomp" + ;; + *-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" + WIN32=yes + ;; + *-*-dragonfly*) + AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix]) + ;; + *) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix]) + have_tap_header="yes" + ;; esac -dnl Checks for programs. -AC_PROG_CC +PKG_PROG_PKG_CONFIG +AC_PROG_CPP AC_PROG_INSTALL -AC_PROG_GCC_TRADITIONAL -AC_GNU_SOURCE - -if test "${WIN32}" = "yes"; then - AC_ARG_VAR([MAN2HTML], [man2html utility]) - AC_CHECK_PROGS([MAN2HTML], [man2html]) - test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32]) -fi - -dnl Checks for header files. -AC_HEADER_STDC +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_MAKE_SET + +AC_ARG_VAR([IFCONFIG], [full path to ipconfig utility]) +AC_ARG_VAR([ROUTE], [full path to route utility]) +AC_ARG_VAR([IPROUTE], [full path to ip utility]) +AC_ARG_VAR([NETSTAT], [path to netstat utility]) # tests +AC_ARG_VAR([MAN2HTML], [path to man2html utility]) +AC_ARG_VAR([GIT], [path to git utility]) +AC_PATH_PROGS([IFCONFIG], [ifconfig],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) +AC_PATH_PROGS([ROUTE], [route],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) +AC_PATH_PROGS([IPROUTE], [ip],, [$PATH:/usr/local/sbin:/usr/sbin:/sbin]) +AC_CHECK_PROGS([NETSTAT], [netstat], [netstat], [$PATH:/usr/local/sbin:/usr/sbin:/sbin:/etc]) # tests +AC_CHECK_PROGS([MAN2HTML], [man2html]) +AC_CHECK_PROGS([GIT], [git]) # optional +AC_DEFINE_UNQUOTED([IFCONFIG_PATH], ["$IFCONFIG"], [Path to ifconfig tool]) +AC_DEFINE_UNQUOTED([IPROUTE_PATH], ["$IPROUTE"], [Path to iproute tool]) +AC_DEFINE_UNQUOTED([ROUTE_PATH], ["$ROUTE"], [Path to route tool]) + +# +# Libtool +# +ifdef( + [LT_INIT], + [ + LT_INIT([win32-dll]) + LT_LANG([Windows Resource]) + ], + [ + AC_LIBTOOL_WIN32_DLL + AC_LIBTOOL_RC + AC_PROG_LIBTOOL + ] +) -dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_C_VOLATILE @@ -357,560 +390,680 @@ AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_UID_T -TYPE_SOCKLEN_T -AC_HEADER_TIME +AC_TYPE_INT8_T +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_UINT8_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_SIGNAL AX_CPP_VARARG_MACRO_ISO AX_CPP_VARARG_MACRO_GCC +AX_TYPE_SOCKLEN_T AX_EMPTY_ARRAY +AC_CHECK_SIZEOF([unsigned int]) +AC_CHECK_SIZEOF([unsigned long]) +AC_CHECK_HEADERS([ \ + stdio.h stdarg.h stdbool.h limits.h \ + time.h errno.h fcntl.h io.h direct.h \ + ctype.h sys/types.h sys/socket.h \ + signal.h unistd.h dlfcn.h \ + netinet/in.h netinet/in_systm.h \ + netinet/tcp.h arpa/inet.h netdb.h \ + windows.h winsock2.h ws2tcpip.h \ +]) +AC_CHECK_HEADERS([ \ + sys/time.h sys/ioctl.h sys/stat.h \ + sys/mman.h sys/file.h sys/wait.h \ + unistd.h signal.h libgen.h stropts.h \ + syslog.h pwd.h grp.h \ + sys/sockio.h sys/uio.h linux/sockios.h \ + linux/types.h sys/poll.h sys/epoll.h err.h \ +]) -dnl Check for more header files. -AC_CHECK_HEADERS(fcntl.h stdlib.h dnl - stdarg.h stdio.h string.h dnl - strings.h ctype.h errno.h dnl -) - -if test "${WIN32}" != "yes"; then - AC_HEADER_SYS_WAIT - AC_CHECK_HEADERS(sys/time.h sys/socket.h sys/un.h sys/ioctl.h sys/stat.h dnl - sys/mman.h fcntl.h sys/file.h stdlib.h stdint.h dnl - stdarg.h unistd.h signal.h stdio.h string.h dnl - strings.h ctype.h errno.h syslog.h pwd.h grp.h dnl - net/if_tun.h net/tun/if_tun.h stropts.h sys/sockio.h dnl - netinet/in.h netinet/in_systm.h dnl - netinet/tcp.h arpa/inet.h dnl - netdb.h sys/uio.h linux/if_tun.h linux/sockios.h dnl - linux/types.h sys/poll.h sys/epoll.h err.h dnl - ) - AC_CHECK_HEADERS(net/if.h,,, - [#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_SYS_SOCKET_H - # include <sys/socket.h> - #endif - ]) - AC_CHECK_HEADERS(netinet/ip.h,,, - [#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - #ifdef HAVE_NETINET_IN_SYSTM_H - # include <netinet/in_systm.h> - #endif - ]) - AC_CHECK_HEADERS(netinet/if_ether.h,,, - [#ifdef HAVE_SYS_TYPES_H - # include <sys/types.h> - #endif - #ifdef HAVE_SYS_SOCKET_H - # include <sys/socket.h> - #endif - #ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - ]) - AC_CHECK_HEADERS(resolv.h,,, - [#ifdef HAVE_NETINET_IN_H - # include <netinet/in.h> - #endif - ]) - AC_CHECK_HEADERS(linux/errqueue.h,,, - [#ifdef HAVE_LINUX_TYPES_H - # include <linux/types.h> - #endif - ]) -fi - -AC_CACHE_SAVE +SOCKET_INCLUDES=" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif +#ifdef HAVE_NETINET_IP_H +#include <netinet/ip.h> +#endif +" + +AC_CHECK_HEADERS( + [net/if.h netinet/ip.h netinet/if_ether.h resolv.h sys/un.h], + , + , + [[${SOCKET_INCLUDES}]] +) -dnl check that in_addr_t is defined -AC_CHECK_TYPE( +AC_CHECK_TYPES( [in_addr_t], - [], - [AC_DEFINE(in_addr_t, uint32_t, [Some systems don't define in_addr_t])], - [#include "syshead.h"]) - -dnl check for basic types -AC_CHECK_TYPE( - [uint8_t], - [], - [AC_DEFINE(uint8_t, unsigned char, [8-bit unsigned type])], - [#include "syshead.h"]) -AC_CHECK_TYPE( - [uint16_t], - [], - [AC_DEFINE(uint16_t, unsigned char, [16-bit unsigned type])], - [#include "syshead.h"]) -AC_CHECK_TYPE( - [uint32_t], - [], - [AC_DEFINE(uint32_t, unsigned long, [32-bit unsigned type])], - [#include "syshead.h"]) - -dnl check for IPv6 types -AC_CHECK_TYPE( - [struct tun_pi], - [AC_DEFINE(HAVE_TUN_PI, 1, [struct tun_pi needed for IPv6 support])], - [], - [#include "syshead.h"]) + , + [AC_DEFINE([in_addr_t], [uint32_t], [Workaround missing in_addr_t])], + [[${SOCKET_INCLUDES}]] +) AC_CHECK_TYPE( [struct iphdr], - [AC_DEFINE(HAVE_IPHDR, 1, [struct iphdr needed for IPv6 support])], - [], - [#include "syshead.h"]) -AC_CHECK_TYPE( - [struct iovec], - [AC_DEFINE(HAVE_IOVEC, 1, [struct iovec needed for IPv6 support])], - [], - [#include "syshead.h"]) - -dnl check for extended socket error types + [AC_DEFINE([HAVE_IPHDR], [1], [struct iphdr needed for IPv6 support])], + , + [[${SOCKET_INCLUDES}]] +) AC_CHECK_TYPE( [struct sock_extended_err], - [AC_DEFINE(HAVE_SOCK_EXTENDED_ERR, 1, [struct sock_extended_err needed for extended socket error support])], - [], - [#include "syshead.h"]) + [AC_DEFINE([HAVE_SOCK_EXTENDED_ERR], [1], [struct sock_extended_err needed for extended socket error support])], + , + [[${SOCKET_INCLUDES}]] +) AC_CHECK_TYPE( [struct msghdr], - [AC_DEFINE(HAVE_MSGHDR, 1, [struct msghdr needed for extended socket error support])], - [], - [#include "syshead.h"]) + [AC_DEFINE([HAVE_MSGHDR], [1], [struct msghdr needed for extended socket error support])], + , + [[${SOCKET_INCLUDES}]] +) AC_CHECK_TYPE( [struct cmsghdr], - [AC_DEFINE(HAVE_CMSGHDR, 1, [struct cmsghdr needed for extended socket error support])], - [], - [#include "syshead.h"]) + [AC_DEFINE([HAVE_CMSGHDR], [1], [struct cmsghdr needed for extended socket error support])], + , + [[${SOCKET_INCLUDES}]] +) AC_CHECK_TYPE( [struct in_pktinfo], - [AC_DEFINE(HAVE_IN_PKTINFO, 1, [struct in_pktinfo needed for IP_PKTINFO support])], - [], - [#include "syshead.h"]) + [AC_DEFINE([HAVE_IN_PKTINFO], [1], [struct in_pktinfo 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.])], + [[${SOCKET_INCLUDES}]] +) +AC_CHECK_DECLS( + [SO_MARK], + , + , + [[${SOCKET_INCLUDES}]] +) + +dnl We emulate signals in Windows +AC_CHECK_DECLS( + [SIGHUP], + , + [AC_DEFINE([SIGHUP], [1], [SIGHUP replacement])], + [[ + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif + ]] +) +AC_CHECK_DECLS( + [SIGINT], + , + [AC_DEFINE([SIGINT], [2], [SIGINT replacement])], + [[ + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif + ]] +) +AC_CHECK_DECLS( + [SIGUSR1], + , + [AC_DEFINE([SIGUSR1], [10], [SIGUSR1 replacement])], + [[ + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif + ]] +) +AC_CHECK_DECLS( + [SIGUSR2], + , + [AC_DEFINE([SIGUSR2], [12], [SIGUSR2 replacement])], + [[ + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif + ]] +) +AC_CHECK_DECLS( + [SIGTERM], + , + [AC_DEFINE([SIGTERM], [15], [SIGTERM replacement])], + [[ + #ifdef HAVE_SIGNAL_H + #include <signal.h> + #endif + ]] +) -AC_CHECK_SIZEOF(unsigned int) -AC_CHECK_SIZEOF(unsigned long) +AC_FUNC_FORK -AC_CACHE_SAVE +AC_CHECK_FUNCS([ \ + daemon chroot getpwnam setuid nice system getpid dup dup2 \ + getpass strerror syslog openlog mlockall getgrnam setgid \ + setgroups stat flock readv writev time gettimeofday \ + ctime memset vsnprintf strdup \ + setsid chdir putenv getpeername unlink \ + chsize ftruncate execve getpeereid umask basename dirname access \ + epoll_create \ +]) -AC_CHECK_FUNCS([ctime memset vsnprintf strdup], , - [AC_MSG_ERROR([Required library function not found])]) -AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl - getpass strerror syslog openlog mlockall getgrnam setgid dnl - setgroups stat flock readv writev time dnl - setsid chdir putenv getpeername unlink dnl - chsize ftruncate execve getpeereid umask) +AC_CHECK_LIB( + [dl], + [dlopen], + [DL_LIBS="-ldl"] +) +AC_SUBST([DL_LIBS]) +AC_CHECK_LIB( + [nsl], + [inet_ntoa], + [SOCKETS_LIBS="${SOCKETS_LIBS} -lnsl"] +) +AC_CHECK_LIB( + [socket], + [socket], + [SOCKETS_LIBS="${SOCKETS_LIBS} -lsocket"] +) +AC_CHECK_LIB( + [resolv], + [gethostbyname], + [SOCKETS_LIBS="${SOCKETS_LIBS} -lresolv"] +) +AC_SUBST([SOCKETS_LIBS]) + +old_LIBS="${LIBS}" +LIBS="${LIBS} ${SOCKETS_LIBS}" +AC_CHECK_FUNCS([sendmsg recvmsg inet_ntop inet_pton]) +AC_CHECK_FUNCS( + [res_init], + , + , + [[#include <resolv.h>]] +) # Windows use stdcall for winsock so we cannot auto detect these -m4_define([SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl - accept connect bind select gethostbyname inet_ntoa]) -m4_define([SOCKET_OPT_FUNCS], [setsockopt getsockopt getsockname poll]) - +m4_define( + [SOCKET_FUNCS], +[socket recv recvfrom send sendto listen dnl +accept connect bind select gethostbyname inet_ntoa]dnl +) +m4_define( + [SOCKET_OPT_FUNCS], + [setsockopt getsockopt getsockname poll]dnl +) if test "${WIN32}" = "yes"; then - - AC_DEFINE([HAVE_GETTIMEOFDAY], [1], [We fake gettimeofday for win32 at otime.c]) - m4_foreach([F], m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS), - m4_define(UF, [[m4_join([_], [HAVE], m4_toupper(F))]]) - AC_DEFINE([UF], [1], [Win32 builtin])) - + m4_foreach( + [F], + m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS), + m4_define([UF], [[m4_join([_], [HAVE], m4_toupper(F))]]) + AC_DEFINE([UF], [1], [Win32 builtin]) + ) else - - dnl check for other types - AC_TYPE_SIGNAL - - dnl Check for libsocket - AC_SEARCH_LIBS(socket, socket) - - dnl Check for libnsl - AC_SEARCH_LIBS(inet_ntoa, nsl) - - dnl Check for libresolv - AC_SEARCH_LIBS(gethostbyname, resolv nsl) - - dnl optional library functions - AC_FUNC_FORK - - AC_CHECK_FUNCS(gettimeofday) - - AC_CHECK_FUNCS(SOCKET_FUNCS, , - [AC_MSG_ERROR([Required library function not found])]) - AC_CHECK_FUNCS(SOCKET_OPT_FUNCS sendmsg recvmsg) - + AC_CHECK_FUNCS( + SOCKET_FUNCS, + , + [AC_MSG_ERROR([Required library function not found])] + ) + AC_CHECK_FUNCS(SOCKET_OPT_FUNCS) fi - -dnl Required library functions -AC_FUNC_MEMCMP - -dnl -dnl Check for res_init -dnl -AC_TRY_LINK([ - #include <resolv.h> - ], [ - res_init (); - ], [ - AC_MSG_RESULT([res_init DEFINED]) - AC_DEFINE([HAVE_RES_INIT], 1, [Indicates if res_init is available]) - ], [ - AC_MSG_RESULT([res_init UNDEFINED]) - ]) - -dnl -dnl check libraries -dnl - -dnl Checking for a working epoll -AC_CHECKING([for working epoll implementation]) -OLDLDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -Wl,--fatal-warnings" -AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL_CREATE, 1, [epoll_create function is defined])) -LDFLAGS="$OLDLDFLAGS" - -dnl -dnl check for valgrind tool -dnl - -if test "$MEMCHECK" = "valgrind"; then - AC_CHECKING([for valgrind tool and Header files]) - AC_CHECK_HEADER(valgrind/memcheck.h, - [ - AC_DEFINE(USE_VALGRIND, 1, [Use valgrind memory debugging library]) - CFLAGS="-g -fno-inline" +LIBS="${old_LIBS}" + +AC_ARG_VAR([TAP_CFLAGS], [C compiler flags for tap]) +old_CFLAGS="${CFLAGS}" +CFLAGS="${CFLAGS} ${TAP_CFLAGS}" +AC_CHECK_HEADERS( + [ \ + net/if_tun.h net/tun/if_tun.h \ + linux/if_tun.h \ + tap-windows.h \ ], - [AC_MSG_ERROR([valgrind headers not found.])] - ) -fi - -dnl -dnl check for dmalloc library -dnl + [have_tap_header="yes"] +) +AC_CHECK_DECLS( + [TUNSETPERSIST], + [AC_DEFINE([ENABLE_FEATURE_TUN_PERSIST], [1], [We have persist tun capability])], + , + [[ + #ifdef HAVE_LINUX_IF_TUN_H + #include <linux/if_tun.h> + #endif + ]] +) +CFLAGS="${old_CFLAGS}" +test "${have_tap_header}" = "yes" || AC_MSG_ERROR([no tap header could be found]) -if test "$MEMCHECK" = "dmalloc"; then - AC_CHECKING([for dmalloc Library and Header files]) - AC_CHECK_HEADER(dmalloc.h, - [AC_CHECK_LIB(dmalloc, malloc, - [ - OPENVPN_ADD_LIBS(-ldmalloc) - AC_DEFINE(DMALLOC, 1, [Use dmalloc memory debugging library]) - ], - [AC_MSG_ERROR([dmalloc library not found.])] - )], - [AC_MSG_ERROR([dmalloc headers not found.])] - ) +AC_CHECK_LIB( + [selinux], + [setcon], + [SELINUX_LIBS="-lselinux"] +) +AC_SUBST([SELINUX_LIBS]) + +AC_ARG_VAR([LIBPAM_CFLAGS], [C compiler flags for libpam]) +AC_ARG_VAR([LIBPAM_LIBS], [linker flags for libpam]) +if test -z "${LIBPAM_LIBS}"; then + AC_CHECK_LIB( + [pam], + [pam_start], + [LIBPAM_LIBS="-lpam"] + ) fi -dnl -dnl Check for dlopen -- first try libc then libdl. -dnl -if test "${WIN32}" != "yes"; then - if test "$PLUGINS" = "yes"; then - AC_CHECKING([for libdl Library and Header files]) - AC_CHECK_HEADER(dlfcn.h, - [AC_CHECK_FUNC(dlopen, - [AC_DEFINE(USE_LIBDL, 1, [Use libdl for dynamic library loading])], - [AC_CHECK_LIB(dl, dlopen, - [ - OPENVPN_ADD_LIBS(-ldl) - AC_DEFINE(USE_LIBDL, 1, [Use libdl for dynamic library loading]) - ], - [AC_MSG_RESULT([libdl library not found.])] - )], - )], - [AC_MSG_RESULT([libdl headers not found.])] - ) - if test "$EUREPHIA" = "yes"; then - AC_DEFINE(ENABLE_EUREPHIA, 1, [Enable support for the eurephia plug-in]) - fi - fi -fi +case "${with_mem_check}" in + valgrind) + AC_CHECK_HEADER( + [valgrind/memcheck.h], + [ + CFLAGS="${CFLAGS} -g -fno-inline" + AC_DEFINE( + [USE_VALGRIND], + [1], + [Use valgrind memory debugging library] + ) + ], + [AC_MSG_ERROR([valgrind headers not found.])] + ) + ;; + dmalloc) + AC_CHECK_HEADER( + [dmalloc.h], + [AC_CHECK_LIB( + [dmalloc], + [malloc], + [ + LIBS="${LIBS} -ldmalloc" + AC_DEFINE( + [DMALLOC], + [1], + [Use dmalloc memory debugging library] + ) + ], + [AC_MSG_ERROR([dmalloc library not found.])] + )], + [AC_MSG_ERROR([dmalloc headers not found.])] + ) + ;; + ssl) + AC_CHECK_LIB( + [ssl], + [CRYPTO_mem_ctrl], + [ + AC_DEFINE( + [CRYPTO_MDEBUG], + [1], + [Use memory debugging function in OpenSSL] + ) + AC_MSG_NOTICE([NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG]) + ], + [AC_MSG_ERROR([Memory Debugging function in OpenSSL library not found.])] + ) + ;; +esac -dnl -dnl Check if LoadLibrary exists on Windows -dnl -if test "${WIN32}" = "yes"; then - if test "$PLUGINS" = "yes"; then - AC_TRY_LINK([ - #include <windows.h> - ], [ - LoadLibrary (NULL); - ], [ - AC_MSG_RESULT([LoadLibrary DEFINED]) - AC_DEFINE(USE_LOAD_LIBRARY, 1, [Use LoadLibrary to load DLLs on Windows]) - ], [ - AC_MSG_RESULT([LoadLibrary UNDEFINED]) - ]) - fi -fi +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" + ] + )] +) -dnl -dnl check for LZO library -dnl +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" + ] + )] +) -if test "$LZO" = "yes"; then - LZO_H="" - AC_CHECKING([for LZO Library and Header files]) - AC_CHECK_HEADER(lzo/lzo1x.h, - [ LZO_H="2" - lzolibs="lzo2 lzo" - AC_DEFINE(LZO_HEADER_DIR, 1, [Use lzo/ directory prefix for LZO header files (for LZO 2.0)]) - ], - [ AC_CHECK_HEADER(lzo1x.h, [ LZO_H="1" ; lzolibs=lzo ]) ] - ) - - if test -n "$LZO_H"; then - havelzolib=0 - for i in $lzolibs ; do - if test $havelzolib = 1 ; then break ; fi - AC_CHECK_LIB($i, lzo1x_1_15_compress, - [ - OPENVPN_ADD_LIBS(-l$i) - AC_DEFINE(USE_LZO, 1, [Use LZO compression library]) - AC_DEFINE_UNQUOTED(LZO_VERSION_NUM, "$LZO_H", [LZO version number]) - havelzolib=1 - ] - ) - done - if test $havelzolib = 0 ; then - AC_MSG_ERROR([LZO headers were found but LZO library was not found]) - fi - else - AC_MSG_RESULT([LZO headers were not found]) - AC_MSG_RESULT([LZO library available from http://www.oberhumer.com/opensource/lzo/]) - AC_MSG_ERROR([Or try ./configure --disable-lzo]) - 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]) + have_openssl_engine="yes" + AC_CHECK_FUNCS( + [ \ + ENGINE_load_builtin_engines \ + ENGINE_register_all_complete \ + ENGINE_cleanup \ + ], + , + [have_openssl_engine="no"; break] + ) + + CFLAGS="${saved_CFLAGS}" + LIBS="${saved_LIBS}" fi -dnl -dnl check for OpenSSL-crypto library -dnl - -if test "$CRYPTO" = "yes"; then - AC_CHECKING([for OpenSSL Crypto Library and Header files]) - AC_CHECK_HEADER(openssl/evp.h,, - [AC_MSG_ERROR([OpenSSL Crypto headers not found.])]) - - for lib in crypto eay32; do - AC_CHECK_LIB($lib, EVP_CIPHER_CTX_init, - [ - cryptofound=1 - OPENVPN_ADD_LIBS(-l$lib) - ] - ) - done - - test -n "$cryptofound" || AC_MSG_ERROR([OpenSSL Crypto library not found.]) - - AC_MSG_CHECKING([that OpenSSL Library is at least version 0.9.6]) - AC_EGREP_CPP(yes, - [ - #include <openssl/evp.h> - #if SSLEAY_VERSION_NUMBER >= 0x00906000L - yes - #endif - ], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE(USE_CRYPTO, 1, [Use OpenSSL crypto library]) - AC_CHECK_FUNCS(EVP_CIPHER_CTX_set_key_length) - - dnl check for OpenSSL crypto acceleration capability - AC_CHECK_HEADERS(openssl/engine.h) - AC_CHECK_FUNCS(ENGINE_load_builtin_engines) - AC_CHECK_FUNCS(ENGINE_register_all_complete) - AC_CHECK_FUNCS(ENGINE_cleanup) - ], - [AC_MSG_ERROR([OpenSSL crypto Library is too old.])] - ) - -dnl -dnl check for OpenSSL-SSL library -dnl - - if test "$SSL" = "yes"; then - AC_CHECKING([for OpenSSL SSL Library and Header files]) - AC_CHECK_HEADER(openssl/ssl.h,, - [AC_MSG_ERROR([OpenSSL SSL headers not found.])] - ) - - for lib in ssl ssl32; do - AC_CHECK_LIB($lib, SSL_CTX_new, +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"], [ - sslfound=1 - OPENVPN_ADD_LIBS(-l$lib) + have_polarssl_ssl="no" + AC_CHECK_LIB( + [polarssl], + [aes_crypt_cbc], + , + [have_polarssl_crypto="no"] + ) ] - ) - done - - test -n "${sslfound}" || AC_MSG_ERROR([OpenSSL SSL library not found.]) - - if test "$MEMCHECK" = "ssl"; then - AC_CHECKING([for Memory Debugging Capabilities in OpenSSL Library]) - AC_CHECK_LIB(ssl, CRYPTO_mem_ctrl, - [ - AC_DEFINE(CRYPTO_MDEBUG, 1, [Use memory debugging function in OpenSSL]) - AC_MSG_RESULT([NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG]) - ], - [AC_MSG_ERROR([Memory Debugging function in OpenSSL library not found.])] - ) - fi - - AC_DEFINE(USE_SSL, 1, [Use OpenSSL SSL library]) - fi + ) fi -dnl enable --x509-username-field feature if requested -if test "$X509ALTUSERNAME" = "yes"; then - AC_DEFINE(ENABLE_X509ALTUSERNAME, 1, [Enable --x509-username-field feature]) +if test "${with_crypto_library}" = "polarssl" ; then + AC_MSG_CHECKING([polarssl version]) + old_CFLAGS="${CFLAGS}" + CFLAGS="${POLARSSL_CFLAGS} ${CFLAGS}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <polarssl/version.h> + ]], + [[ +#if POLARSSL_VERSION_NUMBER < 0x01010000 +#error invalid version +#endif + ]] + )], + [AC_MSG_RESULT([ok])], + [AC_MSG_ERROR([invalid polarssl version])] + ) + CFLAGS="${old_CFLAGS}" fi -dnl enable pkcs11 capability -if test "$PKCS11" = "yes"; then - AC_CHECKING([for pkcs11-helper Library and Header files]) - AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h, - [AC_CHECK_LIB(pkcs11-helper, pkcs11h_initialize, - [ - AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability]) - OPENVPN_ADD_LIBS(-lpkcs11-helper) - ], - [AC_MSG_RESULT([pkcs11-helper library not found.])] - )], - [AC_MSG_RESULT([pkcs11-helper headers not found.])] - ) +AC_ARG_VAR([LZO_CFLAGS], [C compiler flags for lzo]) +AC_ARG_VAR([LZO_LIBS], [linker flags for lzo]) +have_lzo="yes" +if test -z "${LZO_LIBS}"; then + AC_CHECK_LIB( + [lzo2], + [lzo1x_1_15_compress], + [LZO_LIBS="-llzo2"], + [AC_CHECK_LIB( + [lzo], + [lzo1x_1_15_compress], + [LZO_LIBS="-llzo"], + [have_lzo="no"] + )] + ) fi - -dnl enable multi-client mode -if test "$MULTI" = "yes"; then - AC_DEFINE(ENABLE_CLIENT_SERVER, 1, [Enable client/server capability]) +if test "${have_lzo}" = "yes"; then + saved_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${LZO_CFLAGS}" + AC_CHECK_HEADERS( + [lzo/lzoutil.h], + , + [AC_CHECK_HEADERS( + [lzoutil.h], + , + [AC_MSG_ERROR([lzoutil.h is missing])] + )] + ) + AC_CHECK_HEADERS( + [lzo/lzo1x.h], + , + [AC_CHECK_HEADERS( + [lzo1x.h], + , + [AC_MSG_ERROR([lzo1x.h is missing])] + )] + ) + CFLAGS="${saved_CFLAGS}" fi -dnl enable client mode only, not server -if test "$MULTI_SERVER" = "no"; then - AC_DEFINE(ENABLE_CLIENT_ONLY, 1, [Enable client capability only]) -fi +PKG_CHECK_MODULES( + [PKCS11_HELPER], + [libpkcs11-helper-1 >= 1.02], + [have_pkcs11_helper="yes"], + [] +) -dnl enable management server capability -if test "$MANAGEMENT" = "yes"; then - AC_DEFINE(ENABLE_MANAGEMENT, 1, [Enable management server capability]) +AC_MSG_CHECKING([git checkout]) +GIT_CHECKOUT="no" +if test -n "${GIT}" -a -d "${srcdir}/.git"; then + AC_DEFINE([HAVE_CONFIG_VERSION_H], [1], [extra version available in config-version.h]) + GIT_CHECKOUT="yes" fi +AC_MSG_RESULT([${GIT_CHECKOUT}]) -dnl enable socks -if test "$SOCKS" = "yes"; then - AC_DEFINE(ENABLE_SOCKS, 1, [Enable Socks proxy support]) +if test -n "${SP_PLATFORM_WINDOWS}"; then + AC_DEFINE_UNQUOTED([PATH_SEPARATOR], ['\\\\'], [Path separator]) #" + AC_DEFINE_UNQUOTED([PATH_SEPARATOR_STR], ["\\\\"], [Path separator]) #" +else + AC_DEFINE_UNQUOTED([PATH_SEPARATOR], ['/'], [Path separator]) + AC_DEFINE_UNQUOTED([PATH_SEPARATOR_STR], ["/"], [Path separator]) fi -dnl enable HTTP proxy -if test "$HTTP_PROXY" = "yes"; then - AC_DEFINE(ENABLE_HTTP_PROXY, 1, [Enable HTTP proxy support]) -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]) + fi -dnl compile --multihome option -if test "$MULTIHOME" = "yes"; then - AC_DEFINE(ENABLE_MULTIHOME, 1, [Enable multi-homed UDP server capability]) + AC_DEFINE([ENABLE_X509ALTUSERNAME], [1], [Enable --x509-username-field feature]) fi -dnl enable debugging -if test "$DEBUG" = "yes"; then - AC_DEFINE(ENABLE_DEBUG, 1, [Enable debugging support]) -fi +test "${ac_cv_header_sys_uio_h}" = "yes" && AC_DEFINE([HAVE_IOVEC], [1], [struct iovec needed for IPv6 support]) +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]) +test "${enable_fragment}" = "yes" && AC_DEFINE([ENABLE_FRAGMENT], [1], [Enable internal fragmentation support]) +test "${enable_port_share}" = "yes" && AC_DEFINE([ENABLE_PORT_SHARE], [1], [Enable TCP Server port sharing]) +test "${enable_def_auth}" = "yes" && AC_DEFINE([ENABLE_DEF_AUTH], [1], [Enable deferred authentication]) +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]) +test "${enable_password_save}" = "yes" && AC_DEFINE([ENABLE_PASSWORD_SAVE], [1], [Allow --askpass and --auth-user-pass passwords to be read from a file]) +test "${enable_systemd}" = "yes" && AC_DEFINE([ENABLE_SYSTEMD], [1], [Enable systemd support]) + +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 -dnl enable small size optimizations -if test "$SMALL" = "yes"; then - AC_DEFINE(ENABLE_SMALL, 1, [Enable smaller executable size]) +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 -dnl enable --fragment -if test "$FRAGMENT" = "yes"; then - AC_DEFINE(ENABLE_FRAGMENT, 1, [Enable internal fragmentation support]) +if test "${enable_crypto}" = "yes"; then + test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crytpo is required but missing]) + OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}" + OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}" + AC_DEFINE([ENABLE_CRYPTO], [1], [Enable crypto library]) fi -dnl enable --port-share -if test "$PORT_SHARE" = "yes"; then - AC_DEFINE(ENABLE_PORT_SHARE, 1, [Enable TCP Server port sharing]) +if test "${enable_plugins}" = "yes"; then + OPTIONAL_DL_LIBS="${DL_LIBS}" + AC_DEFINE([ENABLE_PLUGIN], [1], [Enable systemd support]) + test "${enable_eurephia}" = "yes" && AC_DEFINE([ENABLE_EUREPHIA], [1], [Enable support for the eurephia plug-in]) +else + enable_plugin_auth_pam="no" + enable_plugin_down_root="no" fi -dnl enable deferred auth -if test "$DEF_AUTH" = "yes"; then - AC_DEFINE(CONFIGURE_DEF_AUTH, 1, [Enable deferred authentication]) +if test "${enable_iproute2}" = "yes"; then + test -z "${IPROUTE}" && AC_MSG_ERROR([ip utility is required but missing]) + AC_DEFINE([ENABLE_IPROUTE], [1], [enable iproute2 support]) +else + if test "${WIN32}" != "yes"; then + test -z "${ROUTE}" && AC_MSG_ERROR([route utility is required but missing]) + test -z "${IFCONFIG}" && AC_MSG_ERROR([ifconfig utility is required but missing]) + fi fi -dnl enable internal packet filter -if test "$PF" = "yes"; then - AC_DEFINE(CONFIGURE_PF, 1, [Enable internal packet filter]) +if test "${enable_selinux}" = "yes"; then + test -z "${SELINUX_LIBS}" && AC_MSG_ERROR([libselinux required but missing]) + OPTIONAL_SELINUX_LIBS="${SELINUX_LIBS}" + AC_DEFINE([ENABLE_SELINUX], [1], [SELinux support]) fi -dnl enable strict compiler warnings -if test "$STRICT" = "yes"; then - CFLAGS="$CFLAGS -Wall -Wno-unused-parameter -Wno-unused-function" +if test "${enable_lzo}" = "yes"; then + test "${have_lzo}" != "yes" && AC_MSG_ERROR([lzo enabled but missing]) + OPTIONAL_LZO_CFLAGS="${LZO_CFLAGS}" + OPTIONAL_LZO_LIBS="${LZO_LIBS}" + AC_DEFINE([ENABLE_LZO], [1], [Enable LZO compression library]) fi - -dnl enable pedantic compiler warnings -if test "$PEDANTIC" = "yes"; then - CFLAGS="$CFLAGS -ansi -pedantic" +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]) fi -dnl enable profiling -if test "$PROFILE" = "yes"; then - CFLAGS="$CFLAGS -pg -DENABLE_PROFILING" +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]) + OPTIONAL_PKCS11_HELPER_CFLAGS="${PKCS11_HELPER_CFLAGS}" + OPTIONAL_PKCS11_HELPER_LIBS="${PKCS11_HELPER_LIBS}" + AC_DEFINE([ENABLE_PKCS11], [1], [Enable PKCS11]) fi -dnl enable strict options check between peers -if test "$STRICT_OPTIONS" = "yes"; then - AC_DEFINE(STRICT_OPTIONS_CHECK, 1, [Enable strict options check between peers]) +if test "${enable_pedantic}" = "yes"; then + enable_strict="yes" + CFLAGS="${CFLAGS} -pedantic" + test "${WIN32}" != "yes" && CFLAGS="${CFLAGS} -ansi" fi - -dnl enable password save -if test "$PASSWORD_SAVE" = "yes"; then - AC_DEFINE(ENABLE_PASSWORD_SAVE, 1, [Allow --askpass and --auth-user-pass passwords to be read from a file]) +if test "${enable_strict}" = "yes"; then + CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function" fi -dnl -dnl check for SELinux library and headers -dnl -if test "$SELINUX" = "yes"; then - AC_CHECKING([for libselinux Library and Header files]) - AC_CHECK_HEADER(selinux/selinux.h, - [AC_CHECK_LIB(selinux, setcon, - [ - OPENVPN_ADD_LIBS(-lselinux) - AC_DEFINE(HAVE_SETCON, 1, [SELinux support]) - ], - [AC_MSG_RESULT([SELinux library not found.])] - )], - [AC_MSG_RESULT([SELinux headers not found.])] - ) +if test "${WIN32}" = "yes"; then + test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32]) fi -TAP_ID="PRODUCT_TAP_ID" -TAP_WIN32_MIN_MAJOR="PRODUCT_TAP_WIN32_MIN_MAJOR" -TAP_WIN32_MIN_MINOR="PRODUCT_TAP_WIN32_MIN_MINOR" -AC_DEFINE_UNQUOTED(TAP_ID, "${TAP_ID}", [The TAP-Win32 id defined in tap-win32/SOURCES]) -AC_DEFINE_UNQUOTED(TAP_WIN32_MIN_MAJOR, ${TAP_WIN32_MIN_MAJOR}, [The TAP-Win32 version number is defined in tap-win32/SOURCES]) -AC_DEFINE_UNQUOTED(TAP_WIN32_MIN_MINOR, ${TAP_WIN32_MIN_MINOR}, [The TAP-Win32 version number is defined in tap-win32/SOURCES]) -AC_SUBST(TAP_ID) -AC_SUBST(TAP_WIN32_MIN_MAJOR) -AC_SUBST(TAP_WIN32_MIN_MINOR) - -win32datadir="\${datadir}/${PACKAGE}-win32" -AC_SUBST(win32datadir) -AM_CONDITIONAL(WIN32, test "${WIN32}" = "yes") - -# workaround for <autoconf-2.60 -if test -z "${docdir}"; then - docdir="\$(datadir)/doc/\$(PACKAGE_NAME)" - AC_SUBST([docdir]) -fi -if test -z "${htmldir}"; then - htmldir="\$(docdir)" - AC_SUBST([htmldir]) +if test "${enable_plugin_auth_pam}" = "yes"; then + PLUGIN_AUTH_PAM_CFLAGS="${LIBPAM_CFLAGS}" + if test "${enable_pam_dlopen}" = "yes"; then + AC_DEFINE([USE_PAM_DLOPEN], [1], [dlopen libpam]) + PLUGIN_AUTH_PAM_LIBS="${DL_LIBS}" + else + test -z "${LIBPAM_LIBS}" && AC_MSG_ERROR([libpam required but missing]) + PLUGIN_AUTH_PAM_LIBS="${LIBPAM_LIBS}" + fi fi -# end workaround -AC_CONFIG_FILES([t_client.sh], [chmod +x t_client.sh]) -AC_OUTPUT([ +CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`" +AC_DEFINE_UNQUOTED([CONFIGURE_DEFINES], ["`echo ${CONFIGURE_DEFINES}`"], [Configuration settings]) + +TAP_WIN_COMPONENT_ID="PRODUCT_TAP_WIN_COMPONENT_ID" +TAP_WIN_MIN_MAJOR="PRODUCT_TAP_WIN_MIN_MAJOR" +TAP_WIN_MIN_MINOR="PRODUCT_TAP_WIN_MIN_MINOR" +AC_DEFINE_UNQUOTED([TAP_WIN_COMPONENT_ID], ["${TAP_WIN_COMPONENT_ID}"], [The tap-windows id]) +AC_DEFINE_UNQUOTED([TAP_WIN_MIN_MAJOR], [${TAP_WIN_MIN_MAJOR}], [The tap-windows version number is required for OpenVPN]) +AC_DEFINE_UNQUOTED([TAP_WIN_MIN_MINOR], [${TAP_WIN_MIN_MINOR}], [The tap-windows version number is required for OpenVPN]) +AC_SUBST([TAP_WIN_COMPONENT_ID]) +AC_SUBST([TAP_WIN_MIN_MAJOR]) +AC_SUBST([TAP_WIN_MIN_MINOR]) + +AC_SUBST([OPTIONAL_DL_LIBS]) +AC_SUBST([OPTIONAL_SELINUX_LIBS]) +AC_SUBST([OPTIONAL_CRYPTO_CFLAGS]) +AC_SUBST([OPTIONAL_CRYPTO_LIBS]) +AC_SUBST([OPTIONAL_LZO_CFLAGS]) +AC_SUBST([OPTIONAL_LZO_LIBS]) +AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS]) +AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS]) + +AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS]) +AC_SUBST([PLUGIN_AUTH_PAM_LIBS]) + +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"]) + +plugindir="${with_plugindir}" +sampledir="\$(docdir)/sample" +AC_SUBST([plugindir]) +AC_SUBST([sampledir]) + +AC_CONFIG_FILES([ + version.sh Makefile - openvpn.spec - images/Makefile - service-win32/Makefile - install-win32/Makefile - install-win32/settings + 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 ]) +AC_CONFIG_FILES([tests/t_client.sh], [chmod +x tests/t_client.sh]) +AC_OUTPUT diff --git a/configure_h.awk b/configure_h.awk deleted file mode 100644 index 672e745..0000000 --- a/configure_h.awk +++ /dev/null @@ -1,39 +0,0 @@ -# -# 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 David Sommerseth <dazo@users.sourceforge.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 script will build up a line which can be included into a C program. -# The line will contain all interesting #define statements from f.ex. ./config.h -# - -BEGIN { - printf ("#define CONFIGURE_DEFINES \"") -} - -/^#define (ENABLE|DISABLE|DEPRECATED|USE)_/ { - printf (" %s", $2) -} - -END { - printf ("\"\n") -} diff --git a/configure_log.awk b/configure_log.awk deleted file mode 100644 index 099e5c4..0000000 --- a/configure_log.awk +++ /dev/null @@ -1,33 +0,0 @@ -# -# 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 David Sommerseth <dazo@users.sourceforge.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 script will build up a line which can be included into a C program. -# The line will only contain the first entry of the ./configure line from -# ./config.log. -# - -/\$ (.*)\/configure/ { - printf ("#define CONFIGURE_CALL \"%s\"\n", $0) - exit 0 -} diff --git a/crypto.h b/crypto.h deleted file mode 100644 index fcd4661..0000000 --- a/crypto.h +++ /dev/null @@ -1,421 +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 - */ - -#ifndef CRYPTO_H -#define CRYPTO_H -#ifdef USE_CRYPTO - -#define ALLOW_NON_CBC_CIPHERS - -/* - * Does our OpenSSL library support crypto hardware acceleration? - */ -#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES) && defined(HAVE_ENGINE_REGISTER_ALL_COMPLETE) && defined(HAVE_ENGINE_CLEANUP) -#define CRYPTO_ENGINE 1 -#else -#define CRYPTO_ENGINE 0 -#endif - -#include <openssl/objects.h> -#include <openssl/rand.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include <openssl/des.h> -#include <openssl/md5.h> -#if NTLM -#include <openssl/md4.h> -#endif -#include <openssl/sha.h> -#include <openssl/err.h> - -#if CRYPTO_ENGINE -#include <openssl/engine.h> -#endif - -#if SSLEAY_VERSION_NUMBER >= 0x00907000L -#include <openssl/des_old.h> -#endif - -#include "basic.h" -#include "buffer.h" -#include "packet_id.h" -#include "mtu.h" - -/* - * 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 INFO_CALLBACK_SSL_CONST -#define INFO_CALLBACK_SSL_CONST const -#endif - -#if SSLEAY_VERSION_NUMBER < 0x00906000 - -#undef EVP_CIPHER_mode -#define EVP_CIPHER_mode(x) 1 -#define EVP_CIPHER_CTX_mode(x) 1 -#define EVP_CIPHER_flags(x) 0 - -#define EVP_CIPH_CBC_MODE 1 -#define EVP_CIPH_CFB_MODE 0 -#define EVP_CIPH_OFB_MODE 0 -#define EVP_CIPH_VARIABLE_LENGTH 0 - -#define OPENSSL_malloc(x) malloc(x) -#define OPENSSL_free(x) free(x) - -static inline int -EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) -{ - EVP_CipherInit (ctx, type, key, iv, enc); - return 1; -} - -static inline int -EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) -{ - EVP_CipherUpdate (ctx, out, outl, in, inl); - return 1; -} - -static inline bool -cipher_ok (const char* name) -{ - const int i = strlen (name) - 4; - if (i >= 0) - return !strcmp (name + i, "-CBC"); - else - return false; -} - -#else - -static inline int -EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) -{ - return EVP_CipherInit (ctx, type, key, iv, enc); -} - -static inline int -EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) -{ - return EVP_CipherUpdate (ctx, out, outl, in, inl); -} - -static inline bool -cipher_ok (const char* name) -{ - return true; -} - -#endif - -#if SSLEAY_VERSION_NUMBER < 0x0090581f -#undef DES_check_key_parity -#define DES_check_key_parity(x) 1 -#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 - -/* - * Max size in bytes of any cipher key that might conceivably be used. - * - * This value is checked at compile time in crypto.c to make sure - * it is always at least EVP_MAX_KEY_LENGTH. - * - * We define our own value, since this parameter - * is used to control the size of static key files. - * If the OpenSSL library increases EVP_MAX_KEY_LENGTH, - * we don't want our key files to be suddenly rendered - * unusable. - */ -#define MAX_CIPHER_KEY_LENGTH 64 - -/* - * Max size in bytes of any HMAC key that might conceivably be used. - * - * This value is checked at compile time in crypto.c to make sure - * it is always at least EVP_MAX_MD_SIZE. We define our own value - * for the same reason as above. - */ -#define MAX_HMAC_KEY_LENGTH 64 - -/* - * Defines a key type and key length for both cipher and HMAC. - */ -struct key_type -{ - uint8_t cipher_length; - uint8_t hmac_length; - const EVP_CIPHER *cipher; - const EVP_MD *digest; -}; - -/* - * A random key. - */ -struct key -{ - uint8_t cipher[MAX_CIPHER_KEY_LENGTH]; - uint8_t hmac[MAX_HMAC_KEY_LENGTH]; -}; - -#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */ -#define KEY_DIRECTION_NORMAL 1 /* encrypt with keys[0], decrypt with keys[1] */ -#define KEY_DIRECTION_INVERSE 2 /* encrypt with keys[1], decrypt with keys[0] */ - -/* - * Dual random keys (for encrypt/decrypt) - */ -struct key2 -{ - int n; - struct key keys[2]; -}; - -/* - * Used for controlling bidirectional keys - * vs. a separate key for each direction. - */ -struct key_direction_state -{ - int out_key; - int in_key; - int need_keys; -}; - -/* - * A key context for cipher and/or HMAC. - */ -struct key_ctx -{ - EVP_CIPHER_CTX *cipher; - HMAC_CTX *hmac; -}; - -/* - * Cipher/HMAC key context for both sending and receiving - * directions. - */ -struct key_ctx_bi -{ - struct key_ctx encrypt; - struct key_ctx decrypt; -}; - -/* - * Options for encrypt/decrypt. - */ -struct crypto_options -{ - struct key_ctx_bi *key_ctx_bi; - struct packet_id *packet_id; - struct packet_id_persist *pid_persist; - -# define CO_PACKET_ID_LONG_FORM (1<<0) -# define CO_USE_IV (1<<1) -# define CO_IGNORE_PACKET_ID (1<<2) -# define CO_MUTE_REPLAY_WARNINGS (1<<3) - unsigned int flags; -}; - -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); - -#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); - -int write_key_file (const int nkeys, const char *filename); - -int read_passphrase_hash (const char *passphrase_file, - const EVP_MD *digest, - uint8_t *output, - int len); - -void generate_key_random (struct key *key, const struct key_type *kt); - -void check_replay_iv_consistency(const struct key_type *kt, bool packet_id, bool use_iv); - -bool check_key (struct key *key, const struct key_type *kt); - -void fixup_key (struct key *key, const struct key_type *kt); - -bool write_key (const struct key *key, const struct key_type *kt, - struct buffer *buf); - -int read_key (struct key *key, const struct key_type *kt, struct buffer *buf); - -bool cfb_ofb_mode (const struct key_type* kt); - -const char *kt_cipher_name (const struct key_type *kt); -const char *kt_digest_name (const struct key_type *kt); -int kt_key_size (const struct key_type *kt); - -/* enc parameter in init_key_ctx */ -#define DO_ENCRYPT 1 -#define DO_DECRYPT 0 - -void init_key_ctx (struct key_ctx *ctx, struct key *key, - const struct key_type *kt, int enc, - const char *prefix); - -void free_key_ctx (struct key_ctx *ctx); -void free_key_ctx_bi (struct key_ctx_bi *ctx); - -void openvpn_encrypt (struct buffer *buf, struct buffer work, - const struct crypto_options *opt, - const struct frame* frame); - -bool openvpn_decrypt (struct buffer *buf, struct buffer work, - const struct crypto_options *opt, - const struct frame* frame); - - -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); - -#define NONCE_SECRET_LEN_MIN 16 -#define NONCE_SECRET_LEN_MAX 64 -void prng_init (const char *md_name, const int nonce_secret_len_parm); -void prng_bytes (uint8_t *output, int len); -void prng_uninit (); - -void test_crypto (const struct crypto_options *co, struct frame* f); - -const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc); - -void show_available_ciphers (void); - -void show_available_digests (void); - -void show_available_engines (void); - -void init_crypto_lib_engine (const char *engine_name); - -void init_crypto_lib (void); - -void uninit_crypto_lib (void); - -/* key direction functions */ - -void key_direction_state_init (struct key_direction_state *kds, int key_direction); - -void verify_fix_key2 (struct key2 *key2, const struct key_type *kt, const char *shared_secret_file); - -void must_have_n_keys (const char *filename, const char *option, const struct key2 *key2, int n); - -int ascii2keydirection (int msglevel, const char *str); - -const char *keydirection2ascii (int kd, bool remote); - -/* print keys */ -void key2_print (const struct key2* k, - const struct key_type *kt, - const char* prefix0, - const char* prefix1); - -/* memory debugging */ -void openssl_dmalloc_init (void); - -#ifdef USE_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 /* USE_SSL */ - -/* - * Inline functions - */ - -static inline bool -key_ctx_bi_defined(const struct key_ctx_bi* key) -{ - return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac; -} - -/* - * md5 functions - */ - -struct md5_state { - MD5_CTX ctx; -}; - -struct md5_digest { - uint8_t digest [MD5_DIGEST_LENGTH]; -}; - -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); - -#endif /* USE_CRYPTO */ -#endif /* CRYPTO_H */ diff --git a/debug/doval b/debug/doval new file mode 100755 index 0000000..e215510 --- /dev/null +++ b/debug/doval @@ -0,0 +1,4 @@ +#!/bin/bash +PROGDIR=`dirname $0` +unset LD_LIBRARY_PATH +valgrind --tool=memcheck --error-limit=no --suppressions=$PROGDIR/debug/valgrind-suppress --gen-suppressions=all --leak-check=full --show-reachable=yes --num-callers=32 $PROGDIR/openvpn "$@" diff --git a/debug/dovalns b/debug/dovalns new file mode 100755 index 0000000..482ae3f --- /dev/null +++ b/debug/dovalns @@ -0,0 +1,2 @@ +#!/bin/bash +valgrind --tool=memcheck --error-limit=no --gen-suppressions=all --leak-check=full --show-reachable=yes --num-callers=32 $* diff --git a/distro/Makefile.am b/distro/Makefile.am new file mode 100644 index 0000000..2dd6a6e --- /dev/null +++ b/distro/Makefile.am @@ -0,0 +1,15 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = rpm diff --git a/distro/Makefile.in b/distro/Makefile.in new file mode 100644 index 0000000..fb6185a --- /dev/null +++ b/distro/Makefile.in @@ -0,0 +1,613 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +VPATH = @srcdir@ +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 = distro +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +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@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = rpm +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) --gnu distro/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu distro/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. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive 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-recursive \ + 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/distro/rpm/Makefile.am b/distro/rpm/Makefile.am new file mode 100644 index 0000000..536061d --- /dev/null +++ b/distro/rpm/Makefile.am @@ -0,0 +1,18 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + openvpn.spec \ + openvpn.init.d.rhel \ + openvpn.init.d.suse diff --git a/distro/rpm/Makefile.in b/distro/rpm/Makefile.in new file mode 100644 index 0000000..9477fed --- /dev/null +++ b/distro/rpm/Makefile.in @@ -0,0 +1,420 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +VPATH = @srcdir@ +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 = distro/rpm +DIST_COMMON = $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/openvpn.spec.in +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 +CONFIG_CLEAN_FILES = openvpn.spec +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DATA = $(dist_noinst_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + openvpn.spec \ + openvpn.init.d.rhel \ + openvpn.init.d.suse + +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) --gnu distro/rpm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu distro/rpm/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): +openvpn.spec: $(top_builddir)/config.status $(srcdir)/openvpn.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +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 $(DATA) +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +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 \ + 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 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/sample-scripts/openvpn.init b/distro/rpm/openvpn.init.d.rhel index 821abd5..821abd5 100755 --- a/sample-scripts/openvpn.init +++ b/distro/rpm/openvpn.init.d.rhel diff --git a/suse/openvpn.init b/distro/rpm/openvpn.init.d.suse index 8f1060a..2bac7f3 100644 --- a/suse/openvpn.init +++ b/distro/rpm/openvpn.init.d.suse @@ -82,7 +82,7 @@ # # Location of openvpn binary -openvpn="/usr/local/sbin/openvpn" +openvpn="/usr/sbin/openvpn" # Lockfile lock="/var/lock/subsys/openvpn" diff --git a/openvpn.spec.in b/distro/rpm/openvpn.spec index c5178e9..ead0039 100644 --- a/openvpn.spec.in +++ b/distro/rpm/openvpn.spec @@ -10,13 +10,10 @@ # # Allow passwords to be read from files # rpmbuild -tb [openvpn.x.tar.gz] --define 'with_password_save 1' -# -# Use this on RH9 and RHEL3 -# rpmbuild -tb [openvpn.x.tar.gz] --define 'with_kerberos 1' Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan. -Name: @PACKAGE@ -Version: @VERSION@ +Name: openvpn +Version: 2.3_rc1 Release: 1 URL: http://openvpn.net/ Source0: http://prdownloads.sourceforge.net/openvpn/%{name}-%{version}.tar.gz @@ -33,27 +30,27 @@ BuildRoot: %{_tmppath}/%{name}-%(id -un) AutoReq: 0 -BuildRequires: openssl-devel >= 0.9.6 -Requires: openssl >= 0.9.6 +BuildRequires: openssl-devel >= 0.9.7 +Requires: openssl >= 0.9.7 %if "%{_vendor}" == "Mandrakesoft" -%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} -%{!?without_lzo:Requires: liblzo1 >= 1.07} +%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} +%{!?without_lzo:Requires: liblzo1 >= 1.07} %else %if "%{_vendor}" == "MandrakeSoft" -%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} -%{!?without_lzo:Requires: liblzo1 >= 1.07} +%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} +%{!?without_lzo:Requires: liblzo1 >= 1.07} %else -%{!?without_lzo:BuildRequires: lzo-devel >= 1.07} -%{!?without_lzo:Requires: lzo >= 1.07} +%{!?without_lzo:BuildRequires: lzo-devel >= 1.07} +%{!?without_lzo:Requires: lzo >= 1.07} %endif %endif -%{!?without_pam:BuildRequires: pam-devel} -%{!?without_pam:Requires: pam} +%{!?without_pam:BuildRequires: pam-devel} +%{!?without_pam:Requires: pam} -%{!?with_pkcs11:BuildRequires: pkcs11-helper-devel} -%{!?with_pkcs11:Requires: pkcs11-helper} +%{?with_pkcs11:BuildRequires: pkcs11-helper-devel} +%{?with_pkcs11:Requires: pkcs11-helper} # # Description @@ -68,6 +65,13 @@ support for dynamic IP addresses and DHCP, scalability to hundreds or thousands of users, and portability to most major OS platforms. +%package devel +Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan. +Group: Applications/Internet +Requires: %{name} +%description devel +Development support for OpenVPN. + # # Define vendor type # @@ -79,13 +83,6 @@ and portability to most major OS platforms. %endif # -# Should we build the auth-pam module? -# - -%define build_auth_pam 1 -%{?without_pam:%define build_auth_pam 0} - -# # Other definitions # @@ -99,21 +96,14 @@ and portability to most major OS platforms. %setup -q %build -%configure --disable-dependency-tracking %{?with_password_save:--enable-password-save} %{?without_lzo:--disable-lzo} %{?with_kerberos:--with-ssl-headers=/usr/kerberos/include} -%__make -%__strip %{name} - -# Build down-root plugin -pushd plugin/down-root +%configure \ + --disable-dependency-tracking \ + --docdir="%{_docdir}/%{name}-%{version}" \ + %{?with_password_save:--enable-password-save} \ + %{!?without_lzo:--enable-lzo} \ + %{?with_pkcs11:--enable-pkcs11} \ + %{?without_pam:--disable-plugin-auth-pam} %__make -popd - -# Build auth-pam plugin -%if %{build_auth_pam} -pushd plugin/auth-pam -%__make -popd -%endif # # Installation section @@ -121,56 +111,30 @@ popd %install [ %{buildroot} != "/" ] && rm -rf %{buildroot} - -# Install man page -%__install -c -d -m 755 %{buildroot}%{_mandir}/man8 -%__install -c -m 755 %{name}.8 %{buildroot}%{_mandir}/man8 - -# Install binary -%__install -c -d -m 755 %{buildroot}%{_sbindir} -%__install -c -m 755 %{name} %{buildroot}%{_sbindir} +%__make install DESTDIR="%{buildroot}" # Install init script %if "%{VENDOR}" == "SuSE" -%__install -c -d -m 755 %{buildroot}/etc/init.d -%__sed -e 's#openvpn=\"/usr/local/sbin/openvpn\"#openvpn=\"/usr/sbin/openvpn\"#' < suse/%{name}.init > %{_tmppath}/%{name}.init -%__install -c -m 755 %{_tmppath}/%{name}.init %{buildroot}/etc/init.d/%{name} -%__rm %{_tmppath}/%{name}.init +%__install -c -d -m 755 "%{buildroot}/etc/init.d" +%__install -c -m 755 "distro/rpm/%{name}.init.d.suse" "%{buildroot}/etc/init.d/%{name}" %else -%__install -c -d -m 755 %{buildroot}/etc/rc.d/init.d -%__install -c -m 755 sample-scripts/%{name}.init %{buildroot}/etc/rc.d/init.d/%{name} +%__install -c -d -m 755 "%{buildroot}/etc/rc.d/init.d" +%__install -c -m 755 distro/rpm/%{name}.init.d.rhel "%{buildroot}/etc/rc.d/init.d/%{name}" %endif # Install /etc/openvpn -%__install -c -d -m 755 %{buildroot}/etc/%{name} - -# -# Build /usr/share/openvpn -# - -%__mkdir_p %{buildroot}%{_datadir}/%{name} - -# -# Install the plugins -# - -%__mkdir_p %{buildroot}%{_datadir}/%{name}/plugin/lib +%__install -c -d -m 755 "%{buildroot}/etc/%{name}" -for pi in auth-pam down-root; do - %__mv -f plugin/$pi/README plugin/README.$pi - if [ -e plugin/$pi/openvpn-$pi.so ]; then - %__install -c -m 755 plugin/$pi/openvpn-$pi.so %{buildroot}%{_datadir}/openvpn/plugin/lib/openvpn-$pi.so - fi -done - -%__mv -f plugin/README plugin/README.plugins +# Install extra %doc stuff +cp -r AUTHORS ChangeLog NEWS contrib/ sample/ \ + "%{buildroot}/%{_docdir}/%{name}-%{version}" # # Clean section # %clean -[ %{buildroot} != "/" ] && rm -rf %{buildroot} +[ %{buildroot} != "/" ] && rm -rf "%{buildroot}" # # On Linux 2.4, make the device node @@ -208,13 +172,15 @@ fi # # Files section # +# don't use %doc as old rpmbuild removes it[1]. +# [1] http://rpm.org/ticket/836 %files %defattr(-,root,root) -%doc AUTHORS ChangeLog COPYING COPYRIGHT.GPL INSTALL NEWS PORTS README -%{_mandir}/man8/%{name}.8* +%{_mandir} %{_sbindir}/%{name} -%{_datadir}/%{name} +%{_libdir}/%{name} +%{_docdir}/%{name}-%{version} %dir /etc/%{name} %if "%{VENDOR}" == "SuSE" /etc/init.d/%{name} @@ -222,8 +188,9 @@ fi /etc/rc.d/init.d/%{name} %endif -# Install extra %doc stuff -%doc contrib/ easy-rsa/ sample-*/ plugin/README.* +%files devel +%defattr(-,root,root) +%{_includedir}/* %changelog * Thu Jul 30 2009 David Sommerseth <dazo@users.sourceforge.net> diff --git a/openvpn.spec b/distro/rpm/openvpn.spec.in index 7e2ae9d..20a8c89 100644 --- a/openvpn.spec +++ b/distro/rpm/openvpn.spec.in @@ -10,13 +10,10 @@ # # Allow passwords to be read from files # rpmbuild -tb [openvpn.x.tar.gz] --define 'with_password_save 1' -# -# Use this on RH9 and RHEL3 -# rpmbuild -tb [openvpn.x.tar.gz] --define 'with_kerberos 1' Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan. -Name: openvpn -Version: 2.2.1 +Name: @PACKAGE@ +Version: @VERSION@ Release: 1 URL: http://openvpn.net/ Source0: http://prdownloads.sourceforge.net/openvpn/%{name}-%{version}.tar.gz @@ -33,27 +30,27 @@ BuildRoot: %{_tmppath}/%{name}-%(id -un) AutoReq: 0 -BuildRequires: openssl-devel >= 0.9.6 -Requires: openssl >= 0.9.6 +BuildRequires: openssl-devel >= 0.9.7 +Requires: openssl >= 0.9.7 %if "%{_vendor}" == "Mandrakesoft" -%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} -%{!?without_lzo:Requires: liblzo1 >= 1.07} +%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} +%{!?without_lzo:Requires: liblzo1 >= 1.07} %else %if "%{_vendor}" == "MandrakeSoft" -%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} -%{!?without_lzo:Requires: liblzo1 >= 1.07} +%{!?without_lzo:BuildRequires: liblzo1-devel >= 1.07} +%{!?without_lzo:Requires: liblzo1 >= 1.07} %else -%{!?without_lzo:BuildRequires: lzo-devel >= 1.07} -%{!?without_lzo:Requires: lzo >= 1.07} +%{!?without_lzo:BuildRequires: lzo-devel >= 1.07} +%{!?without_lzo:Requires: lzo >= 1.07} %endif %endif -%{!?without_pam:BuildRequires: pam-devel} -%{!?without_pam:Requires: pam} +%{!?without_pam:BuildRequires: pam-devel} +%{!?without_pam:Requires: pam} -%{!?with_pkcs11:BuildRequires: pkcs11-helper-devel} -%{!?with_pkcs11:Requires: pkcs11-helper} +%{?with_pkcs11:BuildRequires: pkcs11-helper-devel} +%{?with_pkcs11:Requires: pkcs11-helper} # # Description @@ -68,6 +65,13 @@ support for dynamic IP addresses and DHCP, scalability to hundreds or thousands of users, and portability to most major OS platforms. +%package devel +Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan. +Group: Applications/Internet +Requires: %{name} +%description devel +Development support for OpenVPN. + # # Define vendor type # @@ -79,13 +83,6 @@ and portability to most major OS platforms. %endif # -# Should we build the auth-pam module? -# - -%define build_auth_pam 1 -%{?without_pam:%define build_auth_pam 0} - -# # Other definitions # @@ -99,21 +96,14 @@ and portability to most major OS platforms. %setup -q %build -%configure --disable-dependency-tracking %{?with_password_save:--enable-password-save} %{?without_lzo:--disable-lzo} %{?with_kerberos:--with-ssl-headers=/usr/kerberos/include} -%__make -%__strip %{name} - -# Build down-root plugin -pushd plugin/down-root +%configure \ + --disable-dependency-tracking \ + --docdir="%{_docdir}/%{name}-%{version}" \ + %{?with_password_save:--enable-password-save} \ + %{!?without_lzo:--enable-lzo} \ + %{?with_pkcs11:--enable-pkcs11} \ + %{?without_pam:--disable-plugin-auth-pam} %__make -popd - -# Build auth-pam plugin -%if %{build_auth_pam} -pushd plugin/auth-pam -%__make -popd -%endif # # Installation section @@ -121,56 +111,30 @@ popd %install [ %{buildroot} != "/" ] && rm -rf %{buildroot} - -# Install man page -%__install -c -d -m 755 %{buildroot}%{_mandir}/man8 -%__install -c -m 755 %{name}.8 %{buildroot}%{_mandir}/man8 - -# Install binary -%__install -c -d -m 755 %{buildroot}%{_sbindir} -%__install -c -m 755 %{name} %{buildroot}%{_sbindir} +%__make install DESTDIR="%{buildroot}" # Install init script %if "%{VENDOR}" == "SuSE" -%__install -c -d -m 755 %{buildroot}/etc/init.d -%__sed -e 's#openvpn=\"/usr/local/sbin/openvpn\"#openvpn=\"/usr/sbin/openvpn\"#' < suse/%{name}.init > %{_tmppath}/%{name}.init -%__install -c -m 755 %{_tmppath}/%{name}.init %{buildroot}/etc/init.d/%{name} -%__rm %{_tmppath}/%{name}.init +%__install -c -d -m 755 "%{buildroot}/etc/init.d" +%__install -c -m 755 "distro/rpm/%{name}.init.d.suse" "%{buildroot}/etc/init.d/%{name}" %else -%__install -c -d -m 755 %{buildroot}/etc/rc.d/init.d -%__install -c -m 755 sample-scripts/%{name}.init %{buildroot}/etc/rc.d/init.d/%{name} +%__install -c -d -m 755 "%{buildroot}/etc/rc.d/init.d" +%__install -c -m 755 distro/rpm/%{name}.init.d.rhel "%{buildroot}/etc/rc.d/init.d/%{name}" %endif # Install /etc/openvpn -%__install -c -d -m 755 %{buildroot}/etc/%{name} - -# -# Build /usr/share/openvpn -# - -%__mkdir_p %{buildroot}%{_datadir}/%{name} - -# -# Install the plugins -# - -%__mkdir_p %{buildroot}%{_datadir}/%{name}/plugin/lib +%__install -c -d -m 755 "%{buildroot}/etc/%{name}" -for pi in auth-pam down-root; do - %__mv -f plugin/$pi/README plugin/README.$pi - if [ -e plugin/$pi/openvpn-$pi.so ]; then - %__install -c -m 755 plugin/$pi/openvpn-$pi.so %{buildroot}%{_datadir}/openvpn/plugin/lib/openvpn-$pi.so - fi -done - -%__mv -f plugin/README plugin/README.plugins +# Install extra %doc stuff +cp -r AUTHORS ChangeLog NEWS contrib/ sample/ \ + "%{buildroot}/%{_docdir}/%{name}-%{version}" # # Clean section # %clean -[ %{buildroot} != "/" ] && rm -rf %{buildroot} +[ %{buildroot} != "/" ] && rm -rf "%{buildroot}" # # On Linux 2.4, make the device node @@ -208,13 +172,15 @@ fi # # Files section # +# don't use %doc as old rpmbuild removes it[1]. +# [1] http://rpm.org/ticket/836 %files %defattr(-,root,root) -%doc AUTHORS ChangeLog COPYING COPYRIGHT.GPL INSTALL NEWS PORTS README -%{_mandir}/man8/%{name}.8* +%{_mandir} %{_sbindir}/%{name} -%{_datadir}/%{name} +%{_libdir}/%{name} +%{_docdir}/%{name}-%{version} %dir /etc/%{name} %if "%{VENDOR}" == "SuSE" /etc/init.d/%{name} @@ -222,8 +188,9 @@ fi /etc/rc.d/init.d/%{name} %endif -# Install extra %doc stuff -%doc contrib/ easy-rsa/ sample-*/ plugin/README.* +%files devel +%defattr(-,root,root) +%{_includedir}/* %changelog * Thu Jul 30 2009 David Sommerseth <dazo@users.sourceforge.net> diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..d33e1ed --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,31 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +CLEANFILES = openvpn.8.html + +dist_doc_DATA = \ + management-notes.txt + +dist_noinst_DATA = \ + README.plugins + +if WIN32 +dist_noinst_DATA += openvpn.8 +nodist_html_DATA = openvpn.8.html +openvpn.8.html: $(srcdir)/openvpn.8 + $(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html +else +dist_man_MANS = openvpn.8 +endif + diff --git a/install-win32/Makefile.in b/doc/Makefile.in index 5f0387f..4371dc4 100644 --- a/install-win32/Makefile.in +++ b/doc/Makefile.in @@ -23,20 +23,7 @@ # 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 +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -58,23 +45,26 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WIN32_FALSE@am__append_1 = sample.ovpn -subdir = install-win32 -DIST_COMMON = $(am__dist_conf_DATA_DIST) $(am__dist_noinst_DATA_DIST) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/settings.in +@WIN32_TRUE@am__append_1 = openvpn.8 +subdir = doc +DIST_COMMON = $(am__dist_noinst_DATA_DIST) $(dist_doc_DATA) \ + $(dist_man_MANS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac +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 -CONFIG_CLEAN_FILES = settings +CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = -am__dist_conf_DATA_DIST = sample.ovpn am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -96,20 +86,18 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(confdir)" "$(DESTDIR)$(confdir)" \ - "$(DESTDIR)$(docdir)" "$(DESTDIR)$(easyrsadir)" \ - "$(DESTDIR)$(keysdir)" -am__dist_noinst_DATA_DIST = openssl GetWindowsVersion.nsi \ - build-pkcs11-helper.sh buildinstaller ddk-common doclean \ - dosname.pl getgui getopenssl getpkcs11helper getprebuilt \ - getxgui ifdef.pl m4todef.pl macro.pl makeopenvpn maketap \ - maketapinstall maketext openvpn.nsi setpath.nsi settings.in \ - trans.pl u2d.c winconfig sample.ovpn -DATA = $(dist_conf_DATA) $(dist_noinst_DATA) $(nodist_conf_DATA) \ - $(nodist_doc_DATA) $(nodist_easyrsa_DATA) $(nodist_keys_DATA) +man8dir = $(mandir)/man8 +am__installdirs = "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(htmldir)" +NROFF = nroff +MANS = $(dist_man_MANS) +am__dist_noinst_DATA_DIST = README.plugins openvpn.8 +DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(nodist_html_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -122,11 +110,17 @@ 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@ @@ -135,15 +129,40 @@ 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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ MAKEINFO = @MAKEINFO@ MAN2HTML = @MAN2HTML@ 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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -152,19 +171,35 @@ 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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ -TAP_ID = @TAP_ID@ -TAP_WIN32_MIN_MAJOR = @TAP_WIN32_MIN_MAJOR@ -TAP_WIN32_MIN_MINOR = @TAP_WIN32_MIN_MINOR@ +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@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ @@ -199,9 +234,11 @@ 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@ @@ -210,32 +247,16 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -win32datadir = @win32datadir@ -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -dist_noinst_DATA = openssl GetWindowsVersion.nsi \ - build-pkcs11-helper.sh buildinstaller ddk-common doclean \ - dosname.pl getgui getopenssl getpkcs11helper getprebuilt \ - getxgui ifdef.pl m4todef.pl macro.pl makeopenvpn maketap \ - maketapinstall maketext openvpn.nsi setpath.nsi settings.in \ - trans.pl u2d.c winconfig $(am__append_1) -@WIN32_TRUE@nodist_doc_DATA = tmp/license.txt -@WIN32_TRUE@confdir = $(win32datadir)/config -@WIN32_TRUE@nodist_conf_DATA = \ -@WIN32_TRUE@ tmp/openssl-1.0.0.cnf \ -@WIN32_TRUE@ tmp/client.ovpn \ -@WIN32_TRUE@ tmp/server.ovpn - -@WIN32_TRUE@dist_conf_DATA = \ -@WIN32_TRUE@ sample.ovpn - -@WIN32_TRUE@easyrsadir = $(win32datadir)/easy-rsa/Windows -@WIN32_TRUE@nodist_easyrsa_DATA = \ -@WIN32_TRUE@ $(top_srcdir)/easy-rsa/Windows/* - -@WIN32_TRUE@keysdir = $(win32datadir)/sample-keys -@WIN32_TRUE@nodist_keys_DATA = \ -@WIN32_TRUE@ $(top_srcdir)/sample-keys/* +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in +CLEANFILES = openvpn.8.html +dist_doc_DATA = \ + management-notes.txt + +dist_noinst_DATA = README.plugins $(am__append_1) +@WIN32_TRUE@nodist_html_DATA = openvpn.8.html +@WIN32_FALSE@dist_man_MANS = openvpn.8 all: all-am .SUFFIXES: @@ -248,9 +269,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu install-win32/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu install-win32/Makefile + $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -269,52 +290,54 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -settings: $(top_builddir)/config.status $(srcdir)/settings.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -install-dist_confDATA: $(dist_conf_DATA) - @$(NORMAL_INSTALL) - test -z "$(confdir)" || $(MKDIR_P) "$(DESTDIR)$(confdir)" - @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(confdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(confdir)" || exit $$?; \ - done -uninstall-dist_confDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(confdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(confdir)" && rm -f $$files -install-nodist_confDATA: $(nodist_conf_DATA) +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man8: $(dist_man_MANS) @$(NORMAL_INSTALL) - test -z "$(confdir)" || $(MKDIR_P) "$(DESTDIR)$(confdir)" - @list='$(nodist_conf_DATA)'; test -n "$(confdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(confdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(confdir)" || exit $$?; \ - done + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } -uninstall-nodist_confDATA: +uninstall-man8: @$(NORMAL_UNINSTALL) - @list='$(nodist_conf_DATA)'; test -n "$(confdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(confdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(confdir)" && rm -f $$files -install-nodist_docDATA: $(nodist_doc_DATA) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" - @list='$(nodist_doc_DATA)'; test -n "$(docdir)" || list=; \ + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -324,53 +347,33 @@ install-nodist_docDATA: $(nodist_doc_DATA) $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done -uninstall-nodist_docDATA: +uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) - @list='$(nodist_doc_DATA)'; test -n "$(docdir)" || list=; \ + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(docdir)" && rm -f $$files -install-nodist_easyrsaDATA: $(nodist_easyrsa_DATA) +install-nodist_htmlDATA: $(nodist_html_DATA) @$(NORMAL_INSTALL) - test -z "$(easyrsadir)" || $(MKDIR_P) "$(DESTDIR)$(easyrsadir)" - @list='$(nodist_easyrsa_DATA)'; test -n "$(easyrsadir)" || list=; \ + test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" + @list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(easyrsadir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(easyrsadir)" || exit $$?; \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done -uninstall-nodist_easyrsaDATA: +uninstall-nodist_htmlDATA: @$(NORMAL_UNINSTALL) - @list='$(nodist_easyrsa_DATA)'; test -n "$(easyrsadir)" || list=; \ + @list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(easyrsadir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(easyrsadir)" && rm -f $$files -install-nodist_keysDATA: $(nodist_keys_DATA) - @$(NORMAL_INSTALL) - test -z "$(keysdir)" || $(MKDIR_P) "$(DESTDIR)$(keysdir)" - @list='$(nodist_keys_DATA)'; test -n "$(keysdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(keysdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(keysdir)" || exit $$?; \ - done - -uninstall-nodist_keysDATA: - @$(NORMAL_UNINSTALL) - @list='$(nodist_keys_DATA)'; test -n "$(keysdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(keysdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(keysdir)" && rm -f $$files + echo " ( cd '$(DESTDIR)$(htmldir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(htmldir)" && rm -f $$files tags: TAGS TAGS: @@ -379,6 +382,19 @@ CTAGS: distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -410,9 +426,9 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(DATA) +all-am: Makefile $(MANS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(confdir)" "$(DESTDIR)$(confdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(easyrsadir)" "$(DESTDIR)$(keysdir)"; do \ + for dir in "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -432,6 +448,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -441,10 +458,9 @@ 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) -@WIN32_FALSE@clean-local: clean: clean-am -clean-am: clean-generic clean-local mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile @@ -462,9 +478,8 @@ info: info-am info-am: -install-data-am: install-dist_confDATA install-nodist_confDATA \ - install-nodist_docDATA install-nodist_easyrsaDATA \ - install-nodist_keysDATA +install-data-am: install-dist_docDATA install-man \ + install-nodist_htmlDATA install-dvi: install-dvi-am @@ -480,7 +495,7 @@ install-info: install-info-am install-info-am: -install-man: +install-man: install-man8 install-pdf: install-pdf-am @@ -498,7 +513,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-generic +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -508,45 +523,29 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_confDATA uninstall-nodist_confDATA \ - uninstall-nodist_docDATA uninstall-nodist_easyrsaDATA \ - uninstall-nodist_keysDATA - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-local \ - distclean distclean-generic distdir dvi dvi-am html html-am \ - info info-am install install-am install-data install-data-am \ - install-dist_confDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-nodist_confDATA \ - install-nodist_docDATA install-nodist_easyrsaDATA \ - install-nodist_keysDATA install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ - uninstall-am uninstall-dist_confDATA uninstall-nodist_confDATA \ - uninstall-nodist_docDATA uninstall-nodist_easyrsaDATA \ - uninstall-nodist_keysDATA +uninstall-am: uninstall-dist_docDATA uninstall-man \ + uninstall-nodist_htmlDATA +uninstall-man: uninstall-man8 -@WIN32_TRUE@tmp: -@WIN32_TRUE@ mkdir tmp - -@WIN32_TRUE@tmp/client.ovpn: tmp $(top_srcdir)/sample-config-files/client.conf -@WIN32_TRUE@ cp $(top_srcdir)/sample-config-files/client.conf tmp/client.ovpn - -@WIN32_TRUE@tmp/server.ovpn: tmp $(top_srcdir)/sample-config-files/server.conf -@WIN32_TRUE@ cp $(top_srcdir)/sample-config-files/server.conf tmp/server.ovpn - -@WIN32_TRUE@tmp/license.txt: tmp $(top_srcdir)/COPYING $(top_srcdir)/COPYRIGHT.GPL -@WIN32_TRUE@ cat $(top_srcdir)/COPYING $(top_srcdir)/COPYRIGHT.GPL > tmp/license.txt - -@WIN32_TRUE@tmp/openssl-1.0.0.cnf: tmp $(top_srcdir)/easy-rsa/2.0/openssl-1.0.0.cnf -@WIN32_TRUE@ cp $(top_srcdir)/easy-rsa/2.0/openssl-1.0.0.cnf tmp/openssl-1.0.0.cnf +.MAKE: install-am install-strip -@WIN32_TRUE@clean-local: -@WIN32_TRUE@ -rm -fr tmp +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_docDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man8 install-nodist_htmlDATA 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 uninstall uninstall-am \ + uninstall-dist_docDATA uninstall-man uninstall-man8 \ + uninstall-nodist_htmlDATA + +@WIN32_TRUE@openvpn.8.html: $(srcdir)/openvpn.8 +@WIN32_TRUE@ $(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html # 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/plugin/README b/doc/README.plugins index 6e490c5..6e490c5 100644 --- a/plugin/README +++ b/doc/README.plugins diff --git a/management/management-notes.txt b/doc/management-notes.txt index 1f4cbd0..79e71ad 100644 --- a/management/management-notes.txt +++ b/doc/management-notes.txt @@ -687,6 +687,97 @@ the 10.0.0.0/8 netblock is allowed: 10.10.0.1. Also, the client may not interact with external IP addresses using an "unknown" protocol (i.e. one that is not IPv4 or ARP). +COMMAND -- remote (OpenVPN AS 2.1.5/OpenVPN 2.3 or higher) +-------------------------------------------- + +Provide remote host/port in response to a >REMOTE notification +(client only). Requires that the --management-query-remote +directive is used. + + remote ACTION [HOST PORT] + +The "remote" command should only be given in response to a >REMOTE +notification. For example, the following >REMOTE notification +indicates that the client config file would ordinarily connect +to vpn.example.com port 1194 (UDP): + + >REMOTE:vpn.example.com,1194,udp + +Now, suppose we want to override the host and port, connecting +instead to vpn.otherexample.com port 1234. After receiving +the above notification, use this command: + + remote MOD vpn.otherexample.com 1234 + +To accept the same host and port as the client would ordinarily +have connected to, use this command: + + remote ACCEPT + +To skip the current connection entry and advance to the next one, +use this command: + + remote SKIP + +COMMAND -- proxy (OpenVPN 2.3 or higher) +-------------------------------------------- + +Provide proxy server host/port and flags in response to a >PROXY +notification (client only). Requires that the --management-query-proxy +directive is used. + + proxy TYPE HOST PORT ["nct"] + +The "proxy" command must only be given in response to a >PROXY +notification. Use the "nct" flag if you only want to allow +non-cleartext auth with the proxy server. The following >PROXY +notification indicates that the client config file would ordinarily +connect to the first --remote configured, vpn.example.com using TCP: + + >PROXY:1,TCP,vpn.example.com + +Now, suppose we want to connect to the remote host using the proxy server +proxy.intranet port 8080 with secure authentication only, if required. +After receiving the above notification, use this command: + + proxy HTTP proxy.intranet 8080 nct + +You can also use the SOCKS keyword to pass a SOCKS server address, like: + + proxy SOCKS fe00::1 1080 + +To accept connecting to the host and port directly, use this command: + + proxy NONE + +COMMAND -- rsa-sig (OpenVPN 2.3 or higher) +------------------------------------------ +Provides support for external storage of the private key. Requires the +--management-external-key option. This option can be used instead of "key" +in client mode, and allows the client to run without the need to load the +actual private key. When the SSL protocol needs to perform an RSA sign +operation, the data to be signed will be sent to the management interface +via a notification as follows: + +>RSA_SIGN:[BASE64_DATA] + +The management interface client should then sign BASE64_DATA +using the private key and return the SSL signature as follows: + +rsa-sig +[BASE64_SIG_LINE] +. +. +. +END + +Base64 encoded output of RSA_sign(NID_md5_sha1,... will provide a +correct signature. + +This capability is intended to allow the use of arbitrarycryptographic +service providers with OpenVPN via the management interface. + + OUTPUT FORMAT ------------- @@ -836,3 +927,113 @@ mappings, when not in single quotations: interpret it as enclosing a parameter. \[SPACE] Pass a literal space or tab character, don't interpret it as a parameter delimiter. + +Challenge/Response Protocol +--------------------------- + +The OpenVPN Challenge/Response Protocol allows an OpenVPN server to +generate challenge questions that are shown to the user, and to see +the user's responses to those challenges. Based on the responses, the +server can allow or deny access. + +In this way, the OpenVPN Challenge/Response Protocol can be used +to implement multi-factor authentication. Two different +variations on the challenge/response protocol are supported: the +"Dynamic" and "Static" protocols. + +The basic idea of Challenge/Response is that the user must enter an +additional piece of information, in addition to the username and +password, to successfully authenticate. Normally, this information +is used to prove that the user posesses a certain key-like device +such as cryptographic token or a particular mobile phone. + +Dynamic protocol: + +The OpenVPN dynamic challenge/response protocol works by returning +a specially formatted error message after initial successful +authentication. This error message contains the challenge question, +and is formatted as such: + + CRV1:<flags>:<state_id>:<username_base64>:<challenge_text> + +flags: a series of optional, comma-separated flags: + E : echo the response when the user types it + R : a response is required + +state_id: an opaque string that should be returned to the server + along with the response. + +username_base64 : the username formatted as base64 + +challenge_text : the challenge text to be shown to the user + +Example challenge: + + CRV1:R,E:Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l:Y3Ix:Please enter token PIN + +After showing the challenge_text and getting a response from the user +(if R flag is specified), the client should submit the following +auth creds back to the OpenVPN server: + +Username: [username decoded from username_base64] +Password: CRV1::<state_id>::<response_text> + +Where state_id is taken from the challenge request and response_text +is what the user entered in response to the challenge_text. +If the R flag is not present, response_text may be the empty +string. + +Example response (suppose the user enters "8675309" for the token PIN): + + Username: cr1 ("Y3Ix" base64 decoded) + Password: CRV1::Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l::8675309 + +Static protocol: + +The static protocol differs from the dynamic protocol in that the +challenge question and response field is given to the user in the +initial username/password dialog, and the username, password, and +response are delivered back to the server in a single transaction. + +The "static-challenge" directive is used to give the challenge text +to OpenVPN and indicate whether or not the response should be echoed. + +When the "static-challenge" directive is used, the management +interface will respond as such when credentials are needed: + + >PASSWORD:Need 'Auth' username/password SC:<ECHO>,<TEXT> + + ECHO: "1" if response should be echoed, "0" to not echo + TEXT: challenge text that should be shown to the user to + facilitate their response + +For example: + + >PASSWORD:Need 'Auth' username/password SC:1,Please enter token PIN + +The above notification indicates that OpenVPN needs a --auth-user-pass +password plus a response to a static challenge ("Please enter token PIN"). +The "1" after the "SC:" indicates that the response should be echoed. + +The management interface client in this case should add the static +challenge text to the auth dialog followed by a field for the user to +enter a response. Then the client should pack the password and response +together into an encoded password: + + username "Auth" foo + password "Auth" "SCRV1:<BASE64_PASSWORD>:<BASE64_RESPONSE>" + +For example, if the user entered "bar" as the password and 8675309 +as the PIN, the following management interface commands should be +issued: + + username "Auth" foo + password "Auth" "SCRV1:Zm9v:ODY3NTMwOQ==" + +Client-side support for challenge/response protocol: + +Currently, the Access Server client and standalone OpenVPN +client support both static and dynamic challenge/response +protocols. However, any OpenVPN client UI that drives OpenVPN +via the management interface needs to add explicit support +for the challenge/response protocol. diff --git a/openvpn.8 b/doc/openvpn.8 index 67a9779..2ed5201 100644 --- a/openvpn.8 +++ b/doc/openvpn.8 @@ -482,18 +482,6 @@ as the number of retries of connection attempt (default=infinite). .\"********************************************************* .TP -.B \-\-auto-proxy -Try to sense HTTP or SOCKS proxy settings automatically. -If no settings are present, a direct connection will be attempted. -If both HTTP and SOCKS settings are present, HTTP will be preferred. -If the HTTP proxy server requires a password, it will be queried from -stdin or the management interface. If the underlying OS doesn't support an API for -returning proxy settings, a direct connection will be attempted. -Currently, only Windows clients support this option via the -InternetQueryOption API. -This option exists in OpenVPN 2.1 or higher. -.\"********************************************************* -.TP .B \-\-show-proxy-settings Show sensed HTTP or SOCKS proxy settings. Currently, only Windows clients support this option. @@ -612,12 +600,21 @@ option. .\"********************************************************* .TP .B \-\-ipchange cmd -Execute shell command +Run command .B cmd when our remote ip-address is initially authenticated or changes. -Execute as: +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +When +.B cmd +is executed two arguments are appended after any arguments specified in +.B cmd +, as follows: .B cmd ip_address port_number @@ -632,14 +629,6 @@ script instead. See the "Environmental Variables" section below for additional parameters passed as environmental variables. -Note that -.B cmd -can be a shell command with multiple arguments, in which -case all OpenVPN-generated arguments will be appended -to -.B cmd -to build a command line which will be passed to the script. - If you are running in a dynamic IP address environment where the IP addresses of either peer could change without notice, you can use this script, for example, to edit the @@ -794,6 +783,8 @@ 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 @@ -1045,17 +1036,32 @@ for the TAP-Win32 adapter to come up before adding routes. .\"********************************************************* .TP .B \-\-route-up cmd -Execute shell command +Run command .B cmd after routes are added, subject to .B \-\-route-delay. +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + See the "Environmental Variables" section below for additional parameters passed as environmental variables. +.\"********************************************************* +.TP +.B \-\-route-pre-down cmd +Run command +.B cmd +before routes are removed upon disconnection. -Note that .B cmd -can be a shell command with multiple arguments. +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +See the "Environmental Variables" section below for +additional parameters passed as environmental variables. .\"********************************************************* .TP .B \-\-route-noexec @@ -1069,7 +1075,8 @@ When used with .B \-\-client or .B \-\-pull, -accept options pushed by server EXCEPT for routes. +accept options pushed by server EXCEPT for routes and dhcp options +like DNS servers. When used on the client, this option effectively bars the server from adding routes to the client's routing table, @@ -1086,9 +1093,34 @@ and .B \-\-route-gateway. .\"********************************************************* .TP +.B \-\-client-nat snat|dnat network netmask alias +This pushable client option sets up a stateless one-to-one NAT +rule on packet addresses (not ports), and is useful in cases +where routes or ifconfig settings pushed to the client would +create an IP numbering conflict. + +.B network/netmask +(for example 192.168.0.0/255.255.0.0) +defines the local view of a resource from the client perspective, while +.B alias/netmask +(for example 10.64.0.0/255.255.0.0) +defines the remote view from the server perspective. + +Use +.B snat +(source NAT) for resources owned by the client and +.B dnat +(destination NAT) for remote resources. + +Set +.B \-\-verb 6 +for debugging info showing the transformation of src/dest +addresses in packets. +.\"********************************************************* +.TP .B \-\-redirect-gateway flags... -(Experimental) Automatically execute routing commands to cause all outgoing IP traffic -to be redirected over the VPN. +Automatically execute routing commands to cause all outgoing IP traffic +to be redirected over the VPN. This is a client-side option. This option performs three steps: @@ -1127,6 +1159,11 @@ flag will cause step .B 1 above to be omitted. +.B autolocal \-\- +Try to automatically determine whether to enable +.B local +flag above. + .B def1 \-\- Use this flag to override the default gateway by using 0.0.0.0/1 and 128.0.0.0/1 @@ -1145,12 +1182,10 @@ bypasses the tunnel (Available on Windows clients, may not be available on non-Windows clients). -Using the def1 flag is highly recommended. -.\"********************************************************* -.TP -.B \-\-redirect-private [flags] -Like \-\-redirect-gateway, but omit actually changing the default -gateway. Useful when pushing private subnets. +.B block-local \-\- +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. .\"********************************************************* .TP .B \-\-link-mtu n @@ -1158,6 +1193,12 @@ Sets an upper bound on the size of UDP packets which are sent between OpenVPN peers. It's best not to set this parameter unless you know what you're doing. .\"********************************************************* +.\"********************************************************* +.TP +.B \-\-redirect-private [flags] +Like \-\-redirect-gateway, but omit actually changing the default +gateway. Useful when pushing private subnets. +.\"********************************************************* .TP .B \-\-tun-mtu n Take the TUN device MTU to be @@ -1335,6 +1376,12 @@ Set the TCP/UDP socket receive buffer size. Currently defaults to 65536 bytes. .\"********************************************************* .TP +.B \-\-mark value +Mark encrypted packets being sent with value. The mark value can be +matched in policy routing and packetfilter rules. This option is +only supported in Linux and does nothing on other operating systems. +.\"********************************************************* +.TP .B \-\-socket-flags flags... Apply the given flags to the OpenVPN transport socket. Currently, only @@ -1537,6 +1584,10 @@ and .B \-\-ping-restart in server mode configurations. +The server timeout is set twice the value of the second argument. +This ensures that a timeout is dectected on client side +before the server side drops the connection. + For example, .B \-\-keepalive 10 60 expands as follows: @@ -1649,10 +1700,19 @@ memory available to other applications. .\"********************************************************* .TP .B \-\-up cmd -Shell command to run after successful TUN/TAP device open +Run command +.B cmd +after successful TUN/TAP device open (pre .B \-\-user -UID change). The up script is useful for specifying route +UID change). + +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +The up command is useful for specifying route commands which route IP traffic destined for private subnets which exist at the other end of the VPN connection into the tunnel. @@ -1672,13 +1732,11 @@ execute as: See the "Environmental Variables" section below for additional parameters passed as environmental variables. -Note that -.B cmd -can be a shell command with multiple arguments, in which -case all OpenVPN-generated arguments will be appended -to +Note that if .B cmd -to build a command line which will be passed to the shell. +includes arguments, all OpenVPN-generated arguments will be appended +to them to build an argument list with which the executable will be +called. Typically, .B cmd @@ -1754,12 +1812,20 @@ i.e. the receipt of the first authenticated packet from the peer. .\"********************************************************* .TP .B \-\-down cmd -Shell command to run after TUN/TAP device close +Run command +.B cmd +after TUN/TAP device close (post .B \-\-user UID change and/or .B \-\-chroot -). Called with the same parameters and environmental +). +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +Called with the same parameters and environmental variables as the .B \-\-up option above. @@ -1820,7 +1886,7 @@ is a safety precaution to prevent a LD_PRELOAD style attack from a malicious or compromised server. .\"********************************************************* .TP -.B \-\-script-security level [method] +.B \-\-script-security level This directive offers policy-level control over OpenVPN's usage of external programs and scripts. Lower .B level @@ -1839,24 +1905,40 @@ Allow calling of built-in executables and user-defined scripts. .B 3 \-\- Allow passwords to be passed to scripts via environmental variables (potentially unsafe). -The +OpenVPN releases before v2.3 also supported a .B method -parameter indicates how OpenVPN should call external commands and scripts. -Settings for -.B method: +flag which indicated how OpenVPN should call external commands and scripts. This +could be either +.B execve +or +.B system. +As of OpenVPN v2.3, this flag is no longer accepted. In most *nix environments the execve() +approach has been used without any issues. + +To run scripts in Windows in earlier OpenVPN +versions you needed to either add a full path to the script interpreter which can parse the +script or use the +.B system +flag to run these scripts. As of OpenVPN v2.3 it is now a strict requirement to have +full path to the script interpreter when running non-executables files. +This is not needed for executable files, such as .exe, .com, .bat or .cmd files. For +example, if you have a Visual Basic script, you must use this syntax now: -.B execve \-\- -(default) Use execve() function on Unix family OSes and CreateProcess() on Windows. -.br -.B system \-\- -Use system() function (deprecated and less safe since the external program command -line is subject to shell expansion). +.nf +.ft 3 +.in +4 +\-\-up 'C:\\\\Windows\\\\System32\\\\wscript.exe C:\\\\Program\\ Files\\\\OpenVPN\\\\config\\\\my-up-script.vbs' +.in -4 +.ft +.fi -The -.B \-\-script-security -option was introduced in OpenVPN 2.1_rc9. For configuration file compatibility -with previous OpenVPN versions, use: -.B \-\-script-security 3 system +Please note the single quote marks and the escaping of the backslashes (\\) and +the space character. + +The reason the support for the +.B system +flag was removed is due to the security implications with shell expansions +when executing scripts via the system() call. .\"********************************************************* .TP .B \-\-disable-occ @@ -1987,7 +2069,7 @@ options. Become a daemon after all initialization functions are completed. This option will cause all message and error output to be sent to the syslog file (such as /var/log/messages), -except for the output of shell scripts and +except for the output of scripts and ifconfig commands, which will go to /dev/null unless otherwise redirected. The syslog redirection occurs immediately at the point @@ -2028,6 +2110,11 @@ See directive above for description of .B progname parameter. +.TP +.B \-\-errors-to-stderr +Output errors to stderr instead of stdout unless log output is redirected by one of the +.B \-\-log +options. .\"********************************************************* .TP .B \-\-passtos @@ -2364,11 +2451,14 @@ be set to 127.0.0.1 server to local clients. .TP .B \-\-management-client -Management interface will connect as a TCP client to +Management interface will connect as a TCP/unix domain client to .B IP:port specified by .B \-\-management -rather than listen as a TCP server. +rather than listen as a TCP server or on a unix domain socket. + +If the client connection fails to connect or is disconnected, +a SIGTERM signal will be generated causing OpenVPN to quit. .\"********************************************************* .TP .B \-\-management-query-passwords @@ -2379,6 +2469,23 @@ for inputs which ordinarily would have been queried from the console. .\"********************************************************* .TP +.B \-\-management-query-proxy +Query management channel for proxy server information for a specific +.B \-\-remote +(client-only). +.\"********************************************************* +.TP +.B \-\-management-query-remote +Allow management interface to override +.B \-\-remote +directives (client-only). +.\"********************************************************* +.B \-\-management-external-key +Allows usage for external private key file instead of +.B \-\-key +option (client-only). +.\"********************************************************* +.TP .B \-\-management-forget-disconnect Make OpenVPN forget passwords when management session disconnects. @@ -2399,7 +2506,8 @@ command. .B \-\-management-signal Send SIGUSR1 signal to OpenVPN if management session disconnects. This is useful when you wish to disconnect an OpenVPN session on -user logoff. +user logoff. For --management-client this option is not needed since +a disconnect will always generate a SIGTERM. .\"********************************************************* .TP .B \-\-management-log-cache n @@ -2409,6 +2517,11 @@ lines of log file history for usage by the management channel. .\"********************************************************* .TP +.B \-\-management-up-down +Report tunnel up/down events to management interface. +.B +.\"********************************************************* +.TP .B \-\-management-client-auth Gives management interface client the responsibility to authenticate clients after their client certificate @@ -2659,6 +2772,20 @@ as with a configuration file. This option will ignore .B \-\-push options at the global config file level. +.TP +.B \-\-push-peer-info +Push additional information about the client to server. The additional information +consists of the following data: + +IV_VER=<version> -- the client OpenVPN version + +IV_PLAT=[linux|solaris|openbsd|mac|netbsd|freebsd|win] -- the client OS platform + +IV_HWADDR=<mac address> -- the MAC address of clients default gateway + +IV_LZO_STUB=1 -- if client was built with LZO stub capability + +UV_<name>=<value> -- client environment variables whose names start with "UV_" .\"********************************************************* .TP .B \-\-disable @@ -2743,7 +2870,7 @@ This option is deprecated, and should be replaced with which is functionally equivalent. .\"********************************************************* .TP -.B \-\-ifconfig-push local remote-netmask +.B \-\-ifconfig-push local remote-netmask [alias] Push virtual IP endpoints for client tunnel, overriding the \-\-ifconfig-pool dynamic allocation. @@ -2762,6 +2889,15 @@ are from the perspective of the client, not the server. They may be DNS names rather than IP addresses, in which case they will be resolved on the server at the time of client connection. +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 +will refer to the server view while +.B alias/remote-netmask +will refer to the client view. + This option must be associated with a specific client instance, which means that it must be specified either in a client instance config file using @@ -2868,20 +3004,29 @@ In the absence of this option, OpenVPN will disconnect a client instance upon connection of a new client having the same common name. .\"********************************************************* .TP -.B \-\-client-connect script +.B \-\-client-connect cmd Run -.B script -on client connection. The script is passed the common name +.B command cmd +on client connection. + +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +The command is passed the common name and IP address of the just-authenticated client as environmental variables (see environmental variable section -below). The script is also passed -the pathname of a freshly created temporary file as $1 -(i.e. the first command line argument), to be used by the script +below). The command is also passed +the pathname of a freshly created temporary file as the last argument +(after any arguments specified in +.B cmd +), to be used by the command to pass dynamically generated config file directives back to OpenVPN. If the script wants to generate a dynamic config file to be applied on the server when the client connects, -it should write it to the file named by $1. +it should write it to the file named by the last argument. See the .B \-\-client-config-dir @@ -2896,7 +3041,7 @@ returns a non-zero error status, it will cause the client to be disconnected. .\"********************************************************* .TP -.B \-\-client-disconnect +.B \-\-client-disconnect cmd Like .B \-\-client-connect but called on client instance shutdown. Will not be called @@ -2908,11 +3053,19 @@ successful (0) status returns. The exception to this rule is if the .B \-\-client-disconnect -script or plugins are cascaded, and at least one client-connect +command or plugins are cascaded, and at least one client-connect function succeeded, then ALL of the client-disconnect functions for scripts and plugins will be called on client instance object deletion, even in cases where some of the related client-connect functions returned an error status. + +The +.B \-\-client-disconnect +command is passed the same pathname as the corresponding +.B \-\-client-connect +command as its last argument. (after any arguments specified in +.B cmd +). .B .\"********************************************************* .TP @@ -3056,6 +3209,25 @@ directive affects OpenVPN's internal routing table, not the kernel routing table. .\"********************************************************* .TP +.B \-\-stale-routes-check n [t] +Remove routes haven't had activity for +.B n +seconds (i.e. the ageing time). + +This check is ran every +.B t +seconds (i.e. check interval). + +If +.B t +is not present it defaults to +.B n + +This option helps to keep the dynamic routing table small. +See also +.B \-\-max-routes-per-client +.\"********************************************************* +.TP .B \-\-connect-freq n sec Allow a maximum of .B n @@ -3076,12 +3248,18 @@ and .\"********************************************************* .TP .B \-\-learn-address cmd -Run script or shell command +Run command .B cmd to validate client virtual addresses or routes. .B cmd -will be executed with 3 parameters: +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + +Three arguments will be appended to any arguments in +.B cmd +as follows: .B [1] operation \-\- "add", "update", or "delete" based on whether or not @@ -3115,15 +3293,20 @@ policies with regard to the client's high-level common name, rather than the low level client virtual addresses. .\"********************************************************* .TP -.B \-\-auth-user-pass-verify script method +.B \-\-auth-user-pass-verify cmd method Require the client to provide a username/password (possibly in addition to a client certificate) for authentication. -OpenVPN will execute -.B script -as a shell command to validate the username/password +OpenVPN will run +.B command cmd +to validate the username/password provided by the client. +.B cmd +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +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 @@ -3241,28 +3424,59 @@ the authenticated username as the common name, rather than the common name from the client cert. .\"********************************************************* .TP -.B \-\-no-name-remapping -Allow Common Name, X509 Subject, and username strings to include -any printable character including space, but excluding control -characters such as tab, newline, and carriage-return. - -By default, OpenVPN will remap -any character other than alphanumeric, underbar ('_'), dash -('-'), dot ('.'), and slash ('/') to underbar ('_'). The X509 -Subject string as returned by the +.B \-\-compat\-names [no\-remapping] +Until OpenVPN v2.3 the format of the X.509 Subject fields was formatted +like this: +.IP +.B +/C=US/L=Somewhere/CN=John Doe/emailAddress=john@example.com +.IP +In addition the old behavivour was to remap any character other than +alphanumeric, underscore ('_'), dash ('-'), dot ('.'), and slash ('/') to +underscore ('_'). The X.509 Subject string as returned by the .B tls_id -environmental variable, can additionally contain colon (':') or -equal ('='). +environmental variable, could additionally contain colon (':') or equal ('='). +.IP +When using the +.B \-\-compat\-names +option, this old formatting and remapping will be re-enabled again. This is +purely implemented for compatibility reasons when using older plug-ins or +scripts which does not handle the new formatting or UTF-8 characters. +.IP +In OpenVPN v2.3 the formatting of these fields changed into a more +standardised format. It now looks like: +.IP +.B +C=US, L=Somewhere, CN=John Doe, emailAddress=john@example.com +.IP +The new default format in OpenVPN v2.3 also does not do the character remapping +which happened earlier. This new format enables proper support for UTF\-8 +characters in the usernames, X.509 Subject fields and Common Name variables and +it complies to the RFC 2253, UTF\-8 String Representation of Distinguished +Names. + +As a backwards compatibility for the removed \-\-no\-name\-remapping feature in +older OpenVPN versions, the +.B no\-remapping +mode flag can be used with the +.B +\-\-compat\-names +option. +When this mode flag is used, the Common Name, Subject, and username strings are +allowed to include any printable character including space, but excluding +control characters such as tab, newline, and carriage-return. It ensures +compatibility with the +.B \-\-no\-name\-remapping +option of OpenVPN versions before v2.3. -While name remapping is performed for security reasons to reduce -the possibility of introducing string expansion security vulnerabilities -in user-defined authentication -scripts, this option is provided for those cases where it is desirable to -disable the remapping feature. Don't use this option unless you -know what you are doing! +.B Please note: +This option will not be around for a long time. 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 start +the process to support the new formatting as soon as possible. .\"********************************************************* .TP -.B \-\-port-share host port +.B \-\-port-share host port [dir] When run in TCP server mode, share the OpenVPN port with another application, such as an HTTPS server. If OpenVPN senses a connection to its port which is using a non-OpenVPN @@ -3272,6 +3486,16 @@ Currently only designed to work with HTTP/HTTPS, though it would be theoretically possible to extend to other protocols such as ssh. +.B dir +specifies an optional directory where a temporary file with name N +containing content C will be dynamically generated for each proxy +connection, where N is the source IP:port of the client connection +and C is the source IP:port of the connection to the proxy +receiver. This directory can be used as a dictionary by +the proxy receiver to determine the origin of the connection. +Each generated file will be automatically deleted when the proxied +connection is torn down. + Not implemented on Windows. .\"********************************************************* .SS Client Mode @@ -3374,6 +3598,21 @@ Note that while this option cannot be pushed, it can be controlled from the management interface. .\"********************************************************* .TP +.B \-\-static\-challenge t e +Enable static challenge/response protocol using challenge text +.B t, +with +echo flag given by +.B e +(0|1). + +The echo flag indicates whether or not the user's response +to the challenge should be echoed. + +See management\-notes.txt in the OpenVPN distribution for a +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 @@ -3463,6 +3702,14 @@ would see nothing but random-looking data. .\"********************************************************* .TP +.B \-\-key-direction +Alternative way of specifying the optional direction parameter for the +.B \-\-tls-auth +and +.B \-\-secret +options. Useful when using inline files (See section on inline files). +.\"********************************************************* +.TP .B \-\-auth alg Authenticate packets with HMAC using message digest algorithm @@ -3742,6 +3989,20 @@ space-saving optimization that uses the unique identifier for datagram replay protection as the IV. .\"********************************************************* .TP +.B \-\-use-prediction-resistance +Enable prediction resistance on PolarSSL's RNG. + +Enabling prediction resistance causes the RNG to reseed in each +call for random. Reseeding this often can quickly deplete the kernel +entropy pool. + +If you need this option, please consider running a daemon that adds +entropy to the kernel pool. + +Note that this option only works with PolarSSL versions greater +than 1.1. +.\"********************************************************* +.TP .B \-\-test-crypto Do a self-test of OpenVPN's crypto options by encrypting and decrypting test packets using the data channel encryption options @@ -3846,6 +4107,7 @@ they are distributed with OpenVPN, they are totally insecure. .B \-\-capath dir Directory containing trusted certificates (CAs and CRLs). Available with OpenSSL version >= 0.9.7 dev. +Not available with PolarSSL. .\"********************************************************* .TP .B \-\-dh file @@ -3905,6 +4167,22 @@ that for certificate authority functions, you must set up the files ). .\"********************************************************* .TP +.B \-\-extra-certs file +Specify a +.B file +containing one or more PEM certs (concatenated together) +that complete the +local certificate chain. + +This option is useful for "split" CAs, where the CA for server +certs is different than the CA for client certs. Putting certs +in this file allows them to be used to complete the local +certificate chain without trusting them to verify the peer-submitted +certificate, as would be the case if the certs were placed in the +.B ca +file. +.\"********************************************************* +.TP .B \-\-key file Local peer's private key in .pem format. Use the private key which was generated when you built your peer's certificate (see @@ -3919,6 +4197,18 @@ This option can be used instead of .B \-\-ca, \-\-cert, and .B \-\-key. +Not available with PolarSSL. +.\"********************************************************* +.TP +.B \-\-verify-hash hash +Specify SHA1 fingerprint for level-1 cert. The level-1 cert is the +CA (or intermediate cert) that signs the leaf certificate, and is +one removed from the leaf certificate in the direction of the root. +When accepting a connection from a peer, the level-1 cert +fingerprint must match +.B hash +or certificate verification will fail. Hash is specified +as XX:XX:... For example: AD:B0:95:D8:09:C8:36:45:12:A9:89:C8:90:09:CB:13:72:A6:AD:16 .\"********************************************************* .TP .B \-\-pkcs11-cert-private [0|1]... @@ -3983,7 +4273,7 @@ Mode is encoded as hex number, and can be a mask one of the following: .TP .B \-\-cryptoapicert select-string Load the certificate and private key from the -Windows Certificate System Store (Windows Only). +Windows Certificate System Store (Windows/OpenSSL Only). Use this option instead of .B \-\-cert @@ -4304,7 +4594,7 @@ username/password. It is always cached. .\"********************************************************* .TP .B \-\-tls-verify cmd -Execute shell command +Run command .B cmd to verify the X509 name of a pending TLS connection that has otherwise passed all other @@ -4317,18 +4607,18 @@ test). .B cmd should return 0 to allow the TLS handshake to proceed, or 1 to fail. -Note that .B cmd -is a command line and as such may (if enclosed in quotes) contain -whitespace separated arguments. The first word of -.B cmd -is the shell command to execute and the remaining words are its -arguments. +consists of a path to script (or executable program), optionally +followed by arguments. The path and arguments may be single- or double-quoted +and/or escaped using a backslash, and should be separated by one or more spaces. + When .B cmd -is executed two arguments are appended, as follows: +is executed two arguments are appended after any arguments specified in +.B cmd +, as follows: -.B cmd certificate_depth X509_NAME_oneline +.B cmd certificate_depth subject These arguments are, respectively, the current certificate depth and the X509 common name (cn) of the peer. @@ -4350,7 +4640,7 @@ additional parameters passed as environmental variables. .TP .B \-\-tls-export-cert directory Store the certificates the clients uses upon connection to this -directory. This will be done before --tls-verify is called. The +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 is available via the peer_cert environment variable. @@ -4398,6 +4688,19 @@ works in a environment too. .\"********************************************************* .TP +.B \-\-x509-track attribute +Save peer X509 +.B attribute +value in environment for use by plugins and management interface. +Prepend a '+' to +.B attribute +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 Require that peer certificate was signed with an explicit .B nsCertType @@ -4483,7 +4786,7 @@ or .B \-\-tls-verify. .\"********************************************************* .TP -.B \-\-crl-verify crl +.B \-\-crl-verify crl ['dir'] Check peer certificate against the file .B crl in PEM format. @@ -4499,6 +4802,16 @@ overall integrity of the PKI. The only time when it would be necessary to rebuild the entire PKI from scratch would be if the root certificate key itself was compromised. + +If the optional +.B dir +flag is specified, enable a different mode where +.B crl +is a directory containing files named as revoked serial numbers +(the files may be empty, the contents are never read). If a client +requests a connection, where the client certificate serial number +(decimal string) is the name of a file present in the directory, +it will be rejected. .\"********************************************************* .SS SSL Library information: .\"********************************************************* @@ -4611,20 +4924,23 @@ Optional group to be owner of this tunnel. .SS Windows-Specific Options: .\"********************************************************* .TP -.B \-\-win-sys path|'env' +.B \-\-win-sys path Set the Windows system directory pathname to use when looking for system executables such as .B route.exe and .B netsh.exe. By default, if this directive is -not specified, the pathname will be set to "C:\\WINDOWS" +not specified, OpenVPN will use the SystemRoot environment variable. -The special string -.B 'env' -indicates that the pathname should be read from the -.B SystemRoot -environmental variable. +This option have changed behaviour in OpenVPN 2.3. Earlier you had to +define +.B --win-sys env +to use the SystemRoot environment variable, otherwise it defaulted to C:\\WINDOWS. +It is not needed to use the +.B env +keyword any more, and it will just be ignored. A warning is logged when this +is found in the configuration file. .\"********************************************************* .TP .B \-\-ip-win32 method @@ -4949,6 +5265,57 @@ if certificates are stored as private objects. .B \-\-verb option can be used BEFORE this option to produce debugging information. .\"********************************************************* +.SS IPv6 Related Options +.\"********************************************************* +The following options exist to support IPv6 tunneling in peer-to-peer +and client-server mode. As of now, this is just very basic +documentation of the IPv6-related options. More documentation can be +found on http://www.greenie.net/ipv6/openvpn.html. +.TP +.B --ifconfig-ipv6 ipv6addr/bits ipv6remote +configure IPv6 address +.B ipv6addr/bits +on the ``tun'' device. The second parameter is used as route target for +.B --route-ipv6 +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 +.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 +and +.B --push tun-ipv6 +Is only accepted if ``--mode server'' or ``--server'' is set. +.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. +.TP +.B --ifconfig-ipv6-push ipv6addr/bits ipv6remote +for ccd/ per-client static IPv6 interface configuration, see +.B --client-config-dir +and +.B --ifconfig-push +for more details. +.TP +.B --iroute-ipv6 ipv6addr/bits +for ccd/ per-client static IPv6 route configuration, see +.B --iroute +for more details how to setup and use this, and how +.B --iroute +and +.B --route +interact. + +.\"********************************************************* .SH SCRIPTING AND ENVIRONMENTAL VARIABLES OpenVPN exports a series of environmental variables for use by user-defined scripts. @@ -4982,6 +5349,10 @@ as defined by the option. .\"********************************************************* .TP +.B \-\-route-pre-down +Executed right before the routes are removed. +.\"********************************************************* +.TP .B \-\-client-disconnect Executed in .B \-\-mode server @@ -5163,6 +5534,49 @@ normally occurs prior to script execution. .\"********************************************************* .TP +.B ifconfig_ipv6_local +The local VPN endpoint IPv6 address specified in the +.B \-\-ifconfig-ipv6 +option (first parameter). +Set prior to OpenVPN calling the +.I ifconfig +or +.I netsh +(windows version of ifconfig) commands which +normally occurs prior to +.B \-\-up +script execution. +.\"********************************************************* +.TP +.B ifconfig_ipv6_netbits +The prefix length of the IPv6 network on the VPN interface. Derived from +the /nnn parameter of the IPv6 address in the +.B \-\-ifconfig-ipv6 +option (first parameter). +Set prior to OpenVPN calling the +.I ifconfig +or +.I netsh +(windows version of ifconfig) commands which +normally occurs prior to +.B \-\-up +script execution. +.\"********************************************************* +.TP +.B ifconfig_ipv6_remote +The remote VPN endpoint IPv6 address specified in the +.B \-\-ifconfig-ipv6 +option (second parameter). +Set prior to OpenVPN calling the +.I ifconfig +or +.I netsh +(windows version of ifconfig) commands which +normally occurs prior to +.B \-\-up +script execution. +.\"********************************************************* +.TP .B ifconfig_local The local VPN endpoint IP address specified in the .B \-\-ifconfig @@ -5362,6 +5776,26 @@ than their names as denoted on the command line or configuration file. .\"********************************************************* .TP +.B route_ipv6_{parm}_{n} +A set of variables which define each IPv6 route to be added, and +are set prior to +.B \-\-up +script execution. + +.B parm +will be one of "network" or "gateway" ("netmask" is contained as "/nnn" +in the route_ipv6_network_{n}, unlike IPv4 where it is passed in a separate +environment variable). + +.B n +is the OpenVPN route number, starting from 1. + +If the network or gateway are resolvable DNS names, +their IP address translations will be recorded rather +than their names as denoted on the command line +or configuration file. +.\"********************************************************* +.TP .B peer_cert Temporary file name containing the client certificate upon connection. Useful in conjunction with --tls-verify @@ -5381,6 +5815,7 @@ script being run. It can be one of the following: .B client-connect, client-disconnect, or .B learn-address. +Set prior to execution of any script. .\"********************************************************* .TP .B signal @@ -5463,13 +5898,16 @@ or script execution. .\"********************************************************* .TP -.B trusted_ip +.B trusted_ip (or trusted_ip6) Actual IP address of connecting client or peer which has been authenticated. Set prior to execution of .B \-\-ipchange, \-\-client-connect, and .B \-\-client-disconnect scripts. +If using ipv6 endpoints (udp6, tcp6), +.B trusted_ip6 +will be set instead. .\"********************************************************* .TP .B trusted_port @@ -5481,7 +5919,7 @@ and scripts. .\"********************************************************* .TP -.B untrusted_ip +.B untrusted_ip (or untrusted_ip6) Actual IP address of connecting client or peer which has not been authenticated yet. Sometimes used to .B nmap @@ -5493,6 +5931,9 @@ Set prior to execution of and .B \-\-auth-user-pass-verify scripts. +If using ipv6 endpoints (udp6, tcp6), +.B untrusted_ip6 +will be set instead. .\"********************************************************* .TP .B untrusted_port @@ -5549,6 +5990,37 @@ X509_1_C=KG .ft .fi .\"********************************************************* +.SH INLINE FILE SUPPORT +OpenVPN allows including files in the main configuration for the +.B \-\-ca, \-\-cert, \-\-dh, \-\-extra-certs, \-\-key, \-\-pkcs12, \-\-secret +and +.B \-\-tls-auth +options. + +Each inline file started by the line +.B <option> +and ended by the line +.B </option> + +Here is an example of an inline file usage + +.nf +.ft 3 +.in +4 +<cert> +-----BEGIN CERTIFICATE----- +[...] +-----END CERTIFICATE----- +</cert> +.in -4 +.ft +.fi + +When using the inline file feature with +.B \-\-pkcs12 +the inline file has to be base64 encoded. Encoding of a .p12 file into base64 can be done for example with OpenSSL by running +.B openssl base64 -in input.p12 + .SH SIGNALS .TP .B SIGHUP @@ -5847,7 +6319,7 @@ access any machine on the 10.0.1.0/24 subnet over the secure tunnel (or vice versa). In a production environment, you could put the route command(s) -in a shell script and execute with the +in a script and execute with the .B \-\-up option. .\"********************************************************* diff --git a/doclean b/doclean deleted file mode 100755 index 8b35dd6..0000000 --- a/doclean +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -# Let's have a fresh start. Remove all -# generated files. -# -# Run this script, then: -# autoreconf -i -v -# ./configure -# make -# make install - -if ! [ "$KEEPAUTODEFS" = "yes" ]; then - rm -rf autodefs -fi - -rm -f \ - *.o \ - service-win32/*.o \ - service-win32/*.exe \ - *.exe \ - openvpn \ - config.cache \ - configure \ - Makefile \ - Makefile.in \ - stamp-h* \ - config.guess \ - config.sub \ - depcomp \ - missing \ - mkinstalldirs \ - config.log \ - config.status \ - config.h \ - config.h.in \ - aclocal.m4 \ - openvpn.spec \ - install-sh \ - openvpn.8.html \ - install-win32/*.exe \ - install-win32/makensis.log \ - install-win32/settings \ - install-win32/Makefile \ - install-win32/Makefile.in \ - images/Makefile \ - images/Makefile.in \ - service-win32/Makefile \ - service-win32/Makefile.in - -rm -rf \ - autom4te*.cache \ - .deps \ - */.deps \ - windest \ - gen \ - tapinstall \ - install-win32/tmp - -rm -rf \ - tap-win32/objfre_w2k_x86 \ - tap-win32/dist \ - tap-win32/SOURCES \ - tap-win32/tapdrvr.cod \ - tap-win32/buildfre_wnet_amd64.wrn \ - tap-win32/buildfre_w2k_x86.wrn \ - tap-win32/objfre_wnet_amd64 \ - tap-win32/buildfre_wnet_amd64.log \ - tap-win32/buildfre_w2k_x86.log \ - tap-win32/amd64 \ - tap-win32/i386/tap0901.pdb \ - tap-win32/i386/OemWin2k.inf \ - tap-win32/i386/tap0901.map \ - tap-win32/i386/tap0901.sys diff --git a/domake-win b/domake-win deleted file mode 100644 index bd730e0..0000000 --- a/domake-win +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/sh - -# This is the master OpenVPN build script for Windows. -# This script will build OpenVPN, the TAP driver, and -# the installer from source, targeting x86 on Windows -# 2000 and higher, and x64 on Windows 2003 and higher. -# For quick start options, see pre-built notes below. -# -# Note that if you are only looking to build the -# openvpn user-space binaries (openvpn.exe -# and openvpnserv.exe) you can use the -# provided autoconf/automake build environment. -# -# If you are building from an expanded .tar.gz file, -# make sure to run "./doclean" before "./domake-win". -# -# See top-level build configuration and settings in: -# -# version.m4 -# install-win32/settings.in -# -# Mandatory prerequisites: -# -# MinGW -- for GNU C compiler -# MSYS -- for bash -# msysDTK -- for perl -# NSIS -- for building installer -# -# The following additional prerequisites may be omitted -# when building in pre-built mode (see note below). -# -# svn -- for checking out source code (or TortoiseSVN) -# Windows Driver Kit (6001_17121_HyperV_WDK.iso) -- for building -# TAP driver + tapinstall -# -# Required libraries (must be prebuilt) -# -# OpenSSL -- define OPENSSL_DIR in settings.in -# LZO -- define LZO_DIR in settings.in -# PKCS11-HELPER -- define PKCS11_HELPER_DIR -# -# Optional OpenVPN GUI binary (prebuilt) -# -- define OPENVPN_GUI_DIR and OPENVPN_GUI in settings.in -# -# Required source code not included in OpenVPN SVN repository -# because of MS licensing restrictions: -# -# ../tapinstall -- This is based on 'devcon' which is found in the -# Windows Driver Kit (formerly known as DDK). -# Copy the 'devcon' source tree to ../tapinstall -# Edit 'sources' and modify TARGETNAME=tapinstall - -# Note that all variables referenced here such as GENOUT, -# GENOUT_PREBUILT, and CLEAN are defined in install-win32/settings.in - -# SPECIAL NOTES ON PRE-BUILT MODE -# Setting up a complete tool chain to build OpenVPN and all -# dependencies on Windows can be an onerous task, so the capability -# is provided to reference a directory of pre-built components during -# the build process. When dependencies are missing to build a given -# component (such as the TAP driver), the build script will auto-detect -# this and use the pre-built version instead. This would allow you, for -# example, to build an OpenVPN installer with custom edits to -# install-win32/settings.in, but then avoid needing to build all other -# components (such as OpenSSL, LZO, Pkcs11-helper, TAP driver, Windows -# service, etc.). The procedure is as follows. First Download and expand -# the pre-built binaries from: -# -# http://openvpn.net/prebuilt/ (choose the most recent -prebuilt .tbz file) -# -# After expanding the .tbz file, cd to the top level directory and -# expand an OpenVPN source distribution taken from either the subversion -# repository or a source .tar.gz file. It's best to use an OpenVPN source -# version that is the same or slightly later than the pre-built binaries -# file. So now you have a directory containing something that looks like -# this: -# -# gen-prebuilt -> from prebuilt .tbz file -# lzo-2.02 -> from prebuilt .tbz file -# openssl-0.9.8i -> from prebuilt .tbz file -# pkcs11-helper -> from prebuilt .tbz file -# openvpn-2.1_rc13.tar.gz -> downloaded from openvpn.net -# openvpn-2.1_rc13 -> directory expanded from above file -# -# Now cd to your expanded source tree (openvpn-2.1_rc13 in the -# example above), make edits to install-win32/settings.in (or even -# patch the OpenVPN source code directly), and run this script: -# -# ./domake-win -# -# If everything runs correctly, you should have a custom installer -# written to ./gen/install - -# First build the autodefs directory, containing C, sh, and NSIS versions -# of global settings, using install-win32/settings.in as source. -# These settings will then drive the rest of the build process. -install-win32/winconfig - -# clean all generated files -install-win32/doclean - -# Load a pre-built GENOUT directory if GENOUT_PREBUILT is defined -# and the GENOUT directory is non-existing -install-win32/getprebuilt - -# Each of the scripts below build, get, and/or possibly sign a different -# OpenVPN component, placing the generated files in GENOUT. Each of these -# steps is fully indepedent, and can be executed in any order or omitted. -# The exception is the last script which gathers together all files from -# GENOUT and builds the installer. - -# Make the OpenVPN user-space components (OpenVPN and service) -install-win32/makeopenvpn - -# Make the OpenVPN TAP driver -install-win32/maketap - -# Make the tapinstall utility, used to install the TAP driver -install-win32/maketapinstall - -# Get the OpenSSL libraries from a pre-build OpenSSL tree -install-win32/getopenssl - -# Get the PKCS-11 helper library from a pre-built OpenSSL tree -install-win32/getpkcs11helper - -# Get the OpenVPN GUI (must be prebuilt) -install-win32/getgui - -# Get the OpenVPN XML-based GUI (must be prebuilt) -install-win32/getxgui - -# Produce the license text, install README, and sample config files -install-win32/maketext - -# This final step builds the OpenVPN installer using generated -# files from GENOUT -install-win32/buildinstaller diff --git a/easy-rsa/1.0/README b/easy-rsa/1.0/README deleted file mode 100644 index fd424ef..0000000 --- a/easy-rsa/1.0/README +++ /dev/null @@ -1,161 +0,0 @@ -This is a small RSA key management package, -based on the openssl command line tool, that -can be found in the easy-rsa subdirectory -of the OpenVPN distribution. - -These are reference notes. For step -by step instructions, see the HOWTO: - -http://openvpn.net/howto.html - -INSTALL - -1. Edit vars. -2. Set KEY_CONFIG to point to the openssl.cnf file - included in this distribution. -3. Set KEY_DIR to point to a directory which will - contain all keys, certificates, etc. This - directory need not exist, and if it does, - it will be deleted with rm -rf, so BE - CAREFUL how you set KEY_DIR. -4. (Optional) Edit other fields in vars - per your site data. You may want to - increase KEY_SIZE to 2048 if you are - paranoid and don't mind slower key - processing, but certainly 1024 is - fine for testing purposes. KEY_SIZE - must be compatible across both peers - participating in a secure SSL/TLS - connection. -5 . vars -6. ./clean-all -7. As you create certificates, keys, and - certificate signing requests, understand that - only .key files should be kept confidential. - .crt and .csr files can be sent over insecure - channels such as plaintext email. -8. You should never need to copy a .key file - between computers. Normally each computer - will have its own certificate/key pair. - -BUILD YOUR OWN ROOT CERTIFICATE AUTHORITY (CA) CERTIFICATE/KEY - -1. ./build-ca -2. ca.crt and ca.key will be built in your KEY_DIR - directory - -BUILD AN INTERMEDIATE CERTIFICATE AUTHORITY CERTIFICATE/KEY (optional) - -1. ./build-inter inter -2. inter.crt and inter.key will be built in your KEY_DIR - directory and signed with your root certificate. - -BUILD DIFFIE-HELLMAN PARAMETERS (necessary for -the server end of a SSL/TLS connection). - -1. ./build-dh - -BUILD A CERTIFICATE SIGNING REQUEST (If -you want to sign your certificate with a root -certificate controlled by another individual -or organization, or residing on a different machine). - -1. Get ca.crt (the root certificate) from your - certificate authority. Though this - transfer can be over an insecure channel, to prevent - man-in-the-middle attacks you must confirm that - ca.crt was not tampered with. Large CAs solve this - problem by hardwiring their root certificates into - popular web browsers. A simple way to verify a root - CA is to call the issuer on the telephone and confirm - that the md5sum or sha1sum signatures on the ca.crt - files match (such as with the command: "md5sum ca.crt"). -2. Choose a name for your certificate such as your computer - name. In our example we will use "mycert". -3. ./build-req mycert -4. You can ignore most of the fields, but set - "Common Name" to something unique such as your - computer's host name. Leave all password - fields blank, unless you want your private key - to be protected by password. Using a password - is not required -- it will make your key more secure - but also more inconvenient to use, because you will - need to supply your password anytime the key is used. - NOTE: if you are using a password, use ./build-req-pass - instead of ./build-req -5. Your key will be written to $KEY_DIR/mycert.key -6. Your certificate signing request will be written to - to $KEY_DIR/mycert.csr -7. Email mycert.csr to the individual or organization - which controls the root certificate. This can be - done over an insecure channel. -8. After the .csr file is signed by the root certificate - authority, you will receive a file mycert.crt - (your certificate). Place mycert.crt in your - KEY_DIR directory. -9. The combined files of mycert.crt, mycert.key, - and ca.crt can now be used to secure one end of - an SSL/TLS connection. - -SIGN A CERTIFICATE SIGNING REQUEST - -1. ./sign-req mycert -2. mycert.crt will be built in your KEY_DIR - directory using mycert.csr and your root CA - file as input. - -BUILD AND SIGN A CERTIFICATE SIGNING REQUEST -USING A LOCALLY INSTALLED ROOT CERTIFICATE/KEY -- this -script generates and signs a certificate in one step, -but it requires that the generated certificate and private -key files be copied to the destination host over a -secure channel. - -1. ./build-key mycert (no password protection) -2. OR ./build-key-pass mycert (with password protection) -3. OR ./build-key-pkcs12 mycert (PKCS #12 format) -4. OR ./build-key-server mycert (with nsCertType=server) -5. mycert.crt and mycert.key will be built in your - KEY_DIR directory, and mycert.crt will be signed - by your root CA. If ./build-key-pkcs12 was used a - mycert.p12 file will also be created including the - private key, certificate and the ca certificate. - -IMPORTANT - -To avoid a possible Man-in-the-Middle attack where an authorized -client tries to connect to another client by impersonating the -server, make sure to enforce some kind of server certificate -verification by clients. There are currently four different ways -of accomplishing this, listed in the order of preference: - -(1) Build your server certificates with the build-key-server - script. This will designate the certificate as a - server-only certificate by setting nsCertType=server. - Now add the following line to your client configuration: - - ns-cert-type server - - This will block clients from connecting to any - server which lacks the nsCertType=server designation - in its certificate, even if the certificate has been - signed by the CA which is cited in the OpenVPN configuration - file (--ca directive). - -(2) Use the --tls-remote directive on the client to - accept/reject the server connection based on the common - name of the server certificate. - -(3) Use a --tls-verify script or plugin to accept/reject the - server connection based on a custom test of the server - certificate's embedded X509 subject details. - -(4) Sign server certificates with one CA and client certificates - with a different CA. The client config "ca" directive should - reference the server-signing CA while the server config "ca" - directive should reference the client-signing CA. - -NOTES - -Show certificate fields: - openssl x509 -in cert.crt -text diff --git a/easy-rsa/1.0/build-ca b/easy-rsa/1.0/build-ca deleted file mode 100755 index 5ad59cc..0000000 --- a/easy-rsa/1.0/build-ca +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# -# Build a root certificate -# - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt -config $KEY_CONFIG && \ - chmod 0600 ca.key -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-dh b/easy-rsa/1.0/build-dh deleted file mode 100755 index 6de4baf..0000000 --- a/easy-rsa/1.0/build-dh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# -# Build Diffie-Hellman parameters for the server side -# of an SSL/TLS connection. -# - -if test $KEY_DIR; then - openssl dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE} -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-inter b/easy-rsa/1.0/build-inter deleted file mode 100755 index 8b3a6b2..0000000 --- a/easy-rsa/1.0/build-inter +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# -# Make an intermediate CA certificate/private key pair using a locally generated -# root certificate. -# - -if test $# -ne 1; then - echo "usage: build-inter <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \ - openssl ca -extensions v3_ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-key b/easy-rsa/1.0/build-key deleted file mode 100755 index 3159d2b..0000000 --- a/easy-rsa/1.0/build-key +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -# -# Make a certificate/private key pair using a locally generated -# root certificate. -# - -if test $# -ne 1; then - echo "usage: build-key <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \ - openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \ - chmod 0600 $1.key -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-key-pass b/easy-rsa/1.0/build-key-pass deleted file mode 100755 index 03ab304..0000000 --- a/easy-rsa/1.0/build-key-pass +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -# -# Similar to build-key, but protect the private key -# with a password. -# - -if test $# -ne 1; then - echo "usage: build-key-pass <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \ - openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \ - chmod 0600 $1.key -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-key-pkcs12 b/easy-rsa/1.0/build-key-pkcs12 deleted file mode 100755 index f8a057b..0000000 --- a/easy-rsa/1.0/build-key-pkcs12 +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# -# Make a certificate/private key pair using a locally generated -# root certificate and convert it to a PKCS #12 file including the -# the CA certificate as well. - -if test $# -ne 1; then - echo "usage: build-key-pkcs12 <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \ - openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \ - openssl pkcs12 -export -inkey $1.key -in $1.crt -certfile ca.crt -out $1.p12 && \ - chmod 0600 $1.key $1.p12 -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-key-server b/easy-rsa/1.0/build-key-server deleted file mode 100755 index 30dc41e..0000000 --- a/easy-rsa/1.0/build-key-server +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# -# Make a certificate/private key pair using a locally generated -# root certificate. -# -# Explicitly set nsCertType to server using the "server" -# extension in the openssl.cnf file. - -if test $# -ne 1; then - echo "usage: build-key-server <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -extensions server -config $KEY_CONFIG && \ - openssl ca -days 3650 -out $1.crt -in $1.csr -extensions server -config $KEY_CONFIG && \ - chmod 0600 $1.key -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-req b/easy-rsa/1.0/build-req deleted file mode 100755 index 30f62f5..0000000 --- a/easy-rsa/1.0/build-req +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# Build a certificate signing request and private key. Use this -# when your root certificate and key is not available locally. -# - -if test $# -ne 1; then - echo "usage: build-req <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/build-req-pass b/easy-rsa/1.0/build-req-pass deleted file mode 100755 index 829b286..0000000 --- a/easy-rsa/1.0/build-req-pass +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# Like build-req, but protect your private key -# with a password. -# - -if test $# -ne 1; then - echo "usage: build-req-pass <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl req -days 3650 -new -keyout $1.key -out $1.csr -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/clean-all b/easy-rsa/1.0/clean-all deleted file mode 100755 index d10aef5..0000000 --- a/easy-rsa/1.0/clean-all +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# -# Initialize the $KEY_DIR directory. -# Note that this script does a -# rm -rf on $KEY_DIR so be careful! -# - -d=$KEY_DIR - -if test $d; then - rm -rf $d - mkdir $d && \ - chmod go-rwx $d && \ - touch $d/index.txt && \ - echo 01 >$d/serial -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/list-crl b/easy-rsa/1.0/list-crl deleted file mode 100644 index b214dbd..0000000 --- a/easy-rsa/1.0/list-crl +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# list revoked certificates -# -# - -if test $# -ne 1; then - echo "usage: list-crl <crlfile.pem>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl crl -text -noout -in $1 -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/make-crl b/easy-rsa/1.0/make-crl deleted file mode 100644 index 62fe6c1..0000000 --- a/easy-rsa/1.0/make-crl +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# generate a CRL -# -# - -if test $# -ne 1; then - echo "usage: make-crl <crlfile.pem>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl ca -gencrl -out $1 -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/openssl.cnf b/easy-rsa/1.0/openssl.cnf deleted file mode 100644 index 270b069..0000000 --- a/easy-rsa/1.0/openssl.cnf +++ /dev/null @@ -1,255 +0,0 @@ -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd - -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_match - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "OpenSSL Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always diff --git a/easy-rsa/1.0/revoke-crt b/easy-rsa/1.0/revoke-crt deleted file mode 100644 index 35b071a..0000000 --- a/easy-rsa/1.0/revoke-crt +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# revoke a certificate -# -# - -if test $# -ne 1; then - echo "usage: revoke-crt <file.crt>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl ca -revoke $1 -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/revoke-full b/easy-rsa/1.0/revoke-full deleted file mode 100755 index 66ea03f..0000000 --- a/easy-rsa/1.0/revoke-full +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# revoke a certificate, regenerate CRL, -# and verify revocation - -CRL=crl.pem -RT=revoke-test.pem - -if test $# -ne 1; then - echo "usage: revoke-full <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR - rm -f $RT - - # revoke key and generate a new CRL - openssl ca -revoke $1.crt -config $KEY_CONFIG - - # generate a new CRL - openssl ca -gencrl -out $CRL -config $KEY_CONFIG - cat ca.crt $CRL >$RT - - # verify the revocation - openssl verify -CAfile $RT -crl_check $1.crt -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/sign-req b/easy-rsa/1.0/sign-req deleted file mode 100755 index 59edc42..0000000 --- a/easy-rsa/1.0/sign-req +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# -# Sign a certificate signing request (a .csr file) -# with a local root certificate and key. -# - -if test $# -ne 1; then - echo "usage: sign-req <name>"; - exit 1 -fi - -if test $KEY_DIR; then - cd $KEY_DIR && \ - openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG -else - echo you must define KEY_DIR -fi diff --git a/easy-rsa/1.0/vars b/easy-rsa/1.0/vars deleted file mode 100644 index da89cd2..0000000 --- a/easy-rsa/1.0/vars +++ /dev/null @@ -1,49 +0,0 @@ -# easy-rsa parameter settings - -# NOTE: If you installed from an RPM, -# don't edit this file in place in -# /usr/share/openvpn/easy-rsa -- -# instead, you should copy the whole -# easy-rsa directory to another location -# (such as /etc/openvpn) so that your -# edits will not be wiped out by a future -# OpenVPN package upgrade. - -# This variable should point to -# the top level of the easy-rsa -# tree. -export D=`pwd` - -# This variable should point to -# the openssl.cnf file included -# with easy-rsa. -export KEY_CONFIG=$D/openssl.cnf - -# Edit this variable to point to -# your soon-to-be-created key -# directory. -# -# WARNING: clean-all will do -# a rm -rf on this directory -# so make sure you define -# it correctly! -export KEY_DIR=$D/keys - -# Issue rm -rf warning -echo NOTE: when you run ./clean-all, I will be doing a rm -rf on $KEY_DIR - -# Increase this to 2048 if you -# are paranoid. This will slow -# down TLS negotiation performance -# as well as the one-time DH parms -# generation process. -export KEY_SIZE=1024 - -# These are the default values for fields -# which will be placed in the certificate. -# Don't leave any of these fields blank. -export KEY_COUNTRY=KG -export KEY_PROVINCE=NA -export KEY_CITY=BISHKEK -export KEY_ORG="OpenVPN-TEST" -export KEY_EMAIL="me@myhost.mydomain" diff --git a/easy-rsa/2.0/Makefile b/easy-rsa/2.0/Makefile deleted file mode 100644 index 8000cc5..0000000 --- a/easy-rsa/2.0/Makefile +++ /dev/null @@ -1,13 +0,0 @@ - -DESTDIR= -PREFIX= - -all: - echo "All done." - echo "Run make install DESTDIR=/usr/share/somewhere" - -install: - install -d "${DESTDIR}/${PREFIX}" - install -m 0755 build-* "${DESTDIR}/${PREFIX}" - install -m 0755 clean-all list-crl inherit-inter pkitool revoke-full sign-req whichopensslcnf "${DESTDIR}/${PREFIX}" - install -m 0644 openssl-0.9.6.cnf openssl-0.9.8.cnf openssl-1.0.0.cnf README vars "${DESTDIR}/${PREFIX}" diff --git a/easy-rsa/2.0/README b/easy-rsa/2.0/README deleted file mode 100644 index 6f5395c..0000000 --- a/easy-rsa/2.0/README +++ /dev/null @@ -1,229 +0,0 @@ -EASY-RSA Version 2.0-rc1 - -This is a small RSA key management package, based on the openssl -command line tool, that can be found in the easy-rsa subdirectory -of the OpenVPN distribution. While this tool is primary concerned -with key management for the SSL VPN application space, it can also -be used for building web certificates. - -These are reference notes. For step-by-step instructions, see the -HOWTO: - -http://openvpn.net/howto.html - -This package is based on the ./pkitool script. Run ./pkitool -without arguments for a detailed help message (which is also pasted -below). - -Release Notes for easy-rsa-2.0 - -* Most functionality has been consolidated into the pkitool - script. For compatibility, all previous scripts from 1.0 such - as build-key and build-key-server are provided as stubs - which call pkitool to do the real work. - -* pkitool has a --batch flag (enabled by default) which generates - keys/certs without needing any interactive input. pkitool - can still generate certs/keys using interactive prompting by - using the --interact flag. - -* The inherit-inter script has been provided for creating - a new PKI rooted on an intermediate certificate built within a - higher-level PKI. See comments in the inherit-inter script - for more info. - -* The openssl.cnf file has been modified. pkitool will not - work with the openssl.cnf file included with previous - easy-rsa releases. - -* The vars file has been modified -- the following extra - variables have been added: EASY_RSA, CA_EXPIRE, - KEY_EXPIRE. - -* The make-crl and revoke-crt scripts have been removed and - are replaced by the revoke-full script. - -* The "Organizational Unit" X509 field can be set using - the KEY_OU environmental variable before calling pkitool. - -* This release only affects the Linux/Unix version of easy-rsa. - The Windows version (written to use the Windows shell) is unchanged. - -* Use the revoke-full script to revoke a certificate, and generate - (or update) the crl.pem file in the keys directory (as set by the - vars script). Then use "crl-verify crl.pem" in your OpenVPN server - config file, so that OpenVPN can reject any connections coming from - clients which present a revoked certificate. Usage for the script is: - - revoke-full <common-name> - - Note this this procedure is primarily designed to revoke client - certificates. You could theoretically use this method to revoke - server certificates as well, but then you would need to propagate - the crl.pem file to all clients as well, and have them include - "crl-verify crl.pem" in their configuration files. - -* PKCS#11 support was added. - -* For those interested in using this tool to generate web certificates, - A variant of the easy-rsa package that allows the creation of multi-domain - certificates with subjectAltName can be obtained from here: - - http://www.bisente.com/proyectos/easy-rsa-subjectaltname/ - -INSTALL easy-rsa - -1. Edit vars. -2. Set KEY_CONFIG to point to the correct openssl-<version>.cnf - file included in this distribution. -3. Set KEY_DIR to point to a directory which will - contain all keys, certificates, etc. This - directory need not exist, and if it does, - it will be deleted with rm -rf, so BE - CAREFUL how you set KEY_DIR. -4. (Optional) Edit other fields in vars - per your site data. You may want to - increase KEY_SIZE to 2048 if you are - paranoid and don't mind slower key - processing, but certainly 1024 is - fine for testing purposes. KEY_SIZE - must be compatible across both peers - participating in a secure SSL/TLS - connection. -5. (Optional) If you intend to use PKCS#11, - install openssl >= 0.9.7, install the - following components from www.opensc.org: - - opensc >= 0.10.0 - - engine_pkcs11 >= 0.1.3 - Update the openssl.cnf to load the engine: - - Uncomment pkcs11 under engine_section. - - Validate path at dynamic_path under pkcs11_section. -6. . vars -7. ./clean-all -8. As you create certificates, keys, and - certificate signing requests, understand that - only .key files should be kept confidential. - .crt and .csr files can be sent over insecure - channels such as plaintext email. - -IMPORTANT - -To avoid a possible Man-in-the-Middle attack where an authorized -client tries to connect to another client by impersonating the -server, make sure to enforce some kind of server certificate -verification by clients. There are currently four different ways -of accomplishing this, listed in the order of preference: - -(1) Build your server certificates with specific key usage and - extended key usage. The RFC3280 determine that the following - attributes should be provided for TLS connections: - - Mode Key usage Extended key usage - --------------------------------------------------------------------------- - Client digitalSignature TLS Web Client Authentication - keyAgreement - digitalSignature, keyAgreement - - Server digitalSignature, keyEncipherment TLS Web Server Authentication - digitalSignature, keyAgreement - - Now add the following line to your client configuration: - - remote-cert-tls server - - This will block clients from connecting to any - server which lacks the required extension designation - in its certificate, even if the certificate has been - signed by the CA which is cited in the OpenVPN configuration - file (--ca directive). - -(3) Use the --tls-remote directive on the client to - accept/reject the server connection based on the common - name of the server certificate. - -(3) Use a --tls-verify script or plugin to accept/reject the - server connection based on a custom test of the server - certificate's embedded X509 subject details. - -(4) Sign server certificates with one CA and client certificates - with a different CA. The client config "ca" directive should - reference the server-signing CA while the server config "ca" - directive should reference the client-signing CA. - -NOTES - -Show certificate fields: - openssl x509 -in cert.crt -text - -PKITOOL documentation - -pkitool 2.0 -Usage: pkitool [options...] [common-name] -Options: - --batch : batch mode (default) - --keysize : Set keysize - size : size (default=1024) - --interact : interactive mode - --server : build server cert - --initca : build root CA - --inter : build intermediate CA - --pass : encrypt private key with password - --csr : only generate a CSR, do not sign - --sign : sign an existing CSR - --pkcs12 : generate a combined PKCS#12 file - --pkcs11 : generate certificate on PKCS#11 token - lib : PKCS#11 library - slot : PKCS#11 slot - id : PKCS#11 object id (hex string) - label : PKCS#11 object label -Standalone options: - --pkcs11-slots : list PKCS#11 slots - lib : PKCS#11 library - --pkcs11-objects : list PKCS#11 token objects - lib : PKCS#11 library - slot : PKCS#11 slot - --pkcs11-init : initialize PKCS#11 token DANGEROUS!!! - lib : PKCS#11 library - slot : PKCS#11 slot - label : PKCS#11 token label -Notes: - Please edit the vars script to reflect your configuration, - then source it with "source ./vars". - Next, to start with a fresh PKI configuration and to delete any - previous certificates and keys, run "./clean-all". - Finally, you can run this tool (pkitool) to build certificates/keys. - In order to use PKCS#11 interface you must have opensc-0.10.0 or higher. -Generated files and corresponding OpenVPN directives: -(Files will be placed in the $KEY_DIR directory, defined in ./vars) - ca.crt -> root certificate (--ca) - ca.key -> root key, keep secure (not directly used by OpenVPN) - .crt files -> client/server certificates (--cert) - .key files -> private keys, keep secure (--key) - .csr files -> certificate signing request (not directly used by OpenVPN) - dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh) -Examples: - pkitool --initca -> Build root certificate - pkitool --initca --pass -> Build root certificate with password-protected key - pkitool --server server1 -> Build "server1" certificate/key - pkitool client1 -> Build "client1" certificate/key - pkitool --pass client2 -> Build password-protected "client2" certificate/key - pkitool --pkcs12 client3 -> Build "client3" certificate/key in PKCS#12 format - pkitool --csr client4 -> Build "client4" CSR to be signed by another CA - pkitool --sign client4 -> Sign "client4" CSR - pkitool --inter interca -> Build an intermediate key-signing certificate/key - Also see ./inherit-inter script. - pkitool --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5 - -> Build "client5" certificate/key in PKCS#11 token -Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys. -Protect client2 key with a password. Build DH parms. Generated files in ./keys : - [edit vars with your site-specific info] - source ./vars - ./clean-all - ./build-dh -> takes a long time, consider backgrounding - ./pkitool --initca - ./pkitool --server myserver - ./pkitool client1 - ./pkitool --pass client2 -Typical usage for adding client cert to existing PKI: - source ./vars - ./pkitool client-new diff --git a/easy-rsa/2.0/build-ca b/easy-rsa/2.0/build-ca deleted file mode 100755 index bce29a6..0000000 --- a/easy-rsa/2.0/build-ca +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# -# Build a root certificate -# - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --initca $* diff --git a/easy-rsa/2.0/build-dh b/easy-rsa/2.0/build-dh deleted file mode 100755 index 4beb127..0000000 --- a/easy-rsa/2.0/build-dh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# Build Diffie-Hellman parameters for the server side -# of an SSL/TLS connection. - -if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then - $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE} -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/build-inter b/easy-rsa/2.0/build-inter deleted file mode 100755 index 87bf98d..0000000 --- a/easy-rsa/2.0/build-inter +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Make an intermediate CA certificate/private key pair using a locally generated -# root certificate. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --inter $* diff --git a/easy-rsa/2.0/build-key b/easy-rsa/2.0/build-key deleted file mode 100755 index 6c0fed8..0000000 --- a/easy-rsa/2.0/build-key +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact $* diff --git a/easy-rsa/2.0/build-key-pass b/easy-rsa/2.0/build-key-pass deleted file mode 100755 index 8ef8307..0000000 --- a/easy-rsa/2.0/build-key-pass +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Similar to build-key, but protect the private key -# with a password. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --pass $* diff --git a/easy-rsa/2.0/build-key-pkcs12 b/easy-rsa/2.0/build-key-pkcs12 deleted file mode 100755 index ba90e6a..0000000 --- a/easy-rsa/2.0/build-key-pkcs12 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate and convert it to a PKCS #12 file including the -# the CA certificate as well. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --pkcs12 $* diff --git a/easy-rsa/2.0/build-key-server b/easy-rsa/2.0/build-key-server deleted file mode 100755 index fee0194..0000000 --- a/easy-rsa/2.0/build-key-server +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate. -# -# Explicitly set nsCertType to server using the "server" -# extension in the openssl.cnf file. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --server $* diff --git a/easy-rsa/2.0/build-req b/easy-rsa/2.0/build-req deleted file mode 100755 index 559d512..0000000 --- a/easy-rsa/2.0/build-req +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Build a certificate signing request and private key. Use this -# when your root certificate and key is not available locally. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --csr $* diff --git a/easy-rsa/2.0/build-req-pass b/easy-rsa/2.0/build-req-pass deleted file mode 100755 index b73ee1b..0000000 --- a/easy-rsa/2.0/build-req-pass +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Like build-req, but protect your private key -# with a password. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --csr --pass $* diff --git a/easy-rsa/2.0/clean-all b/easy-rsa/2.0/clean-all deleted file mode 100755 index cc6e3b2..0000000 --- a/easy-rsa/2.0/clean-all +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -# Initialize the $KEY_DIR directory. -# Note that this script does a -# rm -rf on $KEY_DIR so be careful! - -if [ "$KEY_DIR" ]; then - rm -rf "$KEY_DIR" - mkdir "$KEY_DIR" && \ - chmod go-rwx "$KEY_DIR" && \ - touch "$KEY_DIR/index.txt" && \ - echo 01 >"$KEY_DIR/serial" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/inherit-inter b/easy-rsa/2.0/inherit-inter deleted file mode 100755 index aaa5168..0000000 --- a/easy-rsa/2.0/inherit-inter +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# Build a new PKI which is rooted on an intermediate certificate generated -# by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should -# have independent vars settings, and must use a different KEY_DIR directory -# from the parent. This tool can be used to generate arbitrary depth -# certificate chains. -# -# To build an intermediate CA, follow the same steps for a regular PKI but -# replace ./build-key or ./pkitool --initca with this script. - -# The EXPORT_CA file will contain the CA certificate chain and should be -# referenced by the OpenVPN "ca" directive in config files. The ca.crt file -# will only contain the local intermediate CA -- it's needed by the easy-rsa -# scripts but not by OpenVPN directly. -EXPORT_CA="export-ca.crt" - -if [ $# -ne 2 ]; then - echo "usage: $0 <parent-key-dir> <common-name>" - echo "parent-key-dir: the KEY_DIR directory of the parent PKI" - echo "common-name: the common name of the intermediate certificate in the parent PKI" - exit 1; -fi - -if [ "$KEY_DIR" ]; then - cp "$1/$2.crt" "$KEY_DIR/ca.crt" - cp "$1/$2.key" "$KEY_DIR/ca.key" - - if [ -e "$1/$EXPORT_CA" ]; then - PARENT_CA="$1/$EXPORT_CA" - else - PARENT_CA="$1/ca.crt" - fi - cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA" - cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/list-crl b/easy-rsa/2.0/list-crl deleted file mode 100755 index d1d8a69..0000000 --- a/easy-rsa/2.0/list-crl +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# list revoked certificates - -CRL="${1:-crl.pem}" - -if [ "$KEY_DIR" ]; then - cd "$KEY_DIR" && \ - $OPENSSL crl -text -noout -in "$CRL" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/openssl-0.9.6.cnf b/easy-rsa/2.0/openssl-0.9.6.cnf deleted file mode 100755 index d28341d..0000000 --- a/easy-rsa/2.0/openssl-0.9.6.cnf +++ /dev/null @@ -1,265 +0,0 @@ -# For use with easy-rsa version 2.0 - -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd - -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always diff --git a/easy-rsa/2.0/openssl-0.9.8.cnf b/easy-rsa/2.0/openssl-0.9.8.cnf deleted file mode 100755 index 340b8af..0000000 --- a/easy-rsa/2.0/openssl-0.9.8.cnf +++ /dev/null @@ -1,290 +0,0 @@ -# For use with easy-rsa version 2.0 - -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd -openssl_conf = openssl_init - -[ openssl_init ] -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids -engines = engine_section - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -name = Name -name_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN -name_default = $ENV::KEY_NAME - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always - -[ engine_section ] -# -# If you are using PKCS#11 -# Install engine_pkcs11 of opensc (www.opensc.org) -# And uncomment the following -# verify that dynamic_path points to the correct location -# -#pkcs11 = pkcs11_section - -[ pkcs11_section ] -engine_id = pkcs11 -dynamic_path = /usr/lib/engines/engine_pkcs11.so -MODULE_PATH = $ENV::PKCS11_MODULE_PATH -PIN = $ENV::PKCS11_PIN -init = 0 diff --git a/easy-rsa/2.0/openssl-1.0.0.cnf b/easy-rsa/2.0/openssl-1.0.0.cnf deleted file mode 100755 index fa258a5..0000000 --- a/easy-rsa/2.0/openssl-1.0.0.cnf +++ /dev/null @@ -1,285 +0,0 @@ -# For use with easy-rsa version 2.0 and OpenSSL 1.0.0* - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd -openssl_conf = openssl_init - -[ openssl_init ] -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids -engines = engine_section - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # use public key default MD -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString (PKIX recommendation after 2004). -# utf8only: only UTF8Strings (PKIX recommendation after 2004). -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -name = Name -name_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN -name_default = $ENV::KEY_NAME - - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always - -[ engine_section ] -# -# If you are using PKCS#11 -# Install engine_pkcs11 of opensc (www.opensc.org) -# And uncomment the following -# verify that dynamic_path points to the correct location -# -#pkcs11 = pkcs11_section - -[ pkcs11_section ] -engine_id = pkcs11 -dynamic_path = /usr/lib/engines/engine_pkcs11.so -MODULE_PATH = $ENV::PKCS11_MODULE_PATH -PIN = $ENV::PKCS11_PIN -init = 0 diff --git a/easy-rsa/2.0/openssl-1.0.0.cnf-old-copy b/easy-rsa/2.0/openssl-1.0.0.cnf-old-copy deleted file mode 100644 index da425aa..0000000 --- a/easy-rsa/2.0/openssl-1.0.0.cnf-old-copy +++ /dev/null @@ -1,285 +0,0 @@ -# For use with easy-rsa version 2.0 and OpenSSL 1.0.0* - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd -openssl_conf = openssl_init - -[ openssl_init ] -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids -engines = engine_section - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # use public key default MD -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString (PKIX recommendation after 2004). -# utf8only: only UTF8Strings (PKIX recommendation after 2004). -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -name = Name -name_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN -name_default = $ENV::KEY_NAME - - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always - -[ engine_section ] -# -# If you are using PKCS#11 -# Install engine_pkcs11 of opensc (www.opensc.org) -# And uncomment the following -# verify that dynamic_path points to the correct location -# -#pkcs11 = pkcs11_section - -[ pkcs11_section ] -engine_id = pkcs11 -dynamic_path = /usr/lib/engines/engine_pkcs11.so -MODULE_PATH = $ENV::PKCS11_MODULE_PATH -PIN = $ENV::PKCS11_PIN -init = 0 diff --git a/easy-rsa/2.0/pkitool b/easy-rsa/2.0/pkitool deleted file mode 100755 index 49588f5..0000000 --- a/easy-rsa/2.0/pkitool +++ /dev/null @@ -1,379 +0,0 @@ -#!/bin/sh - -# 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 - -# pkitool is a front-end for the openssl tool. - -# Calling scripts can set the certificate organizational -# unit with the KEY_OU environmental variable. - -# Calling scripts can also set the KEY_NAME environmental -# variable to set the "name" X509 subject field. - -PROGNAME=pkitool -VERSION=2.0 -DEBUG=0 - -die() -{ - local m="$1" - - echo "$m" >&2 - exit 1 -} - -need_vars() -{ - echo ' Please edit the vars script to reflect your configuration,' - echo ' then source it with "source ./vars".' - echo ' Next, to start with a fresh PKI configuration and to delete any' - echo ' previous certificates and keys, run "./clean-all".' - echo " Finally, you can run this tool ($PROGNAME) to build certificates/keys." -} - -usage() -{ - echo "$PROGNAME $VERSION" - echo "Usage: $PROGNAME [options...] [common-name]" - echo "Options:" - echo " --batch : batch mode (default)" - echo " --keysize : Set keysize" - echo " size : size (default=1024)" - echo " --interact : interactive mode" - echo " --server : build server cert" - echo " --initca : build root CA" - echo " --inter : build intermediate CA" - echo " --pass : encrypt private key with password" - echo " --csr : only generate a CSR, do not sign" - echo " --sign : sign an existing CSR" - echo " --pkcs12 : generate a combined PKCS#12 file" - echo " --pkcs11 : generate certificate on PKCS#11 token" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " id : PKCS#11 object id (hex string)" - echo " label : PKCS#11 object label" - echo "Standalone options:" - echo " --pkcs11-slots : list PKCS#11 slots" - echo " lib : PKCS#11 library" - echo " --pkcs11-objects : list PKCS#11 token objects" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " --pkcs11-init : initialize PKCS#11 token DANGEROUS!!!" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " label : PKCS#11 token label" - echo "Notes:" - need_vars - echo " In order to use PKCS#11 interface you must have opensc-0.10.0 or higher." - echo "Generated files and corresponding OpenVPN directives:" - echo '(Files will be placed in the $KEY_DIR directory, defined in ./vars)' - echo " ca.crt -> root certificate (--ca)" - echo " ca.key -> root key, keep secure (not directly used by OpenVPN)" - echo " .crt files -> client/server certificates (--cert)" - echo " .key files -> private keys, keep secure (--key)" - echo " .csr files -> certificate signing request (not directly used by OpenVPN)" - echo " dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)" - echo "Examples:" - echo " $PROGNAME --initca -> Build root certificate" - echo " $PROGNAME --initca --pass -> Build root certificate with password-protected key" - echo " $PROGNAME --server server1 -> Build \"server1\" certificate/key" - echo " $PROGNAME client1 -> Build \"client1\" certificate/key" - echo " $PROGNAME --pass client2 -> Build password-protected \"client2\" certificate/key" - echo " $PROGNAME --pkcs12 client3 -> Build \"client3\" certificate/key in PKCS#12 format" - echo " $PROGNAME --csr client4 -> Build \"client4\" CSR to be signed by another CA" - echo " $PROGNAME --sign client4 -> Sign \"client4\" CSR" - echo " $PROGNAME --inter interca -> Build an intermediate key-signing certificate/key" - echo " Also see ./inherit-inter script." - echo " $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 \"client5 id\" client5" - echo " -> Build \"client5\" certificate/key in PKCS#11 token" - echo "Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys." - echo "Protect client2 key with a password. Build DH parms. Generated files in ./keys :" - echo " [edit vars with your site-specific info]" - echo " source ./vars" - echo " ./clean-all" - echo " ./build-dh -> takes a long time, consider backgrounding" - echo " ./$PROGNAME --initca" - echo " ./$PROGNAME --server myserver" - echo " ./$PROGNAME client1" - echo " ./$PROGNAME --pass client2" - echo "Typical usage for adding client cert to existing PKI:" - echo " source ./vars" - echo " ./$PROGNAME client-new" -} - -# Set tool defaults -[ -n "$OPENSSL" ] || export OPENSSL="openssl" -[ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool" -[ -n "$GREP" ] || export GREP="grep" - -# Set defaults -DO_REQ="1" -REQ_EXT="" -DO_CA="1" -CA_EXT="" -DO_P12="0" -DO_P11="0" -DO_ROOT="0" -NODES_REQ="-nodes" -NODES_P12="" -BATCH="-batch" -CA="ca" -# must be set or errors of openssl.cnf -PKCS11_MODULE_PATH="dummy" -PKCS11_PIN="dummy" - -# Process options -while [ $# -gt 0 ]; do - case "$1" in - --keysize ) KEY_SIZE=$2 - shift;; - --server ) REQ_EXT="$REQ_EXT -extensions server" - CA_EXT="$CA_EXT -extensions server" ;; - --batch ) BATCH="-batch" ;; - --interact ) BATCH="" ;; - --inter ) CA_EXT="$CA_EXT -extensions v3_ca" ;; - --initca ) DO_ROOT="1" ;; - --pass ) NODES_REQ="" ;; - --csr ) DO_CA="0" ;; - --sign ) DO_REQ="0" ;; - --pkcs12 ) DO_P12="1" ;; - --pkcs11 ) DO_P11="1" - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - PKCS11_ID="$4" - PKCS11_LABEL="$5" - shift 4;; - - # standalone - --pkcs11-init) - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - PKCS11_LABEL="$4" - if [ -z "$PKCS11_LABEL" ]; then - die "Please specify library name, slot and label" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \ - --label "$PKCS11_LABEL" && - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT" - exit $?;; - --pkcs11-slots) - PKCS11_MODULE_PATH="$2" - if [ -z "$PKCS11_MODULE_PATH" ]; then - die "Please specify library name" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots - exit 0;; - --pkcs11-objects) - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - if [ -z "$PKCS11_SLOT" ]; then - die "Please specify library name and slot" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT" - exit 0;; - - --help|--usage) - usage - exit ;; - --version) - echo "$PROGNAME $VERSION" - exit ;; - # errors - --* ) die "$PROGNAME: unknown option: $1" ;; - * ) break ;; - esac - shift -done - -if ! [ -z "$BATCH" ]; then - if $OPENSSL version | grep 0.9.6 > /dev/null; then - die "Batch mode is unsupported in openssl<0.9.7" - fi -fi - -if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then - die "PKCS#11 and PKCS#12 cannot be specified together" -fi - -if [ $DO_P11 -eq 1 ]; then - if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then - die "Please edit $KEY_CONFIG and setup PKCS#11 engine" - fi -fi - -# If we are generating pkcs12, only encrypt the final step -if [ $DO_P12 -eq 1 ]; then - NODES_P12="$NODES_REQ" - NODES_REQ="-nodes" -fi - -if [ $DO_P11 -eq 1 ]; then - if [ -z "$PKCS11_LABEL" ]; then - die "PKCS#11 arguments incomplete" - fi -fi - -# If undefined, set default key expiration intervals -if [ -z "$KEY_EXPIRE" ]; then - KEY_EXPIRE=3650 -fi -if [ -z "$CA_EXPIRE" ]; then - CA_EXPIRE=3650 -fi - -# Set organizational unit to empty string if undefined -if [ -z "$KEY_OU" ]; then - KEY_OU="" -fi - -# Set X509 Name string to empty string if undefined -if [ -z "$KEY_NAME" ]; then - KEY_NAME="" -fi - -# Set KEY_CN, FN -if [ $DO_ROOT -eq 1 ]; then - if [ -z "$KEY_CN" ]; then - if [ "$1" ]; then - KEY_CN="$1" - elif [ "$KEY_ORG" ]; then - KEY_CN="$KEY_ORG CA" - fi - fi - if [ $BATCH ] && [ "$KEY_CN" ]; then - echo "Using CA Common Name:" "$KEY_CN" - fi - FN="$KEY_CN" -elif [ $BATCH ] && [ "$KEY_CN" ]; then - echo "Using Common Name:" "$KEY_CN" - FN="$KEY_CN" - if [ "$1" ]; then - FN="$1" - fi -else - if [ $# -ne 1 ]; then - usage - exit 1 - else - KEY_CN="$1" - fi - FN="$KEY_CN" -fi - -export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN - -# Show parameters (debugging) -if [ $DEBUG -eq 1 ]; then - echo DO_REQ $DO_REQ - echo REQ_EXT $REQ_EXT - echo DO_CA $DO_CA - echo CA_EXT $CA_EXT - echo NODES_REQ $NODES_REQ - echo NODES_P12 $NODES_P12 - echo DO_P12 $DO_P12 - echo KEY_CN $KEY_CN - echo BATCH $BATCH - echo DO_ROOT $DO_ROOT - echo KEY_EXPIRE $KEY_EXPIRE - echo CA_EXPIRE $CA_EXPIRE - echo KEY_OU $KEY_OU - echo KEY_NAME $KEY_NAME - echo DO_P11 $DO_P11 - echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH - echo PKCS11_SLOT $PKCS11_SLOT - echo PKCS11_ID $PKCS11_ID - echo PKCS11_LABEL $PKCS11_LABEL -fi - -# Make sure ./vars was sourced beforehand -if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then - cd "$KEY_DIR" - - # Make sure $KEY_CONFIG points to the correct version - # of openssl.cnf - if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then - : - else - echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong" - echo "version of openssl.cnf: $KEY_CONFIG" - echo "The correct version should have a comment that says: easy-rsa version 2.x"; - exit 1; - fi - - # Build root CA - if [ $DO_ROOT -eq 1 ]; then - $OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE -sha1 \ - -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \ - chmod 0600 "$CA.key" - else - # Make sure CA key/cert is available - if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then - if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then - echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR" - echo "Try $PROGNAME --initca to build a root certificate/key." - exit 1 - fi - fi - - # Generate key for PKCS#11 token - PKCS11_ARGS= - if [ $DO_P11 -eq 1 ]; then - stty -echo - echo -n "User PIN: " - read -r PKCS11_PIN - stty echo - export PKCS11_PIN - - echo "Generating key pair on PKCS#11 token..." - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \ - --login --pin "$PKCS11_PIN" \ - --key-type rsa:1024 \ - --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1 - PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID" - fi - - # Build cert/key - ( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \ - -keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \ - ( [ $DO_CA -eq 0 ] || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \ - -in "$FN.csr" $CA_EXT -md sha1 -config "$KEY_CONFIG" ) && \ - ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \ - -in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \ - ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ] || chmod 0600 "$FN.key" ) && \ - ( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" ) - - # Load certificate into PKCS#11 token - if [ $DO_P11 -eq 1 ]; then - $OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \ - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \ - --login --pin "$PKCS11_PIN" \ - --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" - [ -e "$FN.crt.der" ]; rm "$FN.crt.der" - fi - - fi - -# Need definitions -else - need_vars -fi diff --git a/easy-rsa/2.0/revoke-full b/easy-rsa/2.0/revoke-full deleted file mode 100755 index 4169c4c..0000000 --- a/easy-rsa/2.0/revoke-full +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -# revoke a certificate, regenerate CRL, -# and verify revocation - -CRL="crl.pem" -RT="revoke-test.pem" - -if [ $# -ne 1 ]; then - echo "usage: revoke-full <cert-name-base>"; - exit 1 -fi - -if [ "$KEY_DIR" ]; then - cd "$KEY_DIR" - rm -f "$RT" - - # set defaults - export KEY_CN="" - export KEY_OU="" - export KEY_NAME="" - - # revoke key and generate a new CRL - $OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG" - - # generate a new CRL -- try to be compatible with - # intermediate PKIs - $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG" - if [ -e export-ca.crt ]; then - cat export-ca.crt "$CRL" >"$RT" - else - cat ca.crt "$CRL" >"$RT" - fi - - # verify the revocation - $OPENSSL verify -CAfile "$RT" -crl_check "$1.crt" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/sign-req b/easy-rsa/2.0/sign-req deleted file mode 100755 index 6cae7b4..0000000 --- a/easy-rsa/2.0/sign-req +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Sign a certificate signing request (a .csr file) -# with a local root certificate and key. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --sign $* diff --git a/easy-rsa/2.0/tmp/README b/easy-rsa/2.0/tmp/README deleted file mode 100644 index 6f5395c..0000000 --- a/easy-rsa/2.0/tmp/README +++ /dev/null @@ -1,229 +0,0 @@ -EASY-RSA Version 2.0-rc1 - -This is a small RSA key management package, based on the openssl -command line tool, that can be found in the easy-rsa subdirectory -of the OpenVPN distribution. While this tool is primary concerned -with key management for the SSL VPN application space, it can also -be used for building web certificates. - -These are reference notes. For step-by-step instructions, see the -HOWTO: - -http://openvpn.net/howto.html - -This package is based on the ./pkitool script. Run ./pkitool -without arguments for a detailed help message (which is also pasted -below). - -Release Notes for easy-rsa-2.0 - -* Most functionality has been consolidated into the pkitool - script. For compatibility, all previous scripts from 1.0 such - as build-key and build-key-server are provided as stubs - which call pkitool to do the real work. - -* pkitool has a --batch flag (enabled by default) which generates - keys/certs without needing any interactive input. pkitool - can still generate certs/keys using interactive prompting by - using the --interact flag. - -* The inherit-inter script has been provided for creating - a new PKI rooted on an intermediate certificate built within a - higher-level PKI. See comments in the inherit-inter script - for more info. - -* The openssl.cnf file has been modified. pkitool will not - work with the openssl.cnf file included with previous - easy-rsa releases. - -* The vars file has been modified -- the following extra - variables have been added: EASY_RSA, CA_EXPIRE, - KEY_EXPIRE. - -* The make-crl and revoke-crt scripts have been removed and - are replaced by the revoke-full script. - -* The "Organizational Unit" X509 field can be set using - the KEY_OU environmental variable before calling pkitool. - -* This release only affects the Linux/Unix version of easy-rsa. - The Windows version (written to use the Windows shell) is unchanged. - -* Use the revoke-full script to revoke a certificate, and generate - (or update) the crl.pem file in the keys directory (as set by the - vars script). Then use "crl-verify crl.pem" in your OpenVPN server - config file, so that OpenVPN can reject any connections coming from - clients which present a revoked certificate. Usage for the script is: - - revoke-full <common-name> - - Note this this procedure is primarily designed to revoke client - certificates. You could theoretically use this method to revoke - server certificates as well, but then you would need to propagate - the crl.pem file to all clients as well, and have them include - "crl-verify crl.pem" in their configuration files. - -* PKCS#11 support was added. - -* For those interested in using this tool to generate web certificates, - A variant of the easy-rsa package that allows the creation of multi-domain - certificates with subjectAltName can be obtained from here: - - http://www.bisente.com/proyectos/easy-rsa-subjectaltname/ - -INSTALL easy-rsa - -1. Edit vars. -2. Set KEY_CONFIG to point to the correct openssl-<version>.cnf - file included in this distribution. -3. Set KEY_DIR to point to a directory which will - contain all keys, certificates, etc. This - directory need not exist, and if it does, - it will be deleted with rm -rf, so BE - CAREFUL how you set KEY_DIR. -4. (Optional) Edit other fields in vars - per your site data. You may want to - increase KEY_SIZE to 2048 if you are - paranoid and don't mind slower key - processing, but certainly 1024 is - fine for testing purposes. KEY_SIZE - must be compatible across both peers - participating in a secure SSL/TLS - connection. -5. (Optional) If you intend to use PKCS#11, - install openssl >= 0.9.7, install the - following components from www.opensc.org: - - opensc >= 0.10.0 - - engine_pkcs11 >= 0.1.3 - Update the openssl.cnf to load the engine: - - Uncomment pkcs11 under engine_section. - - Validate path at dynamic_path under pkcs11_section. -6. . vars -7. ./clean-all -8. As you create certificates, keys, and - certificate signing requests, understand that - only .key files should be kept confidential. - .crt and .csr files can be sent over insecure - channels such as plaintext email. - -IMPORTANT - -To avoid a possible Man-in-the-Middle attack where an authorized -client tries to connect to another client by impersonating the -server, make sure to enforce some kind of server certificate -verification by clients. There are currently four different ways -of accomplishing this, listed in the order of preference: - -(1) Build your server certificates with specific key usage and - extended key usage. The RFC3280 determine that the following - attributes should be provided for TLS connections: - - Mode Key usage Extended key usage - --------------------------------------------------------------------------- - Client digitalSignature TLS Web Client Authentication - keyAgreement - digitalSignature, keyAgreement - - Server digitalSignature, keyEncipherment TLS Web Server Authentication - digitalSignature, keyAgreement - - Now add the following line to your client configuration: - - remote-cert-tls server - - This will block clients from connecting to any - server which lacks the required extension designation - in its certificate, even if the certificate has been - signed by the CA which is cited in the OpenVPN configuration - file (--ca directive). - -(3) Use the --tls-remote directive on the client to - accept/reject the server connection based on the common - name of the server certificate. - -(3) Use a --tls-verify script or plugin to accept/reject the - server connection based on a custom test of the server - certificate's embedded X509 subject details. - -(4) Sign server certificates with one CA and client certificates - with a different CA. The client config "ca" directive should - reference the server-signing CA while the server config "ca" - directive should reference the client-signing CA. - -NOTES - -Show certificate fields: - openssl x509 -in cert.crt -text - -PKITOOL documentation - -pkitool 2.0 -Usage: pkitool [options...] [common-name] -Options: - --batch : batch mode (default) - --keysize : Set keysize - size : size (default=1024) - --interact : interactive mode - --server : build server cert - --initca : build root CA - --inter : build intermediate CA - --pass : encrypt private key with password - --csr : only generate a CSR, do not sign - --sign : sign an existing CSR - --pkcs12 : generate a combined PKCS#12 file - --pkcs11 : generate certificate on PKCS#11 token - lib : PKCS#11 library - slot : PKCS#11 slot - id : PKCS#11 object id (hex string) - label : PKCS#11 object label -Standalone options: - --pkcs11-slots : list PKCS#11 slots - lib : PKCS#11 library - --pkcs11-objects : list PKCS#11 token objects - lib : PKCS#11 library - slot : PKCS#11 slot - --pkcs11-init : initialize PKCS#11 token DANGEROUS!!! - lib : PKCS#11 library - slot : PKCS#11 slot - label : PKCS#11 token label -Notes: - Please edit the vars script to reflect your configuration, - then source it with "source ./vars". - Next, to start with a fresh PKI configuration and to delete any - previous certificates and keys, run "./clean-all". - Finally, you can run this tool (pkitool) to build certificates/keys. - In order to use PKCS#11 interface you must have opensc-0.10.0 or higher. -Generated files and corresponding OpenVPN directives: -(Files will be placed in the $KEY_DIR directory, defined in ./vars) - ca.crt -> root certificate (--ca) - ca.key -> root key, keep secure (not directly used by OpenVPN) - .crt files -> client/server certificates (--cert) - .key files -> private keys, keep secure (--key) - .csr files -> certificate signing request (not directly used by OpenVPN) - dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh) -Examples: - pkitool --initca -> Build root certificate - pkitool --initca --pass -> Build root certificate with password-protected key - pkitool --server server1 -> Build "server1" certificate/key - pkitool client1 -> Build "client1" certificate/key - pkitool --pass client2 -> Build password-protected "client2" certificate/key - pkitool --pkcs12 client3 -> Build "client3" certificate/key in PKCS#12 format - pkitool --csr client4 -> Build "client4" CSR to be signed by another CA - pkitool --sign client4 -> Sign "client4" CSR - pkitool --inter interca -> Build an intermediate key-signing certificate/key - Also see ./inherit-inter script. - pkitool --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5 - -> Build "client5" certificate/key in PKCS#11 token -Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys. -Protect client2 key with a password. Build DH parms. Generated files in ./keys : - [edit vars with your site-specific info] - source ./vars - ./clean-all - ./build-dh -> takes a long time, consider backgrounding - ./pkitool --initca - ./pkitool --server myserver - ./pkitool client1 - ./pkitool --pass client2 -Typical usage for adding client cert to existing PKI: - source ./vars - ./pkitool client-new diff --git a/easy-rsa/2.0/tmp/build-ca b/easy-rsa/2.0/tmp/build-ca deleted file mode 100755 index bce29a6..0000000 --- a/easy-rsa/2.0/tmp/build-ca +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# -# Build a root certificate -# - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --initca $* diff --git a/easy-rsa/2.0/tmp/build-dh b/easy-rsa/2.0/tmp/build-dh deleted file mode 100755 index 4beb127..0000000 --- a/easy-rsa/2.0/tmp/build-dh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# Build Diffie-Hellman parameters for the server side -# of an SSL/TLS connection. - -if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then - $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE} -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/tmp/build-inter b/easy-rsa/2.0/tmp/build-inter deleted file mode 100755 index 87bf98d..0000000 --- a/easy-rsa/2.0/tmp/build-inter +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Make an intermediate CA certificate/private key pair using a locally generated -# root certificate. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --inter $* diff --git a/easy-rsa/2.0/tmp/build-key b/easy-rsa/2.0/tmp/build-key deleted file mode 100755 index 6c0fed8..0000000 --- a/easy-rsa/2.0/tmp/build-key +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact $* diff --git a/easy-rsa/2.0/tmp/build-key-pass b/easy-rsa/2.0/tmp/build-key-pass deleted file mode 100755 index 8ef8307..0000000 --- a/easy-rsa/2.0/tmp/build-key-pass +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Similar to build-key, but protect the private key -# with a password. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --pass $* diff --git a/easy-rsa/2.0/tmp/build-key-pkcs12 b/easy-rsa/2.0/tmp/build-key-pkcs12 deleted file mode 100755 index ba90e6a..0000000 --- a/easy-rsa/2.0/tmp/build-key-pkcs12 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate and convert it to a PKCS #12 file including the -# the CA certificate as well. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --pkcs12 $* diff --git a/easy-rsa/2.0/tmp/build-key-server b/easy-rsa/2.0/tmp/build-key-server deleted file mode 100755 index fee0194..0000000 --- a/easy-rsa/2.0/tmp/build-key-server +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Make a certificate/private key pair using a locally generated -# root certificate. -# -# Explicitly set nsCertType to server using the "server" -# extension in the openssl.cnf file. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --server $* diff --git a/easy-rsa/2.0/tmp/build-req b/easy-rsa/2.0/tmp/build-req deleted file mode 100755 index 559d512..0000000 --- a/easy-rsa/2.0/tmp/build-req +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Build a certificate signing request and private key. Use this -# when your root certificate and key is not available locally. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --csr $* diff --git a/easy-rsa/2.0/tmp/build-req-pass b/easy-rsa/2.0/tmp/build-req-pass deleted file mode 100755 index b73ee1b..0000000 --- a/easy-rsa/2.0/tmp/build-req-pass +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Like build-req, but protect your private key -# with a password. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --csr --pass $* diff --git a/easy-rsa/2.0/tmp/clean-all b/easy-rsa/2.0/tmp/clean-all deleted file mode 100755 index cc6e3b2..0000000 --- a/easy-rsa/2.0/tmp/clean-all +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -# Initialize the $KEY_DIR directory. -# Note that this script does a -# rm -rf on $KEY_DIR so be careful! - -if [ "$KEY_DIR" ]; then - rm -rf "$KEY_DIR" - mkdir "$KEY_DIR" && \ - chmod go-rwx "$KEY_DIR" && \ - touch "$KEY_DIR/index.txt" && \ - echo 01 >"$KEY_DIR/serial" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/tmp/file b/easy-rsa/2.0/tmp/file deleted file mode 100644 index 1987bd7..0000000 --- a/easy-rsa/2.0/tmp/file +++ /dev/null @@ -1 +0,0 @@ -./openssl-1.0.0.cnf diff --git a/easy-rsa/2.0/tmp/inherit-inter b/easy-rsa/2.0/tmp/inherit-inter deleted file mode 100755 index aaa5168..0000000 --- a/easy-rsa/2.0/tmp/inherit-inter +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# Build a new PKI which is rooted on an intermediate certificate generated -# by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should -# have independent vars settings, and must use a different KEY_DIR directory -# from the parent. This tool can be used to generate arbitrary depth -# certificate chains. -# -# To build an intermediate CA, follow the same steps for a regular PKI but -# replace ./build-key or ./pkitool --initca with this script. - -# The EXPORT_CA file will contain the CA certificate chain and should be -# referenced by the OpenVPN "ca" directive in config files. The ca.crt file -# will only contain the local intermediate CA -- it's needed by the easy-rsa -# scripts but not by OpenVPN directly. -EXPORT_CA="export-ca.crt" - -if [ $# -ne 2 ]; then - echo "usage: $0 <parent-key-dir> <common-name>" - echo "parent-key-dir: the KEY_DIR directory of the parent PKI" - echo "common-name: the common name of the intermediate certificate in the parent PKI" - exit 1; -fi - -if [ "$KEY_DIR" ]; then - cp "$1/$2.crt" "$KEY_DIR/ca.crt" - cp "$1/$2.key" "$KEY_DIR/ca.key" - - if [ -e "$1/$EXPORT_CA" ]; then - PARENT_CA="$1/$EXPORT_CA" - else - PARENT_CA="$1/ca.crt" - fi - cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA" - cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/tmp/list-crl b/easy-rsa/2.0/tmp/list-crl deleted file mode 100755 index d1d8a69..0000000 --- a/easy-rsa/2.0/tmp/list-crl +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# list revoked certificates - -CRL="${1:-crl.pem}" - -if [ "$KEY_DIR" ]; then - cd "$KEY_DIR" && \ - $OPENSSL crl -text -noout -in "$CRL" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/tmp/openssl-0.9.6.cnf b/easy-rsa/2.0/tmp/openssl-0.9.6.cnf deleted file mode 100644 index d28341d..0000000 --- a/easy-rsa/2.0/tmp/openssl-0.9.6.cnf +++ /dev/null @@ -1,265 +0,0 @@ -# For use with easy-rsa version 2.0 - -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd - -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always diff --git a/easy-rsa/2.0/tmp/openssl-1.0.0.cnf b/easy-rsa/2.0/tmp/openssl-1.0.0.cnf deleted file mode 100644 index da425aa..0000000 --- a/easy-rsa/2.0/tmp/openssl-1.0.0.cnf +++ /dev/null @@ -1,285 +0,0 @@ -# For use with easy-rsa version 2.0 and OpenSSL 1.0.0* - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd -openssl_conf = openssl_init - -[ openssl_init ] -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids -engines = engine_section - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = $ENV::KEY_DIR # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # use public key default MD -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -#################################################################### -[ req ] -default_bits = $ENV::KEY_SIZE -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString (PKIX recommendation after 2004). -# utf8only: only UTF8Strings (PKIX recommendation after 2004). -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = $ENV::KEY_COUNTRY -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = $ENV::KEY_PROVINCE - -localityName = Locality Name (eg, city) -localityName_default = $ENV::KEY_CITY - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = $ENV::KEY_ORG - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -name = Name -name_max = 64 - -emailAddress = Email Address -emailAddress_default = $ENV::KEY_EMAIL -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = $ENV::KEY_OU -commonName_default = $ENV::KEY_CN -name_default = $ENV::KEY_NAME - - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always - -[ engine_section ] -# -# If you are using PKCS#11 -# Install engine_pkcs11 of opensc (www.opensc.org) -# And uncomment the following -# verify that dynamic_path points to the correct location -# -#pkcs11 = pkcs11_section - -[ pkcs11_section ] -engine_id = pkcs11 -dynamic_path = /usr/lib/engines/engine_pkcs11.so -MODULE_PATH = $ENV::PKCS11_MODULE_PATH -PIN = $ENV::PKCS11_PIN -init = 0 diff --git a/easy-rsa/2.0/tmp/pkitool b/easy-rsa/2.0/tmp/pkitool deleted file mode 100755 index 49588f5..0000000 --- a/easy-rsa/2.0/tmp/pkitool +++ /dev/null @@ -1,379 +0,0 @@ -#!/bin/sh - -# 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 - -# pkitool is a front-end for the openssl tool. - -# Calling scripts can set the certificate organizational -# unit with the KEY_OU environmental variable. - -# Calling scripts can also set the KEY_NAME environmental -# variable to set the "name" X509 subject field. - -PROGNAME=pkitool -VERSION=2.0 -DEBUG=0 - -die() -{ - local m="$1" - - echo "$m" >&2 - exit 1 -} - -need_vars() -{ - echo ' Please edit the vars script to reflect your configuration,' - echo ' then source it with "source ./vars".' - echo ' Next, to start with a fresh PKI configuration and to delete any' - echo ' previous certificates and keys, run "./clean-all".' - echo " Finally, you can run this tool ($PROGNAME) to build certificates/keys." -} - -usage() -{ - echo "$PROGNAME $VERSION" - echo "Usage: $PROGNAME [options...] [common-name]" - echo "Options:" - echo " --batch : batch mode (default)" - echo " --keysize : Set keysize" - echo " size : size (default=1024)" - echo " --interact : interactive mode" - echo " --server : build server cert" - echo " --initca : build root CA" - echo " --inter : build intermediate CA" - echo " --pass : encrypt private key with password" - echo " --csr : only generate a CSR, do not sign" - echo " --sign : sign an existing CSR" - echo " --pkcs12 : generate a combined PKCS#12 file" - echo " --pkcs11 : generate certificate on PKCS#11 token" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " id : PKCS#11 object id (hex string)" - echo " label : PKCS#11 object label" - echo "Standalone options:" - echo " --pkcs11-slots : list PKCS#11 slots" - echo " lib : PKCS#11 library" - echo " --pkcs11-objects : list PKCS#11 token objects" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " --pkcs11-init : initialize PKCS#11 token DANGEROUS!!!" - echo " lib : PKCS#11 library" - echo " slot : PKCS#11 slot" - echo " label : PKCS#11 token label" - echo "Notes:" - need_vars - echo " In order to use PKCS#11 interface you must have opensc-0.10.0 or higher." - echo "Generated files and corresponding OpenVPN directives:" - echo '(Files will be placed in the $KEY_DIR directory, defined in ./vars)' - echo " ca.crt -> root certificate (--ca)" - echo " ca.key -> root key, keep secure (not directly used by OpenVPN)" - echo " .crt files -> client/server certificates (--cert)" - echo " .key files -> private keys, keep secure (--key)" - echo " .csr files -> certificate signing request (not directly used by OpenVPN)" - echo " dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)" - echo "Examples:" - echo " $PROGNAME --initca -> Build root certificate" - echo " $PROGNAME --initca --pass -> Build root certificate with password-protected key" - echo " $PROGNAME --server server1 -> Build \"server1\" certificate/key" - echo " $PROGNAME client1 -> Build \"client1\" certificate/key" - echo " $PROGNAME --pass client2 -> Build password-protected \"client2\" certificate/key" - echo " $PROGNAME --pkcs12 client3 -> Build \"client3\" certificate/key in PKCS#12 format" - echo " $PROGNAME --csr client4 -> Build \"client4\" CSR to be signed by another CA" - echo " $PROGNAME --sign client4 -> Sign \"client4\" CSR" - echo " $PROGNAME --inter interca -> Build an intermediate key-signing certificate/key" - echo " Also see ./inherit-inter script." - echo " $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 \"client5 id\" client5" - echo " -> Build \"client5\" certificate/key in PKCS#11 token" - echo "Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys." - echo "Protect client2 key with a password. Build DH parms. Generated files in ./keys :" - echo " [edit vars with your site-specific info]" - echo " source ./vars" - echo " ./clean-all" - echo " ./build-dh -> takes a long time, consider backgrounding" - echo " ./$PROGNAME --initca" - echo " ./$PROGNAME --server myserver" - echo " ./$PROGNAME client1" - echo " ./$PROGNAME --pass client2" - echo "Typical usage for adding client cert to existing PKI:" - echo " source ./vars" - echo " ./$PROGNAME client-new" -} - -# Set tool defaults -[ -n "$OPENSSL" ] || export OPENSSL="openssl" -[ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool" -[ -n "$GREP" ] || export GREP="grep" - -# Set defaults -DO_REQ="1" -REQ_EXT="" -DO_CA="1" -CA_EXT="" -DO_P12="0" -DO_P11="0" -DO_ROOT="0" -NODES_REQ="-nodes" -NODES_P12="" -BATCH="-batch" -CA="ca" -# must be set or errors of openssl.cnf -PKCS11_MODULE_PATH="dummy" -PKCS11_PIN="dummy" - -# Process options -while [ $# -gt 0 ]; do - case "$1" in - --keysize ) KEY_SIZE=$2 - shift;; - --server ) REQ_EXT="$REQ_EXT -extensions server" - CA_EXT="$CA_EXT -extensions server" ;; - --batch ) BATCH="-batch" ;; - --interact ) BATCH="" ;; - --inter ) CA_EXT="$CA_EXT -extensions v3_ca" ;; - --initca ) DO_ROOT="1" ;; - --pass ) NODES_REQ="" ;; - --csr ) DO_CA="0" ;; - --sign ) DO_REQ="0" ;; - --pkcs12 ) DO_P12="1" ;; - --pkcs11 ) DO_P11="1" - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - PKCS11_ID="$4" - PKCS11_LABEL="$5" - shift 4;; - - # standalone - --pkcs11-init) - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - PKCS11_LABEL="$4" - if [ -z "$PKCS11_LABEL" ]; then - die "Please specify library name, slot and label" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \ - --label "$PKCS11_LABEL" && - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT" - exit $?;; - --pkcs11-slots) - PKCS11_MODULE_PATH="$2" - if [ -z "$PKCS11_MODULE_PATH" ]; then - die "Please specify library name" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots - exit 0;; - --pkcs11-objects) - PKCS11_MODULE_PATH="$2" - PKCS11_SLOT="$3" - if [ -z "$PKCS11_SLOT" ]; then - die "Please specify library name and slot" - fi - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT" - exit 0;; - - --help|--usage) - usage - exit ;; - --version) - echo "$PROGNAME $VERSION" - exit ;; - # errors - --* ) die "$PROGNAME: unknown option: $1" ;; - * ) break ;; - esac - shift -done - -if ! [ -z "$BATCH" ]; then - if $OPENSSL version | grep 0.9.6 > /dev/null; then - die "Batch mode is unsupported in openssl<0.9.7" - fi -fi - -if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then - die "PKCS#11 and PKCS#12 cannot be specified together" -fi - -if [ $DO_P11 -eq 1 ]; then - if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then - die "Please edit $KEY_CONFIG and setup PKCS#11 engine" - fi -fi - -# If we are generating pkcs12, only encrypt the final step -if [ $DO_P12 -eq 1 ]; then - NODES_P12="$NODES_REQ" - NODES_REQ="-nodes" -fi - -if [ $DO_P11 -eq 1 ]; then - if [ -z "$PKCS11_LABEL" ]; then - die "PKCS#11 arguments incomplete" - fi -fi - -# If undefined, set default key expiration intervals -if [ -z "$KEY_EXPIRE" ]; then - KEY_EXPIRE=3650 -fi -if [ -z "$CA_EXPIRE" ]; then - CA_EXPIRE=3650 -fi - -# Set organizational unit to empty string if undefined -if [ -z "$KEY_OU" ]; then - KEY_OU="" -fi - -# Set X509 Name string to empty string if undefined -if [ -z "$KEY_NAME" ]; then - KEY_NAME="" -fi - -# Set KEY_CN, FN -if [ $DO_ROOT -eq 1 ]; then - if [ -z "$KEY_CN" ]; then - if [ "$1" ]; then - KEY_CN="$1" - elif [ "$KEY_ORG" ]; then - KEY_CN="$KEY_ORG CA" - fi - fi - if [ $BATCH ] && [ "$KEY_CN" ]; then - echo "Using CA Common Name:" "$KEY_CN" - fi - FN="$KEY_CN" -elif [ $BATCH ] && [ "$KEY_CN" ]; then - echo "Using Common Name:" "$KEY_CN" - FN="$KEY_CN" - if [ "$1" ]; then - FN="$1" - fi -else - if [ $# -ne 1 ]; then - usage - exit 1 - else - KEY_CN="$1" - fi - FN="$KEY_CN" -fi - -export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN - -# Show parameters (debugging) -if [ $DEBUG -eq 1 ]; then - echo DO_REQ $DO_REQ - echo REQ_EXT $REQ_EXT - echo DO_CA $DO_CA - echo CA_EXT $CA_EXT - echo NODES_REQ $NODES_REQ - echo NODES_P12 $NODES_P12 - echo DO_P12 $DO_P12 - echo KEY_CN $KEY_CN - echo BATCH $BATCH - echo DO_ROOT $DO_ROOT - echo KEY_EXPIRE $KEY_EXPIRE - echo CA_EXPIRE $CA_EXPIRE - echo KEY_OU $KEY_OU - echo KEY_NAME $KEY_NAME - echo DO_P11 $DO_P11 - echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH - echo PKCS11_SLOT $PKCS11_SLOT - echo PKCS11_ID $PKCS11_ID - echo PKCS11_LABEL $PKCS11_LABEL -fi - -# Make sure ./vars was sourced beforehand -if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then - cd "$KEY_DIR" - - # Make sure $KEY_CONFIG points to the correct version - # of openssl.cnf - if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then - : - else - echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong" - echo "version of openssl.cnf: $KEY_CONFIG" - echo "The correct version should have a comment that says: easy-rsa version 2.x"; - exit 1; - fi - - # Build root CA - if [ $DO_ROOT -eq 1 ]; then - $OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE -sha1 \ - -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \ - chmod 0600 "$CA.key" - else - # Make sure CA key/cert is available - if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then - if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then - echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR" - echo "Try $PROGNAME --initca to build a root certificate/key." - exit 1 - fi - fi - - # Generate key for PKCS#11 token - PKCS11_ARGS= - if [ $DO_P11 -eq 1 ]; then - stty -echo - echo -n "User PIN: " - read -r PKCS11_PIN - stty echo - export PKCS11_PIN - - echo "Generating key pair on PKCS#11 token..." - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \ - --login --pin "$PKCS11_PIN" \ - --key-type rsa:1024 \ - --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1 - PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID" - fi - - # Build cert/key - ( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \ - -keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \ - ( [ $DO_CA -eq 0 ] || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \ - -in "$FN.csr" $CA_EXT -md sha1 -config "$KEY_CONFIG" ) && \ - ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \ - -in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \ - ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ] || chmod 0600 "$FN.key" ) && \ - ( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" ) - - # Load certificate into PKCS#11 token - if [ $DO_P11 -eq 1 ]; then - $OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \ - $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \ - --login --pin "$PKCS11_PIN" \ - --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" - [ -e "$FN.crt.der" ]; rm "$FN.crt.der" - fi - - fi - -# Need definitions -else - need_vars -fi diff --git a/easy-rsa/2.0/tmp/revoke-full b/easy-rsa/2.0/tmp/revoke-full deleted file mode 100755 index 4169c4c..0000000 --- a/easy-rsa/2.0/tmp/revoke-full +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -# revoke a certificate, regenerate CRL, -# and verify revocation - -CRL="crl.pem" -RT="revoke-test.pem" - -if [ $# -ne 1 ]; then - echo "usage: revoke-full <cert-name-base>"; - exit 1 -fi - -if [ "$KEY_DIR" ]; then - cd "$KEY_DIR" - rm -f "$RT" - - # set defaults - export KEY_CN="" - export KEY_OU="" - export KEY_NAME="" - - # revoke key and generate a new CRL - $OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG" - - # generate a new CRL -- try to be compatible with - # intermediate PKIs - $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG" - if [ -e export-ca.crt ]; then - cat export-ca.crt "$CRL" >"$RT" - else - cat ca.crt "$CRL" >"$RT" - fi - - # verify the revocation - $OPENSSL verify -CAfile "$RT" -crl_check "$1.crt" -else - echo 'Please source the vars script first (i.e. "source ./vars")' - echo 'Make sure you have edited it to reflect your configuration.' -fi diff --git a/easy-rsa/2.0/tmp/sign-req b/easy-rsa/2.0/tmp/sign-req deleted file mode 100755 index 6cae7b4..0000000 --- a/easy-rsa/2.0/tmp/sign-req +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# Sign a certificate signing request (a .csr file) -# with a local root certificate and key. - -export EASY_RSA="${EASY_RSA:-.}" -"$EASY_RSA/pkitool" --interact --sign $* diff --git a/easy-rsa/2.0/tmp/vars b/easy-rsa/2.0/tmp/vars deleted file mode 100644 index 2ea1ced..0000000 --- a/easy-rsa/2.0/tmp/vars +++ /dev/null @@ -1,74 +0,0 @@ -# easy-rsa parameter settings - -# NOTE: If you installed from an RPM, -# don't edit this file in place in -# /usr/share/openvpn/easy-rsa -- -# instead, you should copy the whole -# easy-rsa directory to another location -# (such as /etc/openvpn) so that your -# edits will not be wiped out by a future -# OpenVPN package upgrade. - -# This variable should point to -# the top level of the easy-rsa -# tree. -export EASY_RSA="`pwd`" - -# -# This variable should point to -# the requested executables -# -export OPENSSL="openssl" -export PKCS11TOOL="pkcs11-tool" -export GREP="grep" - - -# This variable should point to -# the openssl.cnf file included -# with easy-rsa. -export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` - -# Edit this variable to point to -# your soon-to-be-created key -# directory. -# -# WARNING: clean-all will do -# a rm -rf on this directory -# so make sure you define -# it correctly! -export KEY_DIR="$EASY_RSA/keys" - -# Issue rm -rf warning -echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR - -# PKCS11 fixes -export PKCS11_MODULE_PATH="dummy" -export PKCS11_PIN="dummy" - -# Increase this to 2048 if you -# are paranoid. This will slow -# down TLS negotiation performance -# as well as the one-time DH parms -# generation process. -export KEY_SIZE=1024 - -# In how many days should the root CA key expire? -export CA_EXPIRE=3650 - -# In how many days should certificates expire? -export KEY_EXPIRE=3650 - -# These are the default values for fields -# which will be placed in the certificate. -# Don't leave any of these fields blank. -export KEY_COUNTRY="US" -export KEY_PROVINCE="CA" -export KEY_CITY="SanFrancisco" -export KEY_ORG="Fort-Funston" -export KEY_EMAIL="me@myhost.mydomain" -export KEY_EMAIL=mail@host.domain -export KEY_CN=changeme -export KEY_NAME=changeme -export KEY_OU=changeme -export PKCS11_MODULE_PATH=changeme -export PKCS11_PIN=1234 diff --git a/easy-rsa/2.0/tmp/whichopensslcnf b/easy-rsa/2.0/tmp/whichopensslcnf deleted file mode 100755 index 94225cb..0000000 --- a/easy-rsa/2.0/tmp/whichopensslcnf +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -cnf="$1/openssl.cnf" -if [ "$OPENSSL" ]; then - if $OPENSSL version | grep 0.9.6 > /dev/null; then - cnf="$1/openssl-0.9.6.cnf" - elif $OPENSSL version | grep -E "1\.0\.([[:digit:]][[:alnum:]])" > /dev/null; then - cnf="$1/openssl-1.0.0.cnf" - else - cnf="$1/openssl.cnf" - fi -fi - -echo $cnf - -if [ ! -r $cnf ]; then - echo "**************************************************************" >&2 - echo " No $cnf file could be found" >&2 - echo " Further invocations will fail" >&2 - echo "**************************************************************" >&2 -fi - -exit 0 diff --git a/easy-rsa/2.0/vars b/easy-rsa/2.0/vars deleted file mode 100755 index 2ea1ced..0000000 --- a/easy-rsa/2.0/vars +++ /dev/null @@ -1,74 +0,0 @@ -# easy-rsa parameter settings - -# NOTE: If you installed from an RPM, -# don't edit this file in place in -# /usr/share/openvpn/easy-rsa -- -# instead, you should copy the whole -# easy-rsa directory to another location -# (such as /etc/openvpn) so that your -# edits will not be wiped out by a future -# OpenVPN package upgrade. - -# This variable should point to -# the top level of the easy-rsa -# tree. -export EASY_RSA="`pwd`" - -# -# This variable should point to -# the requested executables -# -export OPENSSL="openssl" -export PKCS11TOOL="pkcs11-tool" -export GREP="grep" - - -# This variable should point to -# the openssl.cnf file included -# with easy-rsa. -export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` - -# Edit this variable to point to -# your soon-to-be-created key -# directory. -# -# WARNING: clean-all will do -# a rm -rf on this directory -# so make sure you define -# it correctly! -export KEY_DIR="$EASY_RSA/keys" - -# Issue rm -rf warning -echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR - -# PKCS11 fixes -export PKCS11_MODULE_PATH="dummy" -export PKCS11_PIN="dummy" - -# Increase this to 2048 if you -# are paranoid. This will slow -# down TLS negotiation performance -# as well as the one-time DH parms -# generation process. -export KEY_SIZE=1024 - -# In how many days should the root CA key expire? -export CA_EXPIRE=3650 - -# In how many days should certificates expire? -export KEY_EXPIRE=3650 - -# These are the default values for fields -# which will be placed in the certificate. -# Don't leave any of these fields blank. -export KEY_COUNTRY="US" -export KEY_PROVINCE="CA" -export KEY_CITY="SanFrancisco" -export KEY_ORG="Fort-Funston" -export KEY_EMAIL="me@myhost.mydomain" -export KEY_EMAIL=mail@host.domain -export KEY_CN=changeme -export KEY_NAME=changeme -export KEY_OU=changeme -export PKCS11_MODULE_PATH=changeme -export PKCS11_PIN=1234 diff --git a/easy-rsa/2.0/whichopensslcnf b/easy-rsa/2.0/whichopensslcnf deleted file mode 100755 index 2226a8e..0000000 --- a/easy-rsa/2.0/whichopensslcnf +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -cnf="$1/openssl.cnf" - -if [ "$OPENSSL" ]; then - if $OPENSSL version | grep -E "0\.9\.6[[:alnum:]]" > /dev/null; then - cnf="$1/openssl-0.9.6.cnf" - elif $OPENSSL version | grep -E "0\.9\.8[[:alnum:]]" > /dev/null; then - cnf="$1/openssl-0.9.8.cnf" - elif $OPENSSL version | grep -E "1\.0\.([[:digit:]][[:alnum:]])" > /dev/null; then - cnf="$1/openssl-1.0.0.cnf" - else - cnf="$1/openssl.cnf" - fi -fi - -echo $cnf - -if [ ! -r $cnf ]; then - echo "**************************************************************" >&2 - echo " No $cnf file could be found" >&2 - echo " Further invocations will fail" >&2 - echo "**************************************************************" >&2 -fi - -exit 0 diff --git a/easy-rsa/Windows/README.txt b/easy-rsa/Windows/README.txt deleted file mode 100644 index 2ede7b1..0000000 --- a/easy-rsa/Windows/README.txt +++ /dev/null @@ -1,44 +0,0 @@ -Extract all zip'd files to the OpenVPN home directory, -including the openssl.cnf file from the top-level -"easy-rsa" directory. - -First run init-config.bat - -Next, edit vars.bat to adapt it to your environment, and -create the directory that will hold your key files. - -To generate TLS keys: - -Create new empty index and serial files (once only) -1. vars -2. clean-all - -Build a CA key (once only) -1. vars -2. build-ca - -Build a DH file (for server side, once only) -1. vars -2. build-dh - -Build a private key/certficate for the openvpn server -1. vars -2. build-key-server <machine-name> - -Build key files in PEM format (for each client machine) -1. vars -2. build-key <machine-name> - (use <machine name> for specific name within script) - -or - -Build key files in PKCS #12 format (for each client machine) -1. vars -2. build-key-pkcs12 <machine-name> - (use <machine name> for specific name within script) - -To revoke a TLS certificate and generate a CRL file: -1. vars -2. revoke-full <machine-name> -3. verify last line of output confirms revokation -4. copy crl.pem to server directory and ensure config file uses "crl-verify <crl filename>" diff --git a/easy-rsa/Windows/build-ca-pass.bat b/easy-rsa/Windows/build-ca-pass.bat deleted file mode 100644 index ab0b2a4..0000000 --- a/easy-rsa/Windows/build-ca-pass.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/build-ca.bat b/easy-rsa/Windows/build-ca.bat deleted file mode 100644 index a3f234b..0000000 --- a/easy-rsa/Windows/build-ca.bat +++ /dev/null @@ -1,4 +0,0 @@ -@echo off -cd %HOME% -rem build a cert authority valid for ten years, starting now -openssl req -days 3650 -nodes -new -x509 -keyout %KEY_DIR%\ca.key -out %KEY_DIR%\ca.crt -config %KEY_CONFIG% diff --git a/easy-rsa/Windows/build-dh.bat b/easy-rsa/Windows/build-dh.bat deleted file mode 100644 index 74bc603..0000000 --- a/easy-rsa/Windows/build-dh.bat +++ /dev/null @@ -1,4 +0,0 @@ -@echo off -cd %HOME% -rem build a dh file for the server side -openssl dhparam -out %KEY_DIR%/dh%KEY_SIZE%.pem %KEY_SIZE% diff --git a/easy-rsa/Windows/build-key-pass.bat b/easy-rsa/Windows/build-key-pass.bat deleted file mode 100644 index ab0b2a4..0000000 --- a/easy-rsa/Windows/build-key-pass.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/build-key-pkcs12.bat b/easy-rsa/Windows/build-key-pkcs12.bat deleted file mode 100644 index 1fc083e..0000000 --- a/easy-rsa/Windows/build-key-pkcs12.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem convert the key/cert and embed the ca cert into a pkcs12 file. -openssl pkcs12 -export -inkey %KEY_DIR%\%1.key -in %KEY_DIR%\%1.crt -certfile %KEY_DIR%\ca.crt -out %KEY_DIR%\%1.p12 -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/build-key-server-pass.bat b/easy-rsa/Windows/build-key-server-pass.bat deleted file mode 100644 index 99ed4d3..0000000 --- a/easy-rsa/Windows/build-key-server-pass.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG% -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/build-key-server.bat b/easy-rsa/Windows/build-key-server.bat deleted file mode 100644 index 20e3605..0000000 --- a/easy-rsa/Windows/build-key-server.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG% -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/build-key.bat b/easy-rsa/Windows/build-key.bat deleted file mode 100644 index c040904..0000000 --- a/easy-rsa/Windows/build-key.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -cd %HOME% -rem build a request for a cert that will be valid for ten years -openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem sign the cert request with our ca, creating a cert/key pair -openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG% -rem delete any .old files created in this process, to avoid future file creation errors -del /q %KEY_DIR%\*.old diff --git a/easy-rsa/Windows/clean-all.bat b/easy-rsa/Windows/clean-all.bat deleted file mode 100644 index 71cbf4d..0000000 --- a/easy-rsa/Windows/clean-all.bat +++ /dev/null @@ -1,13 +0,0 @@ -@echo off -rem move to the HOME directory specified in VARS script -cd %HOME% -rem set a temporary KEY_DIR variable -set d=%KEY_DIR% -rem delete the KEY_DIR and any subdirs quietly -rmdir /s /q %d% -rem make a new KEY_DIR -mkdir %d% -rem copy in a fesh index file so we begin with an empty database -copy index.txt.start %d%\index.txt -rem copy in a fresh serial file so we begin generating keys at index 01 -copy serial.start %d%\serial. diff --git a/easy-rsa/Windows/index.txt.start b/easy-rsa/Windows/index.txt.start deleted file mode 100644 index e69de29..0000000 --- a/easy-rsa/Windows/index.txt.start +++ /dev/null diff --git a/easy-rsa/Windows/init-config.bat b/easy-rsa/Windows/init-config.bat deleted file mode 100755 index 12e6d78..0000000 --- a/easy-rsa/Windows/init-config.bat +++ /dev/null @@ -1 +0,0 @@ -copy vars.bat.sample vars.bat diff --git a/easy-rsa/Windows/revoke-full.bat b/easy-rsa/Windows/revoke-full.bat deleted file mode 100644 index ef2e4b5..0000000 --- a/easy-rsa/Windows/revoke-full.bat +++ /dev/null @@ -1,13 +0,0 @@ -@echo off -cd %HOME% -rem revoke cert -openssl ca -revoke %KEY_DIR%\%1.crt -config %KEY_CONFIG% -rem generate new crl -openssl ca -gencrl -out %KEY_DIR%\crl.pem -config %KEY_CONFIG% -rem test revocation -rem first concatinate ca cert with newly generated crl -copy %KEY_DIR%\ca.crt+%KEY_DIR%\crl.pem %KEY_DIR%\revoke_test_file.pem -rem now verify the revocation -openssl verify -CAfile %KEY_DIR%\revoke_test_file.pem -crl_check %KEY_DIR%\%1.crt -rem delete temporary test file -del /q %KEY_DIR%\revoke_test_file.pem diff --git a/easy-rsa/Windows/serial.start b/easy-rsa/Windows/serial.start deleted file mode 100644 index 8a0f05e..0000000 --- a/easy-rsa/Windows/serial.start +++ /dev/null @@ -1 +0,0 @@ -01 diff --git a/easy-rsa/Windows/vars.bat.sample b/easy-rsa/Windows/vars.bat.sample deleted file mode 100644 index 36e6f71..0000000 --- a/easy-rsa/Windows/vars.bat.sample +++ /dev/null @@ -1,40 +0,0 @@ -@echo off -rem Edit this variable to point to -rem the openssl.cnf file included -rem with easy-rsa. - -set HOME=%ProgramFiles%\OpenVPN\easy-rsa -set KEY_CONFIG=openssl-1.0.0.cnf - -rem Edit this variable to point to -rem your soon-to-be-created key -rem directory. -rem -rem WARNING: clean-all will do -rem a rm -rf on this directory -rem so make sure you define -rem it correctly! -set KEY_DIR=keys - -rem Increase this to 2048 if you -rem are paranoid. This will slow -rem down TLS negotiation performance -rem as well as the one-time DH parms -rem generation process. -set KEY_SIZE=1024 - -rem These are the default values for fields -rem which will be placed in the certificate. -rem Change these to reflect your site. -rem Don't leave any of these parms blank. - -set KEY_COUNTRY=US -set KEY_PROVINCE=CA -set KEY_CITY=SanFrancisco -set KEY_ORG=OpenVPN -set KEY_EMAIL=mail@host.domain -set KEY_CN=changeme -set KEY_NAME=changeme -set KEY_OU=changeme -set PKCS11_MODULE_PATH=changeme -set PKCS11_PIN=1234 diff --git a/forward.h b/forward.h deleted file mode 100644 index 17cc928..0000000 --- a/forward.h +++ /dev/null @@ -1,86 +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 - */ - -#ifndef FORWARD_H -#define FORWARD_H - -#include "openvpn.h" -#include "occ.h" -#include "ping.h" - -#define TUN_OUT(c) (BLEN(&(c)->c2.to_tun) > 0) -#define LINK_OUT(c) (BLEN(&(c)->c2.to_link) > 0) -#define ANY_OUT(c) (TUN_OUT(c) || LINK_OUT(c)) - -#ifdef ENABLE_FRAGMENT -#define TO_LINK_FRAG(c) ((c)->c2.fragment && fragment_outgoing_defined ((c)->c2.fragment)) -#else -#define TO_LINK_FRAG(c) (false) -#endif - -#define TO_LINK_DEF(c) (LINK_OUT(c) || TO_LINK_FRAG(c)) - -#define IOW_TO_TUN (1<<0) -#define IOW_TO_LINK (1<<1) -#define IOW_READ_TUN (1<<2) -#define IOW_READ_LINK (1<<3) -#define IOW_SHAPER (1<<4) -#define IOW_CHECK_RESIDUAL (1<<5) -#define IOW_FRAG (1<<6) -#define IOW_MBUF (1<<7) -#define IOW_READ_TUN_FORCE (1<<8) -#define IOW_WAIT_SIGNAL (1<<9) - -#define IOW_READ (IOW_READ_TUN|IOW_READ_LINK) - -void pre_select (struct context *c); - -void process_io (struct context *c); - -void encrypt_sign (struct context *c, bool comp_frag); - -const char *wait_status_string (struct context *c, struct gc_arena *gc); -void show_wait_status (struct context *c); - -void read_incoming_link (struct context *c); -void process_incoming_link (struct context *c); -void read_incoming_tun (struct context *c); -void process_incoming_tun (struct context *c); -void process_outgoing_link (struct context *c); -void process_outgoing_tun (struct context *c); - -bool send_control_channel_string (struct context *c, const char *str, int msglevel); - -#define PIPV4_PASSTOS (1<<0) -#define PIPV4_MSSFIX (1<<1) -#define PIPV4_OUTGOING (1<<2) -#define PIPV4_EXTRACT_DHCP_ROUTER (1<<3) - -void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf); - -#if P2MP -void schedule_exit (struct context *c, const int n_seconds, const int signal); -#endif - -#endif /* FORWARD_H */ diff --git a/fragment.h b/fragment.h deleted file mode 100644 index fc2b1b8..0000000 --- a/fragment.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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-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 FRAGMENT_H -#define FRAGMENT_H - -#ifdef ENABLE_FRAGMENT - -#include "common.h" -#include "buffer.h" -#include "interval.h" -#include "mtu.h" -#include "shaper.h" -#include "error.h" - -#define N_FRAG_BUF 25 /* number of packet buffers */ -#define FRAG_TTL_SEC 10 /* number of seconds time-to-live for a fragment */ -#define FRAG_WAKEUP_INTERVAL 5 /* wakeup code called once per n seconds */ - -struct fragment { - bool defined; - - int max_frag_size; /* maximum size of each fragment */ - - /* - * 32 bit array corresponding to each fragment. A 1 bit in element n means that - * the fragment n has been received. Needs to have at least MAX_FRAGS bits. - */ -# define FRAG_MAP_MASK 0xFFFFFFFF -# define MAX_FRAGS 32 /* maximum number of fragments per packet */ - unsigned int map; - - time_t timestamp; /* timestamp for time-to-live purposes */ - - struct buffer buf; /* fragment assembly buffer for received datagrams */ -}; - -struct fragment_list { - int seq_id; - int index; - struct fragment fragments[N_FRAG_BUF]; -}; - -struct fragment_master { - struct event_timeout wakeup; /* when should main openvpn event loop wake us up */ - - /* true if the OS has explicitly recommended an MTU value */ - bool received_os_mtu_hint; - - /* a sequence ID describes a set of fragments that make up one datagram */ -# define N_SEQ_ID 256 /* sequence number wraps to 0 at this value (should be a power of 2) */ - int outgoing_seq_id; /* sent as FRAG_SEQ_ID below */ - - /* outgoing packet is possibly sent as a series of fragments */ - -# define MAX_FRAG_PKT_SIZE 65536 /* maximum packet size */ - int outgoing_frag_size; /* sent to peer via FRAG_SIZE when FRAG_YES_LAST set */ - - int outgoing_frag_id; /* each fragment in a datagram is numbered 0 to MAX_FRAGS-1 */ - - struct buffer outgoing; /* outgoing datagram, free if current_frag_id == 0 */ - struct buffer outgoing_return; /* buffer to return outgoing fragment */ - - /* incoming fragments from remote */ - struct fragment_list incoming; -}; - -/* - * Fragment header sent over the wire. - */ - -typedef uint32_t fragment_header_type; - -/* convert a fragment_header_type from host to network order */ -#define hton_fragment_header_type(x) htonl(x) - -/* convert a fragment_header_type from network to host order */ -#define ntoh_fragment_header_type(x) ntohl(x) - -/* FRAG_TYPE 2 bits */ -#define FRAG_TYPE_MASK 0x00000003 -#define FRAG_TYPE_SHIFT 0 - -#define FRAG_WHOLE 0 /* packet is whole, FRAG_N_PACKETS_RECEIVED echoed back to peer */ -#define FRAG_YES_NOTLAST 1 /* packet is a fragment, but is not the last fragment, - FRAG_N_PACKETS_RECEIVED set as above */ -#define FRAG_YES_LAST 2 /* packet is the last fragment, FRAG_SIZE = size of non-last frags */ -#define FRAG_TEST 3 /* control packet for establishing MTU size (not implemented yet) */ - -/* FRAG_SEQ_ID 8 bits */ -#define FRAG_SEQ_ID_MASK 0x000000ff -#define FRAG_SEQ_ID_SHIFT 2 - -/* FRAG_ID 5 bits */ -#define FRAG_ID_MASK 0x0000001f -#define FRAG_ID_SHIFT 10 - -/* - * FRAG_SIZE 14 bits - * - * IF FRAG_YES_LAST (FRAG_SIZE): - * The max size of a fragment. If a fragment is not the last fragment in the packet, - * then the fragment size is guaranteed to be equal to the max fragment size. Therefore, - * max_frag_size is only sent over the wire if FRAG_LAST is set. Otherwise it is assumed - * to be the actual fragment size received. - */ - -/* FRAG_SIZE 14 bits */ -#define FRAG_SIZE_MASK 0x00003fff -#define FRAG_SIZE_SHIFT 15 -#define FRAG_SIZE_ROUND_SHIFT 2 /* fragment/datagram sizes represented as multiple of 4 */ - -#define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1) - -/* - * FRAG_EXTRA 16 bits - * - * IF FRAG_WHOLE or FRAG_YES_NOTLAST, these 16 bits are available (not currently used) - */ - -/* FRAG_EXTRA 16 bits */ -#define FRAG_EXTRA_MASK 0x0000ffff -#define FRAG_EXTRA_SHIFT 15 - -/* - * Public functions - */ - -struct fragment_master *fragment_init (struct frame *frame); - -void fragment_frame_init (struct fragment_master *f, const struct frame *frame); - -void fragment_free (struct fragment_master *f); - -void fragment_incoming (struct fragment_master *f, struct buffer *buf, - const struct frame* frame); - -void fragment_outgoing (struct fragment_master *f, struct buffer *buf, - const struct frame* frame); - -bool fragment_ready_to_send (struct fragment_master *f, struct buffer *buf, - const struct frame* frame); - -/* - * Private functions. - */ -void fragment_wakeup (struct fragment_master *f, struct frame *frame); - -/* - * Inline functions - */ - -static inline void -fragment_housekeeping (struct fragment_master *f, struct frame *frame, struct timeval *tv) -{ - if (event_timeout_trigger (&f->wakeup, tv, ETT_DEFAULT)) - fragment_wakeup (f, frame); -} - -static inline bool -fragment_outgoing_defined (struct fragment_master *f) -{ - return f->outgoing.len > 0; -} - -#endif -#endif diff --git a/ieproxy.c b/ieproxy.c deleted file mode 100644 index 3099870..0000000 --- a/ieproxy.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info> - * - * 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 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 (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 "syshead.h" - -#ifdef WIN32 - -#include <wininet.h> -#include <malloc.h> - -LPCTSTR getIeHttpProxyError=NULL; - -/* getIeHttpProxy fetches the current IE proxy settings for http */ - -LPCTSTR getIeHttpProxy() -{ - DWORD psize=0; - INTERNET_PROXY_INFO *pinfo; - LPTSTR proxyString; - LPTSTR p; - LPTSTR q; - unsigned int len; - - /* first see how big a buffer we need for the IPO structure */ - InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &psize); - if(!psize) - { - getIeHttpProxyError="InternetQueryOption failed to return buffer size"; - return(NULL); - } - - /* allocate memory for IPO */ - pinfo = malloc (psize*sizeof(TCHAR)); - if (pinfo == NULL) - { - getIeHttpProxyError="malloc failed (1)"; - return(NULL); - } - - /* now run the real query */ - if(!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, (LPVOID) pinfo, &psize)) - { - getIeHttpProxyError="InternetQueryOption() failed to find proxy info"; - free(pinfo); - return(NULL); - } - - - /* see what sort of result we got */ - - if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) - { - /* No proxy configured */ - free(pinfo); - return(""); - } - else if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY) - { - /* we have a proxy - now parse result string */ - /* if result string does NOT contain an '=' sign then */ - /* there is a single proxy for all protocols */ - for (p=(LPTSTR)pinfo->lpszProxy; *p && *p != '='; p++); - if(!*p) - { - /* single proxy */ - /* allocate a new string to return */ - len = 1+strlen(pinfo->lpszProxy); - proxyString = malloc (len*sizeof(TCHAR)); - if (proxyString == NULL) - { - getIeHttpProxyError="malloc failed (2)"; - free(pinfo); - return(NULL); - } - strncpy(proxyString, pinfo->lpszProxy,len); - proxyString[len]=0; - free(pinfo); - return(proxyString); - } - else - { - /* multiple space seperated proxies defined in the form */ - /* protocol=proxyhost[:port] */ - /* we want the one marked "http=", if any. */ - p=(LPTSTR)pinfo->lpszProxy; - while(*p && strncmp(p, "http=", 5)) - { - for(; *p && *p != ' '; p++); - if(*p) p++; - } - if(*p) - { - /* found the proxy */ - p+=5; - for(q=p; *q && *q != ' '; q++); - /* allocate a buffer for the proxy information */ - len=1+(q-p); - proxyString=malloc(len*sizeof(TCHAR)); - if(proxyString==NULL) - { - getIeHttpProxyError="malloc failed (3)"; - free(pinfo); - return(NULL); - } - strncpy(proxyString, p, len); - proxyString[len]=0; - free(pinfo); - return(proxyString); - } - else - { - /* No http proxy in list */ - free(pinfo); - return(""); - } - } - } - else - { - /* InternetQueryOption returned a proxy type we don't know about*/ - getIeHttpProxyError="Unknown Proxy Type"; - free(pinfo); - return(NULL); - } -} -#else -#ifdef _MSC_VER /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */ -static void dummy (void) {} -#endif -#endif /* WIN32 */ diff --git a/ieproxy.h b/ieproxy.h deleted file mode 100644 index 0786c05..0000000 --- a/ieproxy.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info> - * - * 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 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 (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 __GETIEHTTPPROXY__ -#define __GETIEHTTPPROXY__ -extern LPTSTR getIeHttpProxyError; -LPCTSTR getIeHttpProxy(); -#endif diff --git a/images/Makefile.am b/images/Makefile.am deleted file mode 100644 index 334554f..0000000 --- a/images/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -# -# 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-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 -# - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -images = \ - install-whirl.bmp \ - icon.ico - -if WIN32 - -imagedir = $(win32datadir)/images -dist_image_DATA = $(images) - -else - -dist_noinst_DATA = $(images) - -endif - diff --git a/images/icon.ico b/images/icon.ico Binary files differdeleted file mode 100755 index 03ea0b1..0000000 --- a/images/icon.ico +++ /dev/null diff --git a/images/install-whirl.bmp b/images/install-whirl.bmp Binary files differdeleted file mode 100755 index 03f33fc..0000000 --- a/images/install-whirl.bmp +++ /dev/null diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..13dee61 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,15 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +include_HEADERS = openvpn-plugin.h diff --git a/include/Makefile.in b/include/Makefile.in new file mode 100644 index 0000000..4d08ed9 --- /dev/null +++ b/include/Makefile.in @@ -0,0 +1,509 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +VPATH = @srcdir@ +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 = include +DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +include_HEADERS = openvpn-plugin.h +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) --gnu include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/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 +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +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: uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags 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 uninstall uninstall-am uninstall-includeHEADERS + + +# 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/openvpn-plugin.h b/include/openvpn-plugin.h index 173a0c1..0879f49 100644 --- a/openvpn-plugin.h +++ b/include/openvpn-plugin.h @@ -22,7 +22,32 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define OPENVPN_PLUGIN_VERSION 2 +#ifndef OPENVPN_PLUGIN_H_ +#define OPENVPN_PLUGIN_H_ + +#define OPENVPN_PLUGIN_VERSION 3 + +#ifdef ENABLE_SSL +#ifdef ENABLE_CRYPTO_POLARSSL +#include <polarssl/x509.h> +#ifndef __OPENVPN_X509_CERT_T_DECLARED +#define __OPENVPN_X509_CERT_T_DECLARED +typedef x509_cert 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 /* * Plug-in types. These types correspond to the set of script callbacks @@ -98,7 +123,8 @@ #define OPENVPN_PLUGIN_CLIENT_CONNECT_V2 9 #define OPENVPN_PLUGIN_TLS_FINAL 10 #define OPENVPN_PLUGIN_ENABLE_PF 11 -#define OPENVPN_PLUGIN_N 12 +#define OPENVPN_PLUGIN_ROUTE_PREDOWN 12 +#define OPENVPN_PLUGIN_N 13 /* * Build a mask out of a set of plug-in types. @@ -121,7 +147,7 @@ typedef void *openvpn_plugin_handle_t; /* * For Windows (needs to be modified for MSVC) */ -#if defined(__MINGW32_VERSION) && !defined(OPENVPN_PLUGIN_H) +#if defined(WIN32) && !defined(OPENVPN_PLUGIN_H) # define OPENVPN_EXPORT __declspec(dllexport) #else # define OPENVPN_EXPORT @@ -163,6 +189,195 @@ struct openvpn_plugin_string_list 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. + * + */ +#define OPENVPN_PLUGINv3_STRUCTVER 1 + +/** + * 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; +}; + +/** + * 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; +}; + + +/** + * 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_SSL defined) + * + * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_SSL 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_SSL + 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 @@ -329,6 +544,118 @@ OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v2) 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_PLUGIN_VERSION 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 * @@ -459,3 +786,9 @@ OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_op 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/install-win32/GetWindowsVersion.nsi b/install-win32/GetWindowsVersion.nsi deleted file mode 100644 index 103caff..0000000 --- a/install-win32/GetWindowsVersion.nsi +++ /dev/null @@ -1,109 +0,0 @@ -; Turn off old selected section -; GetWindowsVersion -; -; Based on Yazno's function -; Updated by Joost Verburg -; Updated for Windows 98 SE by Matthew Win Tibbals 5-21-03 -; Updated for Vista by Joe Cincotta 12-2-07 -; -; Returns on top of stack -; -; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003, VISTA) -; or -; '' (Unknown Windows Version) -; -; Usage: -; Call GetWindowsVersion -; Pop $R0 -; ; at this point $R0 is "NT 4.0" or whatnot -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function GetWindowsVersion - - Push $R0 - Push $R1 - - ClearErrors - - ReadRegStr $R0 HKLM \ - "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - - IfErrors 0 lbl_winnt - - ; we are not NT - ReadRegStr $R0 HKLM \ - "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber - - StrCpy $R1 $R0 1 - StrCmp $R1 '4' 0 lbl_error - - StrCpy $R1 $R0 3 - - StrCmp $R1 '4.0' lbl_win32_95 - StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 - - lbl_win32_95: - StrCpy $R0 '95' - Goto lbl_done - - lbl_win32_98: -;;beginning of additions to support win 98 SE - push $R0 - push "." - call strstr - pop $R0 - StrCpy $R0 $R0 "" 1 - StrCmp $R0 "10.2222" lbl_win32_98SE - StrCpy $R0 '98' ;;this line was not added - Goto lbl_done ;;this line was not added either - - lbl_win32_98SE: - StrCpy $R0 '98 SE' - Goto lbl_done -;;end of additions to support win 98 SE - lbl_win32_ME: - StrCpy $R0 'ME' - Goto lbl_done - - lbl_winnt: - - StrCpy $R1 $R0 1 - - StrCmp $R1 '3' lbl_winnt_x - StrCmp $R1 '4' lbl_winnt_x - - StrCpy $R1 $R0 3 - - StrCmp $R1 '5.0' lbl_winnt_2000 - StrCmp $R1 '5.1' lbl_winnt_XP - StrCmp $R1 '5.2' lbl_winnt_2003 - StrCmp $R1 '6.0' lbl_winnt_VISTA lbl_error - - lbl_winnt_x: - StrCpy $R0 "NT $R0" 6 - Goto lbl_done - - lbl_winnt_2000: - Strcpy $R0 '2000' - Goto lbl_done - - lbl_winnt_XP: - Strcpy $R0 'XP' - Goto lbl_done - - lbl_winnt_2003: - Strcpy $R0 '2003' - Goto lbl_done - - lbl_winnt_VISTA: - Strcpy $R0 'VISTA' - Goto lbl_done - - lbl_error: - Strcpy $R0 '' - lbl_done: - - Pop $R1 - Exch $R0 - -FunctionEnd -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/install-win32/Makefile.am b/install-win32/Makefile.am deleted file mode 100644 index 75932fe..0000000 --- a/install-win32/Makefile.am +++ /dev/null @@ -1,97 +0,0 @@ -# -# 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-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 -# - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -dist_noinst_DATA = \ - openssl \ - GetWindowsVersion.nsi \ - build-pkcs11-helper.sh \ - buildinstaller \ - ddk-common \ - doclean \ - dosname.pl \ - getgui \ - getopenssl \ - getpkcs11helper \ - getprebuilt \ - getxgui \ - ifdef.pl \ - m4todef.pl \ - macro.pl \ - makeopenvpn \ - maketap \ - maketapinstall \ - maketext \ - openvpn.nsi \ - setpath.nsi \ - settings.in \ - trans.pl \ - u2d.c \ - winconfig - -if WIN32 - -nodist_doc_DATA = tmp/license.txt - -confdir = $(win32datadir)/config -nodist_conf_DATA = \ - tmp/openssl-1.0.0.cnf \ - tmp/client.ovpn \ - tmp/server.ovpn -dist_conf_DATA = \ - sample.ovpn - -easyrsadir = $(win32datadir)/easy-rsa/Windows -nodist_easyrsa_DATA = \ - $(top_srcdir)/easy-rsa/Windows/* - -keysdir = $(win32datadir)/sample-keys -nodist_keys_DATA = \ - $(top_srcdir)/sample-keys/* - -tmp: - mkdir tmp - -tmp/client.ovpn: tmp $(top_srcdir)/sample-config-files/client.conf - cp $(top_srcdir)/sample-config-files/client.conf tmp/client.ovpn - -tmp/server.ovpn: tmp $(top_srcdir)/sample-config-files/server.conf - cp $(top_srcdir)/sample-config-files/server.conf tmp/server.ovpn - -tmp/license.txt: tmp $(top_srcdir)/COPYING $(top_srcdir)/COPYRIGHT.GPL - cat $(top_srcdir)/COPYING $(top_srcdir)/COPYRIGHT.GPL > tmp/license.txt - -tmp/openssl-1.0.0.cnf: tmp $(top_srcdir)/easy-rsa/2.0/openssl-1.0.0.cnf - cp $(top_srcdir)/easy-rsa/2.0/openssl-1.0.0.cnf tmp/openssl-1.0.0.cnf - -clean-local: - -rm -fr tmp - -else - -dist_noinst_DATA += sample.ovpn - -endif - diff --git a/install-win32/build-pkcs11-helper.sh b/install-win32/build-pkcs11-helper.sh deleted file mode 100644 index fd336df..0000000 --- a/install-win32/build-pkcs11-helper.sh +++ /dev/null @@ -1,24 +0,0 @@ -F=pkcs11-helper-1.06-beta1 -OPENSSL_DIR=`pwd`/openssl-0.9.8h - -PKCS11_HELPER_DIR=`pwd`/pkcs11-helper -rm -rf $PKCS11_HELPER_DIR -mkdir $PKCS11_HELPER_DIR -tbz=$F.tar.bz2 - -rm -rf $F -tar xfj $tbz - -cd $F -./configure \ - MAN2HTML=true \ - --disable-crypto-engine-gnutls \ - --disable-crypto-engine-nss \ - PKG_CONFIG=true \ - OPENSSL_CFLAGS="-I${OPENSSL_DIR}/include" \ - OPENSSL_LIBS="-L${OPENSSL_DIR}/out -leay32" - -make -make install DESTDIR="${PKCS11_HELPER_DIR}" - -# ./configure doesn't need this any more: ac_cv_type_size_t=no diff --git a/install-win32/buildinstaller b/install-win32/buildinstaller deleted file mode 100644 index a17a027..0000000 --- a/install-win32/buildinstaller +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -# load version.nsi definitions -. autodefs/defs.sh - -# build the installer -rm -f $GENOUT/*.exe -'/c/Program Files/NSIS/makensis' $GENOUT/nsi/openvpn.nsi &>makensis.log -tail -20 makensis.log - -# sign the installer -if [ -d "$SIGNTOOL" ]; then - python $SIGNTOOL/signapp.py "$(echo $(pwd)/$GENOUT/*.exe)" -fi diff --git a/install-win32/ddk-common b/install-win32/ddk-common deleted file mode 100644 index b45c9e5..0000000 --- a/install-win32/ddk-common +++ /dev/null @@ -1,2 +0,0 @@ -# DDKs <= 5600 use "AMD64", later use "x64" -x64_tag=x64 diff --git a/install-win32/doclean b/install-win32/doclean deleted file mode 100644 index 3f39543..0000000 --- a/install-win32/doclean +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# get version.nsi definitions -. autodefs/defs.sh - -[ "$CLEAN" = "yes" ] && rm -rf $GENOUT && KEEPAUTODEFS="yes" ./doclean diff --git a/install-win32/dosname.pl b/install-win32/dosname.pl deleted file mode 100644 index a678e66..0000000 --- a/install-win32/dosname.pl +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/perl - -# convert a unix filename to a DOS filename - -while ($unixname = shift(@ARGV)) { - $unixname =~ s#^/([a-zA-Z])(/|$)#$1:\\#g; - $unixname =~ s#/#\\#g; - print "$unixname\n"; -} diff --git a/install-win32/getgui b/install-win32/getgui deleted file mode 100644 index aa83e85..0000000 --- a/install-win32/getgui +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# Get and sign the OpenVPN GUI - -# load version.nsi definitions -. autodefs/defs.sh - -GUI="$OPENVPN_GUI_DIR/$OPENVPN_GUI" - -if [ -f "$GUI" ]; then - mkdir -p $GENOUT/bin &>/dev/null - cp $GUI $GENOUT/bin -fi - -if [ -f "$GENOUT/bin/$OPENVPN_GUI" ]; then - echo '!define OPENVPN_GUI_DEFINED' >autodefs/guidefs.nsi -else - cat /dev/null >autodefs/guidefs.nsi -fi diff --git a/install-win32/getopenssl b/install-win32/getopenssl deleted file mode 100644 index b772741..0000000 --- a/install-win32/getopenssl +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# get version.nsi definitions -. autodefs/defs.sh - -# Get OpenSSL binaries -if [ -d "$OPENSSL_DIR" ] ; then - mkdir -p $GENOUT/lib &>/dev/null - mkdir -p $GENOUT/bin &>/dev/null - for f in libeay32.dll libssl32.dll out/openssl.exe ; do - cp $OPENSSL_DIR/$f $GENOUT/lib - if [ -z "$NO_STRIP" ]; then - strip $GENOUT/lib/`basename $f` - fi - done - mv $GENOUT/lib/openssl.exe $GENOUT/bin -else - echo OpenSSL DIR $OPENSSL_DIR NOT FOUND -fi diff --git a/install-win32/getpkcs11helper b/install-win32/getpkcs11helper deleted file mode 100644 index 8fcfdd4..0000000 --- a/install-win32/getpkcs11helper +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# get version.nsi definitions -. autodefs/defs.sh - -# Get PKCS11-helper libraries -if [ -d "$PKCS11_HELPER_DIR" ] ; then - mkdir -p $GENOUT/lib &>/dev/null - for f in libpkcs11-helper-1.dll ; do - cp $PKCS11_HELPER_DIR/usr/local/bin/$f $GENOUT/lib - if [ -z "$NO_STRIP" ]; then - strip $GENOUT/lib/$f - fi - done -else - echo PKCS11-helper DIR $PKCS11_HELPER_DIR NOT FOUND -fi diff --git a/install-win32/getprebuilt b/install-win32/getprebuilt deleted file mode 100644 index 36c4827..0000000 --- a/install-win32/getprebuilt +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# get version.nsi definitions -. autodefs/defs.sh - -# Get PKCS11-helper libraries -if [ -d "$GENOUT_PREBUILT" ] && ! [ -d "$GENOUT" ]; then - echo LOADING prebuilt binaries from $GENOUT_PREBUILT - cp -a $GENOUT_PREBUILT $GENOUT -fi diff --git a/install-win32/getxgui b/install-win32/getxgui deleted file mode 100644 index 3a1e626..0000000 --- a/install-win32/getxgui +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -# Get and sign the OpenVPN XML-based GUI - -# load version.nsi definitions -. autodefs/defs.sh - -if [ -d "$OPENVPN_XGUI_DIR" ]; then - SIGNED_EXES="gui/ovpn-xgui-en.exe sta/ovpn-tray.exe" - UNSIGNED_EXES="xmlserv/ovpn-xmlserv.exe" - EXES="$SIGNED_EXES $UNSIGNED_EXES" - - mkdir -p $GENOUT/bin &>/dev/null - - if [ -z "$NO_STRIP" ]; then - for f in $EXES; do - cp $OPENVPN_XGUI_DIR/$f $GENOUT/bin - strip $GENOUT/bin/`basename $f` - done - fi - - rm -rf $GENOUT/htdocs - cp -a $OPENVPN_XGUI_DIR/ajax/htdocs $GENOUT/htdocs - - echo '!define OPENVPN_XGUI_DEFINED' >autodefs/xguidefs.nsi -else - cat /dev/null >autodefs/xguidefs.nsi -fi diff --git a/install-win32/ifdef.pl b/install-win32/ifdef.pl deleted file mode 100644 index d240ebb..0000000 --- a/install-win32/ifdef.pl +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/perl - -# Simple ifdef/else/endif processor. - -die "usage: ifdef [-C<command-prefix>] [-Dname ...] [control-file ...] " if (@ARGV[0] =~ /^(-h|--help)$/); - -%Parms = (); - -$pre = "!"; -while ($arg=shift(@ARGV)) { - if ($arg =~ /^-/) { - if ($arg =~ /^-D(\w+)$/) { - $Parms{$1} = 1; - } elsif ($arg =~ /-C(.*)$/) { - $pre = $1; - } else { - die "unrecognized option: $arg"; - } - } else { - open(CONTROL, "< $arg") or die "cannot open $arg"; - while (<CONTROL>) { - if (/^!define\s+(\w+)/) { - $Parms{$1} = 1; - } - } - } -} - -sub ifdef { - my ($var, $enabled) = @_; - my $def = 0; - $def = 1 if (defined $Parms{$var}) || ($var eq "true"); - $def = 0 if $var eq "false"; - while (<STDIN>) { - if (/^\s*\Q$pre\Eifdef\s+(\w+)\s*$/) { - return 1 if ifdef ($1, $def & $enabled); - } elsif (/^\s*\Q$pre\Eelseif\s+(\w+)\s*$/) { - $def = $def ^ 1; - return ifdef ($1, $def & $enabled); - } elsif (/^\s*\Q$pre\Eelse\s*$/) { - $def = $def ^ 1; - } elsif (/^\s*\Q$pre\Eendif\s*$/) { - return 0; - } elsif (/^\s*\Q$pre\E/) { - die "unrecognized command: $_"; - } else { - print if $def && $enabled; - } - } - return 1; -} - -ifdef("true", 1); diff --git a/install-win32/m4todef.pl b/install-win32/m4todef.pl deleted file mode 100644 index d2705b0..0000000 --- a/install-win32/m4todef.pl +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/perl - -# used to convert version.m4 to simple -# definition format - -while (<STDIN>) { - chomp; - if (/^\s*$/) { - print "\n"; - } elsif (/^define\((\w+),\[(.*?)\]\)/) { - print "!define $1 \"$2\"\n"; - } elsif (/^dnl(.*)$/) { - print "#$1\n"; - } -} diff --git a/install-win32/macro.pl b/install-win32/macro.pl deleted file mode 100644 index 08ba58a..0000000 --- a/install-win32/macro.pl +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/perl - -# Simple macro processor. - -# Macros are defined in a control file that follows -# a simple definition-based grammar as documented in the -# trans script. Stdin is then copied to stdout, and any -# occurrence of @@MACRO@@ is substituted. Macros can also -# be specified on the command line. - -die "usage: macro [-O<openquote>] [-C<closequote>] [-Dname=var ...] [control-file ...] " if (@ARGV < 1); - -%Parms = (); -$open_quote = "@@"; -$close_quote = "@@"; - -while ($arg=shift(@ARGV)) { - if ($arg =~ /^-/) { - if ($arg =~ /^-D(\w+)(?:=(.*))?$/) { - $Parms{$1} = $2 - } elsif ($arg =~ /-O(.*)$/) { - $open_quote = $1; - } elsif ($arg =~ /-C(.*)$/) { - $close_quote = $1; - } else { - die "unrecognized option: $arg"; - } - } else { - open(CONTROL, "< $arg") or die "cannot open $arg"; - while (<CONTROL>) { - if (/^!define\s+(\w+)(?:\s+['"]?(.*?)['"]?)?\s*$/) { - $Parms{$1} = $2; - } - } - } -} - -sub print_symbol_table { - foreach my $k (sort (keys(%Parms))) { - my $v = $Parms{$k}; - print "[$k] -> \"$v\"\n"; - } -} - -#print_symbol_table (); -#exit 0; - -while (<STDIN>) { - s{ - \Q$open_quote\E - \s* - ( - \w+ - ) - \s* - \Q$close_quote\E - }{ - $Parms{$1} - }xge; - print; -} diff --git a/install-win32/makeopenvpn b/install-win32/makeopenvpn deleted file mode 100644 index c1a805d..0000000 --- a/install-win32/makeopenvpn +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -H=`pwd` - -# get version.nsi definitions -. autodefs/defs.sh - -if gcc --version &>/dev/null && [ -d "$OPENSSL_DIR" ] && [ -d "$LZO_DIR" ] && [ -d "$PKCS11_HELPER_DIR" ]; then - # build OpenVPN binary - - if ! [ -f Makefile ]; then - autoreconf -i -v \ - && ./configure \ - --enable-strict \ - --prefix=$H/windest \ - MAN2HTML=true \ - --with-ssl-headers=$H/$OPENSSL_DIR/include \ - --with-ssl-lib=$H/$OPENSSL_DIR/out \ - --with-lzo-headers=$H/$LZO_DIR/include \ - --with-lzo-lib=$H/$LZO_DIR \ - --with-pkcs11-helper-headers=$H/$PKCS11_HELPER_DIR/usr/local/include \ - --with-pkcs11-helper-lib=$H/$PKCS11_HELPER_DIR/usr/local/lib - fi - - make -j $MAKE_JOBS && make install - - # copy OpenVPN and service executables to GENOUT/bin - mkdir -p $GENOUT/bin &>/dev/null - cp windest/sbin/openvpn.exe $GENOUT/bin - cp windest/sbin/openvpnserv.exe $GENOUT/bin - if [ -z "$NO_STRIP" ]; then - strip $GENOUT/bin/openvpn.exe - strip $GENOUT/bin/openvpnserv.exe - fi -else - echo DID NOT BUILD openvpn.exe and openvpnserv.exe because one or more of gcc, OPENSSL_DIR, LZO_DIR, or PKCS11_HELPER_DIR directories were missing -fi diff --git a/install-win32/maketap b/install-win32/maketap deleted file mode 100644 index b9c4070..0000000 --- a/install-win32/maketap +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# Get the x86 and x64 versions of the TAP driver - -# get version.nsi definitions -. autodefs/defs.sh - -if [ -d "$TAPBINSRC" ]; then - mkdir -p $GENOUT/driver/i386 &>/dev/null - mkdir -p $GENOUT/driver/amd64 &>/dev/null - for arch in i386 amd64; do - s=$TAPBINSRC/$arch - cp $s/*.sys $s/*.cat $s/*.inf $GENOUT/driver/$arch - done -else - echo Cannot find pre-built tap drivers -fi diff --git a/install-win32/maketapinstall b/install-win32/maketapinstall deleted file mode 100644 index 9fe0470..0000000 --- a/install-win32/maketapinstall +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# Get the x86 and x64 versions of the tapinstall tool - -# get version.nsi definitions -. autodefs/defs.sh - -if [ -d "$TAPBINSRC" ]; then - mkdir -p $GENOUT/tapinstall/i386 &>/dev/null - mkdir -p $GENOUT/tapinstall/amd64 &>/dev/null - cp $TAPBINSRC/i386/tapinstall.exe $GENOUT/tapinstall/i386 - cp $TAPBINSRC/amd64/tapinstall.exe $GENOUT/tapinstall/amd64 -else - echo Cannot find pre-built tapinstall -fi diff --git a/install-win32/maketext b/install-win32/maketext deleted file mode 100644 index 9a94a81..0000000 --- a/install-win32/maketext +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh - -# get version.nsi definitions -. autodefs/defs.sh - -mkdir -p $GENOUT/text &>/dev/null - -# build license file -cat COPYING COPYRIGHT.GPL >$GENOUT/text/license.txt - -# copy install file -cp INSTALL-win32.txt $GENOUT/text/INSTALL-win32.txt - -# copy sample configuration files and docs -s=$GENOUT/samples -mkdir -p $s &>/dev/null -cp sample-config-files/client.conf $s/client.$PRODUCT_FILE_EXT -cp sample-config-files/server.conf $s/server.$PRODUCT_FILE_EXT -cp install-win32/sample.ovpn $s/sample.$PRODUCT_FILE_EXT - -# get easy-rsa (Windows) -e=$GENOUT/easy-rsa -mkdir -p $e &>/dev/null -cp easy-rsa/1.0/openssl.cnf $e/openssl.cnf.sample -cp easy-rsa/Windows/* $e - -# get images -i=$GENOUT/images -mkdir -p $i &>/dev/null -cp images/*.ico $i -cp images/*.bmp $i - -# get NSI files -n=$GENOUT/nsi -mkdir -p $n &>/dev/null -cp autodefs/defs.nsi $n -cp autodefs/guidefs.nsi $n -cp autodefs/xguidefs.nsi $n -cp install-win32/openvpn.nsi $n -cp install-win32/setpath.nsi $n -cp install-win32/GetWindowsVersion.nsi $n - -if [ -n "$EXTRACT_FILES" ]; then - cp "$EXTRACT_FILES/MultiFileExtract.nsi" $n -fi - -# get OpenVPN client config files -if [ -n "$SAMPCONF_DIR" ]; then - c=$GENOUT/conf - mkdir -p $c &>/dev/null - test -n "$SAMPCONF_CONF" && cp "../$SAMPCONF_DIR/$SAMPCONF_CONF" $c - test -n "$SAMPCONF_CONF2" && cp "../$SAMPCONF_DIR/$SAMPCONF_CONF2" $c - test -n "$SAMPCONF_P12" && cp "../$SAMPCONF_DIR/$SAMPCONF_P12" $c - test -n "$SAMPCONF_TA" && cp "../$SAMPCONF_DIR/$SAMPCONF_TA" $c - test -n "$SAMPCONF_CA" && cp "../$SAMPCONF_DIR/$SAMPCONF_CA" $c - test -n "$SAMPCONF_CRT" && cp "../$SAMPCONF_DIR/$SAMPCONF_CRT" $c - test -n "$SAMPCONF_KEY" && cp "../$SAMPCONF_DIR/$SAMPCONF_KEY" $c - test -n "$SAMPCONF_DH" && cp "../$SAMPCONF_DIR/$SAMPCONF_DH" $c -fi diff --git a/install-win32/openssl/README.txt b/install-win32/openssl/README.txt deleted file mode 100644 index 6a042f4..0000000 --- a/install-win32/openssl/README.txt +++ /dev/null @@ -1,21 +0,0 @@ -Rebuild OpenSSL tarball without symbolic links, so -it can be extracted on Windows (run on Unix): - - [download tarball and .asc sig] - gpg --verify openssl-0.9.8k.tar.gz.asc - tar xfz openssl-0.9.8k.tar.gz - tar cfzh openssl-0.9.8k-nolinks.tar.gz openssl-0.9.8k - -To apply patch (in MSYS shell): - - cd /c/src/openssl-0.9.8k - patch -p1 <../21/install-win32/openssl/openssl098.patch - -To build OpenSSL, open a command prompt window, then: - - cd \src\openssl-0.9.8k - ms\mw - -To build a new patch (optional): - - diff -urw openssl-0.9.8k.orig openssl-0.9.8k | grep -v '^Only in' >openssl098.patch diff --git a/install-win32/openssl/openssl097.patch b/install-win32/openssl/openssl097.patch deleted file mode 100644 index ccef40a..0000000 --- a/install-win32/openssl/openssl097.patch +++ /dev/null @@ -1,68 +0,0 @@ -[in msys bash window] -cd /c/src/openssl-0.9.7m -patch -p1 <../21/install-win32/openssl.patch - -[open command prompt window] -cd \src\openssl-0.9.7m -ms\mw - -diff -wur openssl-0.9.7m.orig/ms/mw.bat openssl-0.9.7m/ms/mw.bat ---- openssl-0.9.7m.orig/ms/mw.bat Sat Feb 22 11:02:46 2003 -+++ openssl-0.9.7m/ms/mw.bat Mon Jan 21 23:12:34 2008 -@@ -1,17 +1,23 @@ - @rem OpenSSL with Mingw32 - @rem -------------------- - -+@rem Include MinGW, MSYS, and ActiveState Perl in path -+set PATH=c:\perl\bin;c:\MinGW\bin;c:\msys\1.0\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem -+ - @rem Makefile - perl util\mkfiles.pl >MINFO --perl util\mk1mf.pl Mingw32 >ms\mingw32.mak -+perl util\mk1mf.pl no-idea no-mdc2 no-rc5 Mingw32 >ms\mingw32.mak -+ - @rem DLL definition files --perl util\mkdef.pl 32 libeay >ms\libeay32.def -+perl util\mkdef.pl no-idea no-mdc2 no-rc5 32 libeay >ms\libeay32.def - if errorlevel 1 goto end --perl util\mkdef.pl 32 ssleay >ms\ssleay32.def -+perl util\mkdef.pl no-idea no-mdc2 no-rc5 32 ssleay >ms\ssleay32.def - if errorlevel 1 goto end - - @rem Build the libraries --make -f ms/mingw32.mak -+ -+@rem JY added --win32 flag -+make --win32 -f ms/mingw32.mak - if errorlevel 1 goto end - - @rem Generate the DLLs and input libraries -@@ -20,7 +26,9 @@ - dllwrap --dllname libssl32.dll --output-lib out/libssl32.a --def ms/ssleay32.def out/libssl.a out/libeay32.a - if errorlevel 1 goto end - -+@rem JY added openssl.exe linked to DLL -+gcc -o openssl tmp\verify.o tmp\asn1pars.o tmp\req.o tmp\dgst.o tmp\dh.o tmp\dhparam.o tmp\enc.o tmp\passwd.o tmp\gendh.o tmp\errstr.o tmp\ca.o tmp\pkcs7.o tmp\crl2p7.o tmp\crl.o tmp\rsa.o tmp\rsautl.o tmp\dsa.o tmp\dsaparam.o tmp\x509.o tmp\genrsa.o tmp\gendsa.o tmp\s_server.o tmp\s_client.o tmp\speed.o tmp\s_time.o tmp\apps.o tmp\s_cb.o tmp\s_socket.o tmp\app_rand.o tmp\version.o tmp\sess_id.o tmp\ciphers.o tmp\nseq.o tmp\pkcs12.o tmp\pkcs8.o tmp\spkac.o tmp\smime.o tmp\rand.o tmp\engine.o tmp\ocsp.o tmp\prime.o tmp\openssl.o -leay32 -lssl32 -L. -lwsock32 -lgdi32 -+ - echo Done compiling OpenSSL - - :end -- -diff -wur openssl-0.9.7m.orig/util/pl/Mingw32.pl openssl-0.9.7m/util/pl/Mingw32.pl ---- openssl-0.9.7m.orig/util/pl/Mingw32.pl Sun May 16 23:28:32 2004 -+++ openssl-0.9.7m/util/pl/Mingw32.pl Mon Jan 21 17:52:36 2008 -@@ -99,10 +99,10 @@ - $n=&bname($target); - $ret.="$target: $files $dep_libs\n"; - $ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n"; -- if (defined $sha1file) -- { -- $ret.="\t$openssl sha1 -hmac etaonrishdlcupfm -binary $target > $sha1file"; -- } -+# if (defined $sha1file) -+# { -+# $ret.="\t$openssl sha1 -hmac etaonrishdlcupfm -binary $target > $sha1file"; -+# } - $ret.="\n"; - return($ret); - } diff --git a/install-win32/openssl/openssl098.patch b/install-win32/openssl/openssl098.patch deleted file mode 100644 index 653d2fe..0000000 --- a/install-win32/openssl/openssl098.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff -urw tmp/openssl-0.9.8h/crypto/pqueue/pqueue.c openssl-0.9.8h/crypto/pqueue/pqueue.c ---- tmp/openssl-0.9.8h/crypto/pqueue/pqueue.c Tue Jun 28 06:53:34 2005 -+++ openssl-0.9.8h/crypto/pqueue/pqueue.c Wed Jun 4 02:52:42 2008 -@@ -199,10 +199,10 @@ - return found; - } - --#if PQ_64BIT_IS_INTEGER - void - pqueue_print(pqueue_s *pq) - { -+#if PQ_64BIT_IS_INTEGER - pitem *item = pq->items; - - while(item != NULL) -@@ -210,8 +210,8 @@ - printf("item\t" PQ_64BIT_PRINT "\n", item->priority); - item = item->next; - } -- } - #endif -+ } - - pitem * - pqueue_iterator(pqueue_s *pq) -diff -urw tmp/openssl-0.9.8h/ms/mw.bat openssl-0.9.8h/ms/mw.bat ---- tmp/openssl-0.9.8h/ms/mw.bat Sat Feb 22 11:00:10 2003 -+++ openssl-0.9.8h/ms/mw.bat Wed Jun 4 02:56:54 2008 -@@ -1,17 +1,23 @@ - @rem OpenSSL with Mingw32 - @rem -------------------- - -+@rem Include MinGW, MSYS, and ActiveState Perl in path -+set PATH=c:\bin;C:\Perl\bin\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\MinGW\bin;c:\msys\1.0\bin -+ - @rem Makefile - perl util\mkfiles.pl >MINFO --perl util\mk1mf.pl Mingw32 >ms\mingw32.mak -+perl util\mk1mf.pl no-idea no-mdc2 no-rc5 Mingw32 >ms\mingw32.mak -+ - @rem DLL definition files --perl util\mkdef.pl 32 libeay >ms\libeay32.def -+perl util\mkdef.pl no-idea no-mdc2 no-rc5 32 libeay >ms\libeay32.def - if errorlevel 1 goto end --perl util\mkdef.pl 32 ssleay >ms\ssleay32.def -+perl util\mkdef.pl no-idea no-mdc2 no-rc5 32 ssleay >ms\ssleay32.def - if errorlevel 1 goto end - - @rem Build the libraries --make -f ms/mingw32.mak -+ -+@rem JY added --win32 -+make --win32 -f ms/mingw32.mak - if errorlevel 1 goto end - - @rem Generate the DLLs and input libraries diff --git a/install-win32/openvpn.nsi b/install-win32/openvpn.nsi deleted file mode 100755 index f06c5aa..0000000 --- a/install-win32/openvpn.nsi +++ /dev/null @@ -1,886 +0,0 @@ -; **************************************************************************** -; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * -; * 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. * -; **************************************************************************** - -; OpenVPN install script for Windows, using NSIS - -SetCompressor lzma - -!include "MUI.nsh" - -!include "defs.nsi" -!include "guidefs.nsi" -!include "xguidefs.nsi" -!include "setpath.nsi" -!include "GetWindowsVersion.nsi" - -!ifdef EXTRACT_FILES -!include "MultiFileExtract.nsi" -!endif - -!define GEN ".." -!define BIN "${GEN}\bin" -!define LIB "${GEN}\lib" - -; Which GUI to use (XGUI has priority). -; We will define either USE_XGUI (XML-based version) or -; USE_GUI (Mathias Sundman version) but not both. -!ifdef OPENVPN_XGUI_DEFINED -!define USE_XGUI -!else -!ifdef OPENVPN_GUI_DEFINED -!define USE_GUI -!endif -!endif - -!define PRODUCT_ICON "icon.ico" - -!ifdef USE_XGUI -!define XGUI_POSTFIX "X" -!else -!define XGUI_POSTFIX "" -!endif - -!ifdef PRODUCT_TAP_DEBUG -!define DBG_POSTFIX "-DBG" -!else -!define DBG_POSTFIX "" -!endif - -!define VERSION "${PRODUCT_VERSION}${XGUI_POSTFIX}${DBG_POSTFIX}" - -!define TAP "${PRODUCT_TAP_ID}" -!define TAPDRV "${TAP}.sys" - -; Default service settings -!define SERV_CONFIG_DIR "$INSTDIR\config" -!define SERV_CONFIG_EXT "${PRODUCT_FILE_EXT}" -!define SERV_EXE_PATH "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" -!define SERV_LOG_DIR "$INSTDIR\log" -!define SERV_PRIORITY "NORMAL_PRIORITY_CLASS" -!define SERV_LOG_APPEND "0" - -; XGUI variables -!define XGUI_EXE ovpn-xgui-en.exe -!define XGUI_TRAY ovpn-tray.exe -!define XGUI_XMLSERV ovpn-xmlserv.exe -!define XGUI_HTDOCS htdocs - -!define XGUI_AJAX_GUI_NAME "${PRODUCT_NAME} Ajax GUI" -!define XGUI_TRANSITION_GUI_NAME "${PRODUCT_NAME} Transitional GUI" - -;-------------------------------- -;Configuration - - ;General - - OutFile "${GEN}\${PRODUCT_UNIX_NAME}-${VERSION}${OUTFILE_LABEL}-install.exe" - - ShowInstDetails show - ShowUninstDetails show - - ;Folder selection page - InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" - - ;Remember install folder - InstallDirRegKey HKCU "Software\${PRODUCT_NAME}" "" - -;-------------------------------- -;Modern UI Configuration - - Name "${PRODUCT_NAME} ${VERSION} ${TITLE_LABEL}" - - !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of ${PRODUCT_NAME}, an Open Source VPN package by James Yonan.\r\n\r\nNote that the Windows version of ${PRODUCT_NAME} will only run on Win 2000, XP, or higher.\r\n\r\n\r\n" - - !define MUI_COMPONENTSPAGE_TEXT_TOP "Select the components to install/upgrade. Stop any ${PRODUCT_NAME} processes or the ${PRODUCT_NAME} service if it is running. All DLLs are installed locally." - - !define MUI_COMPONENTSPAGE_SMALLDESC - !ifdef USE_XGUI - !define MUI_FINISHPAGE_SHOWREADME "http://openvpn.net/" - !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED - !else - !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\INSTALL-win32.txt" - !endif - !define MUI_FINISHPAGE_NOAUTOCLOSE - !define MUI_ABORTWARNING - !define MUI_ICON "${GEN}\images\${PRODUCT_ICON}" - !define MUI_UNICON "${GEN}\images\${PRODUCT_ICON}" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "${GEN}\images\install-whirl.bmp" - !define MUI_UNFINISHPAGE_NOAUTOCLOSE - - !insertmacro MUI_PAGE_WELCOME - !insertmacro MUI_PAGE_LICENSE "${GEN}\text\license.txt" - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_UNPAGE_FINISH - - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -;Language Strings - - LangString DESC_SecOpenVPNUserSpace ${LANG_ENGLISH} "Install ${PRODUCT_NAME} user-space components, including ${PRODUCT_UNIX_NAME}.exe." - -!ifdef USE_GUI - LangString DESC_SecOpenVPNGUI ${LANG_ENGLISH} "Install ${PRODUCT_NAME} GUI by Mathias Sundman" -!endif - -!ifdef USE_XGUI - LangString DESC_SecOpenVPNXGUI ${LANG_ENGLISH} "Install ${PRODUCT_NAME} XML-based GUI" -!endif - - LangString DESC_SecOpenVPNEasyRSA ${LANG_ENGLISH} "Install ${PRODUCT_NAME} RSA scripts for X509 certificate management." - - LangString DESC_SecOpenSSLDLLs ${LANG_ENGLISH} "Install OpenSSL DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecPKCS11DLLs ${LANG_ENGLISH} "Install PKCS#11 helper DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP virtual device driver. Will not interfere with CIPE." - - LangString DESC_SecService ${LANG_ENGLISH} "Install the ${PRODUCT_NAME} service wrapper (${PRODUCT_UNIX_NAME}serv.exe)" - - LangString DESC_SecOpenSSLUtilities ${LANG_ENGLISH} "Install the OpenSSL Utilities (used for generating public/private key pairs)." - - LangString DESC_SecAddPath ${LANG_ENGLISH} "Add ${PRODUCT_NAME} executable directory to the current user's PATH." - - LangString DESC_SecAddShortcuts ${LANG_ENGLISH} "Add ${PRODUCT_NAME} shortcuts to the current user's Start Menu." - - LangString DESC_SecFileAssociation ${LANG_ENGLISH} "Register ${PRODUCT_NAME} config file association (*.${SERV_CONFIG_EXT})" - -;-------------------------------- -;Reserve Files - - ;Things that need to be extracted on first (keep these lines before any File command!) - ;Only useful for BZIP2 compression - - ReserveFile "${GEN}\images\install-whirl.bmp" - -;-------------------------------- -;Macros - -!macro WriteRegStringIfUndef ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 "" +1 +2 -WriteRegStr "${ROOT}" "${SUBKEY}" "${KEY}" '${VALUE}' -Pop $R0 -!macroend - -!macro DelRegStringIfUnchanged ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegValue "${ROOT}" "${SUBKEY}" "${KEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfUnchanged ROOT SUBKEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegKey "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfEmpty ROOT SUBKEY -Push $R0 -EnumRegValue $R0 "${ROOT}" "${SUBKEY}" 1 -StrCmp $R0 "" +1 +2 -DeleteRegKey /ifempty "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -;------------------------------------------ -;Set reboot flag based on tapinstall return - -Function CheckReboot - IntCmp $R0 1 "" noreboot noreboot - IntOp $R0 0 & 0 - SetRebootFlag true - DetailPrint "REBOOT flag set" - noreboot: -FunctionEnd - -;-------------------------------- -;Installer Sections - -Function .onInit - ClearErrors - -# Verify that user has admin privs - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to install ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: - -# Delete previous start menu - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - -!ifdef CHECK_WINDOWS_VERSION -# Check windows version - Call GetWindowsVersion - Pop $1 - StrCmp $1 "2000" goodwinver - StrCmp $1 "XP" goodwinver - StrCmp $1 "2003" goodwinver - StrCmp $1 "VISTA" goodwinver - - Messagebox MB_OK "Sorry, ${PRODUCT_NAME} does not currently support Windows $1" - Abort - -goodwinver: - System::Call "kernel32::GetCurrentProcess() i .s" - System::Call "kernel32::IsWow64Process(i s, *i .r0)" - IntCmp $0 0 init32bits - - ; we are running on 64-bit windows - StrCmp $1 "VISTA" vista64bummer - -# Messagebox MB_OK "Sorry, ${PRODUCT_NAME} doesn't currently support 64-bit Windows." -# Abort - -vista64bummer: - -# Messagebox MB_OK "Sorry, ${PRODUCT_NAME} doesn't currently support 64-bit Vista because Microsoft doesn't allow the installation of 64 bit unsigned drivers." -# Abort - -init32bits: - -!endif - -FunctionEnd - -!ifndef SF_SELECTED -!define SF_SELECTED 1 -!endif - -;-------------------- -;Pre-install section - -Section -pre - - ; Stop OpenVPN if currently running - DetailPrint "Previous Service REMOVE (if exists)" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - -!ifdef USE_XGUI - DetailPrint "Previous XML Service REMOVE (if exists)" - nsExec::ExecToLog '"$INSTDIR\bin\${XGUI_XMLSERV}" -remove' - Pop $R0 # return value/error/timeout -!endif - - Sleep 3000 - -SectionEnd - -Section "${PRODUCT_NAME} User-Space Components" SecOpenVPNUserSpace - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${PRODUCT_UNIX_NAME}.exe" - -SectionEnd - -!ifdef USE_GUI -Section "${PRODUCT_NAME} GUI" SecOpenVPNGUI - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${OPENVPN_GUI}" - -SectionEnd -!endif - -!ifdef USE_XGUI -Section "${PRODUCT_NAME} XML-based GUI" SecOpenVPNXGUI - - SetOverwrite on - - SetOutPath "$INSTDIR\bin" - File "${BIN}\${XGUI_EXE}" - File "${BIN}\${XGUI_TRAY}" - File "${BIN}\${XGUI_XMLSERV}" - - SetOutPath "$INSTDIR\${XGUI_HTDOCS}" - File "${GEN}\${XGUI_HTDOCS}\*.*" - -SectionEnd -!endif - -Section "${PRODUCT_NAME} RSA Certificate Management Scripts" SecOpenVPNEasyRSA - - SetOverwrite on - SetOutPath "$INSTDIR\easy-rsa" - - File "${GEN}\easy-rsa\openssl-1.0.0.cnf" - File "${GEN}\easy-rsa\vars.bat.sample" - - File "${GEN}\easy-rsa\init-config.bat" - - File "${GEN}\easy-rsa\README.txt" - File "${GEN}\easy-rsa\build-ca.bat" - File "${GEN}\easy-rsa\build-dh.bat" - File "${GEN}\easy-rsa\build-key-server.bat" - File "${GEN}\easy-rsa\build-key.bat" - File "${GEN}\easy-rsa\build-key-pkcs12.bat" - File "${GEN}\easy-rsa\clean-all.bat" - File "${GEN}\easy-rsa\index.txt.start" - File "${GEN}\easy-rsa\revoke-full.bat" - File "${GEN}\easy-rsa\serial.start" - -SectionEnd - -Section "${PRODUCT_NAME} Service" SecService - - SetOverwrite on - - SetOutPath "$INSTDIR\bin" - File "${BIN}\${PRODUCT_UNIX_NAME}serv.exe" - - SetOutPath "$INSTDIR\config" - - FileOpen $R0 "$INSTDIR\config\README.txt" w - FileWrite $R0 "This directory should contain ${PRODUCT_NAME} configuration files$\r$\n" - FileWrite $R0 "each having an extension of .${SERV_CONFIG_EXT}$\r$\n" - FileWrite $R0 "$\r$\n" - FileWrite $R0 "When ${PRODUCT_NAME} is started as a service, a separate ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "process will be instantiated for each configuration file.$\r$\n" - FileClose $R0 - - SetOutPath "$INSTDIR\sample-config" - File "${GEN}\samples\sample.${SERV_CONFIG_EXT}" - File "${GEN}\samples\client.${SERV_CONFIG_EXT}" - File "${GEN}\samples\server.${SERV_CONFIG_EXT}" - - CreateDirectory "$INSTDIR\log" - FileOpen $R0 "$INSTDIR\log\README.txt" w - FileWrite $R0 "This directory will contain the log files for ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "sessions which are being run as a service.$\r$\n" - FileClose $R0 - -SectionEnd - -Section "${PRODUCT_NAME} File Associations" SecFileAssociation -SectionEnd - -Section "OpenSSL DLLs" SecOpenSSLDLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${LIB}\libeay32.dll" - File "${LIB}\libssl32.dll" - -SectionEnd - -Section "OpenSSL Utilities" SecOpenSSLUtilities - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\openssl.exe" - -SectionEnd - -Section "PKCS#11 DLLs" SecPKCS11DLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${LIB}\libpkcs11-helper-1.dll" - -SectionEnd - -Section "TAP Virtual Ethernet Adapter" SecTAP - - SetOverwrite on - - FileOpen $R0 "$INSTDIR\bin\addtap.bat" w - FileWrite $R0 "rem Add a new TAP virtual ethernet adapter$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - FileOpen $R0 "$INSTDIR\bin\deltapall.bat" w - FileWrite $R0 "echo WARNING: this script will delete ALL TAP virtual adapters (use the device manager to delete adapters one at a time)$\r$\n" - FileWrite $R0 "pause$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - ; Check if we are running on a 64 bit system. - System::Call "kernel32::GetCurrentProcess() i .s" - System::Call "kernel32::IsWow64Process(i s, *i .r0)" - IntCmp $0 0 tap-32bit - -; tap-64bit: - - DetailPrint "We are running on a 64-bit system." - - SetOutPath "$INSTDIR\bin" - - File "${GEN}\tapinstall\amd64\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - - File "${GEN}\driver\amd64\OemWin2k.inf" - File "${GEN}\driver\amd64\${PRODUCT_TAP_ID}.cat" - File "${GEN}\driver\amd64\${TAPDRV}" - -goto tapend - -tap-32bit: - - DetailPrint "We are running on a 32-bit system." - - SetOutPath "$INSTDIR\bin" - File "${GEN}\tapinstall\i386\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - File "${GEN}\driver\i386\OemWin2k.inf" - File "${GEN}\driver\i386\${PRODUCT_TAP_ID}.cat" - File "${GEN}\driver\i386\${TAPDRV}" - - tapend: - -SectionEnd - -Section "Add ${PRODUCT_NAME} to PATH" SecAddPath - - ; remove previously set path (if any) - Push "$INSTDIR\bin" - Call RemoveFromPath - - ; append our bin directory to end of current user path - Push "$INSTDIR\bin" - Call AddToPath - -SectionEnd - -Section "Add Shortcuts to Start Menu" SecAddShortcuts - - SetOverwrite on - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Documentation" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Windows Notes.url" "InternetShortcut" "URL" "http://openvpn.net/INSTALL-win32.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Manual Page.url" "InternetShortcut" "URL" "http://openvpn.net/man.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} HOWTO.url" "InternetShortcut" "URL" "http://openvpn.net/howto.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Web Site.url" "InternetShortcut" "URL" "http://openvpn.net/" - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk" "$INSTDIR\Uninstall.exe" - -SectionEnd - -;-------------------- -;Post-install section - -Section -post - - SetOverwrite on - - ; delete old devcon.exe - Delete "$INSTDIR\bin\devcon.exe" - - ; Store README, license, icon - SetOverwrite on - SetOutPath $INSTDIR - !ifndef USE_XGUI - File "${GEN}\text\INSTALL-win32.txt" - !endif - File "${GEN}\text\license.txt" - File "${GEN}\images\${PRODUCT_ICON}" - - ; store sample config files - !ifdef SAMPCONF_DIR - SetOverwrite on - SetOutPath "$INSTDIR\config" - !ifdef SAMPCONF_CONF - File "${GEN}\conf\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - File "${GEN}\conf\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - File "${GEN}\conf\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - File "${GEN}\conf\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - File "${GEN}\conf\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - File "${GEN}\conf\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - File "${GEN}\conf\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - File "${GEN}\conf\${SAMPCONF_DH}" - !endif - !endif - - ; Try to extract files if present - !ifdef EXTRACT_FILES - Push "$INSTDIR" - Call MultiFileExtract - Pop $R0 - IntCmp $R0 0 +3 +1 +1 - DetailPrint "MultiFileExtract Failed status=$R0" - goto +2 - DetailPrint "MultiFileExtract Succeeded" - !endif - - ; - ; install/upgrade TAP driver if selected, using tapinstall.exe - ; - SectionGetFlags ${SecTAP} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" notap notap - ; TAP install/update was selected. - ; Should we install or update? - ; If tapinstall error occurred, $5 will - ; be nonzero. - IntOp $5 0 & 0 - nsExec::ExecToStack '"$INSTDIR\bin\tapinstall.exe" hwids ${TAP}' - Pop $R0 # return value/error/timeout - IntOp $5 $5 | $R0 - DetailPrint "tapinstall hwids returned: $R0" - - ; If tapinstall output string contains "${TAP}" we assume - ; that TAP device has been previously installed, - ; therefore we will update, not install. - Push "${TAP}" - Call StrStr - Pop $R0 - - IntCmp $5 0 "" tapinstall_check_error tapinstall_check_error - IntCmp $R0 -1 tapinstall - - ;tapupdate: - DetailPrint "TAP UPDATE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" update "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall update returned: $R0" - Goto tapinstall_check_error - - tapinstall: - DetailPrint "TAP REMOVE OLD TAP" - - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove TAP0801' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove TAP0801 returned: $R0" - - DetailPrint "TAP INSTALL (${TAP})" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall install returned: $R0" - - tapinstall_check_error: - DetailPrint "tapinstall cumulative status: $5" - IntCmp $5 0 notap - MessageBox MB_OK "An error occurred installing the TAP device driver." - - notap: - - ; Store install folder in registry - WriteRegStr HKLM SOFTWARE\${PRODUCT_NAME} "" $INSTDIR - - ; install as a service if requested - SectionGetFlags ${SecService} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noserv noserv - - ; set registry parameters for openvpnserv - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_dir" "${SERV_CONFIG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_ext" "${SERV_CONFIG_EXT}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "exe_path" "${SERV_EXE_PATH}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_dir" "${SERV_LOG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "priority" "${SERV_PRIORITY}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_append" "${SERV_LOG_APPEND}" - - ; install openvpnserv as a service (to be started manually from service control manager) - DetailPrint "Service INSTALL" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -install' - Pop $R0 # return value/error/timeout - - noserv: - !ifdef USE_XGUI - IfFileExists "$INSTDIR\bin\${XGUI_XMLSERV}" "" fileass - ; install and automatically start XML service - DetailPrint "XML Service INSTALL" - nsExec::ExecToLog '"$INSTDIR\bin\${XGUI_XMLSERV}" -install' - Pop $R0 # return value/error/timeout - - Sleep 2000 - - DetailPrint "XML Service START" - nsExec::ExecToLog '"$INSTDIR\bin\${XGUI_XMLSERV}" -start' - Pop $R0 # return value/error/timeout - - !endif - - ; Create file association if requested - fileass: - SectionGetFlags ${SecFileAssociation} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noass noass - WriteRegStr HKCR ".${SERV_CONFIG_EXT}" "" "${PRODUCT_NAME}File" - WriteRegStr HKCR "${PRODUCT_NAME}File" "" "${PRODUCT_NAME} Config File" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell" "" "open" - WriteRegStr HKCR "${PRODUCT_NAME}File\DefaultIcon" "" "$INSTDIR\${PRODUCT_ICON},0" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\open\command" "" 'notepad.exe "%1"' - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run" "" "Start ${PRODUCT_NAME} on this config file" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run\command" "" '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" --pause-exit --config "%1"' - - ; Create start menu folders - noass: - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Utilities" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts" - - ; Create start menu and desktop shortcuts to OpenVPN GUI - !ifdef USE_GUI - IfFileExists "$INSTDIR\bin\${OPENVPN_GUI}" "" tryaddxgui - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" "" - CreateShortcut "$DESKTOP\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" - !endif - - ; Create start menu and desktop shortcuts to OpenVPN XGUI - tryaddxgui: - !ifdef USE_XGUI - IfFileExists "$INSTDIR\bin\${XGUI_EXE}" "" tryaddtray - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${XGUI_TRANSITION_GUI_NAME}.lnk" "$INSTDIR\bin\${XGUI_EXE}" "" -# CreateShortcut "$DESKTOP\${XGUI_TRANSITION_GUI_NAME}.lnk" "$INSTDIR\bin\${XGUI_EXE}" - tryaddtray: - IfFileExists "$INSTDIR\bin\${XGUI_TRAY}" "" tryaddtap - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${XGUI_AJAX_GUI_NAME}.lnk" "$INSTDIR\bin\${XGUI_EXE}" "" - CreateShortcut "$DESKTOP\${XGUI_AJAX_GUI_NAME}.lnk" "$INSTDIR\bin\${XGUI_TRAY}" - !endif - - ; Create start menu shortcuts to addtap.bat and deltapall.bat - tryaddtap: - IfFileExists "$INSTDIR\bin\addtap.bat" "" trydeltap - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Add a new TAP virtual ethernet adapter.lnk" "$INSTDIR\bin\addtap.bat" "" - - trydeltap: - IfFileExists "$INSTDIR\bin\deltapall.bat" "" config_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Delete ALL TAP virtual ethernet adapters.lnk" "$INSTDIR\bin\deltapall.bat" "" - - ; Create start menu shortcuts for config and log directories - config_shortcut: - IfFileExists "$INSTDIR\config" "" log_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} configuration file directory.lnk" "$INSTDIR\config" "" - - log_shortcut: - IfFileExists "$INSTDIR\log" "" samp_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} log file directory.lnk" "$INSTDIR\log" "" - - samp_shortcut: - IfFileExists "$INSTDIR\sample-config" "" genkey_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} Sample Configuration Files.lnk" "$INSTDIR\sample-config" "" - - genkey_shortcut: - IfFileExists "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" "" noshortcuts - IfFileExists "$INSTDIR\config" "" noshortcuts - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Generate a static ${PRODUCT_NAME} key.lnk" "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" '--pause-exit --verb 3 --genkey --secret "$INSTDIR\config\key.txt"' "$INSTDIR\${PRODUCT_ICON}" 0 - - noshortcuts: - ; Create uninstaller - WriteUninstaller "$INSTDIR\Uninstall.exe" - - ; Show up in Add/Remove programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME} ${VERSION}" - WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\${PRODUCT_ICON}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${VERSION}" - - ; Advise a reboot - ;Messagebox MB_OK "IMPORTANT: Rebooting the system is advised in order to finalize TAP driver installation/upgrade (this is an informational message only, pressing OK will not reboot)." - -SectionEnd - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNUserSpace} $(DESC_SecOpenVPNUserSpace) - !ifdef USE_GUI - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNGUI} $(DESC_SecOpenVPNGUI) - !endif - !ifdef USE_XGUI - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNXGUI} $(DESC_SecOpenVPNXGUI) - !endif - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNEasyRSA} $(DESC_SecOpenVPNEasyRSA) - !insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLUtilities} $(DESC_SecOpenSSLUtilities) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLDLLs} $(DESC_SecOpenSSLDLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecPKCS11DLLs} $(DESC_SecPKCS11DLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddPath} $(DESC_SecAddPath) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddShortcuts} $(DESC_SecAddShortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService) - !insertmacro MUI_DESCRIPTION_TEXT ${SecFileAssociation} $(DESC_SecFileAssociation) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;-------------------------------- -;Uninstaller Section - -Function un.onInit - ClearErrors - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to uninstall ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: -FunctionEnd - -Section "Uninstall" - -!ifdef USE_XGUI - DetailPrint "XML Service REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\${XGUI_XMLSERV}" -remove' - Pop $R0 # return value/error/timeout -!endif - - ; Stop OpenVPN if currently running - DetailPrint "Service REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - - Sleep 3000 - - DetailPrint "TAP REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove returned: $R0" - - Push "$INSTDIR\bin" - Call un.RemoveFromPath - - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - - ; delete sample config files - !ifdef SAMPCONF_DIR - !ifdef SAMPCONF_CONF - Delete "$INSTDIR\config\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - Delete "$INSTDIR\config\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - Delete "$INSTDIR\config\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - Delete "$INSTDIR\config\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - Delete "$INSTDIR\config\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - Delete "$INSTDIR\config\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - Delete "$INSTDIR\config\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - Delete "$INSTDIR\config\${SAMPCONF_DH}" - !endif - !endif - - !ifdef USE_GUI - Delete "$INSTDIR\bin\${OPENVPN_GUI}" - Delete "$DESKTOP\${PRODUCT_NAME} GUI.lnk" - !endif - - !ifdef USE_XGUI - Delete "$INSTDIR\bin\${XGUI_EXE}" - Delete "$INSTDIR\bin\${XGUI_TRAY}" - Delete "$INSTDIR\bin\${XGUI_XMLSERV}" - RMDir /r "$INSTDIR\${XGUI_HTDOCS}" - Delete "$DESKTOP\${XGUI_AJAX_GUI_NAME}.lnk" - Delete "$DESKTOP\${XGUI_TRANSITION_GUI_NAME}.lnk" - !endif - - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" - Delete "$INSTDIR\bin\libeay32.dll" - Delete "$INSTDIR\bin\libssl32.dll" - Delete "$INSTDIR\bin\libpkcs11-helper-1.dll" - Delete "$INSTDIR\bin\tapinstall.exe" - Delete "$INSTDIR\bin\addtap.bat" - Delete "$INSTDIR\bin\deltapall.bat" - - Delete "$INSTDIR\config\README.txt" - Delete "$INSTDIR\config\sample.${SERV_CONFIG_EXT}.txt" - - Delete "$INSTDIR\log\README.txt" - - Delete "$INSTDIR\driver\OemWin2k.inf" - Delete "$INSTDIR\driver\${PRODUCT_TAP_ID}.cat" - Delete "$INSTDIR\driver\${TAPDRV}" - - Delete "$INSTDIR\bin\openssl.exe" - - Delete "$INSTDIR\INSTALL-win32.txt" - Delete "$INSTDIR\${PRODUCT_ICON}" - Delete "$INSTDIR\license.txt" - Delete "$INSTDIR\Uninstall.exe" - - Delete "$INSTDIR\easy-rsa\openssl-1.0.0.cnf" - Delete "$INSTDIR\easy-rsa\vars.bat.sample" - Delete "$INSTDIR\easy-rsa\init-config.bat" - Delete "$INSTDIR\easy-rsa\README.txt" - Delete "$INSTDIR\easy-rsa\build-ca.bat" - Delete "$INSTDIR\easy-rsa\build-dh.bat" - Delete "$INSTDIR\easy-rsa\build-key-server.bat" - Delete "$INSTDIR\easy-rsa\build-key.bat" - Delete "$INSTDIR\easy-rsa\build-key-pkcs12.bat" - Delete "$INSTDIR\easy-rsa\clean-all.bat" - Delete "$INSTDIR\easy-rsa\index.txt.start" - Delete "$INSTDIR\easy-rsa\revoke-key.bat" - Delete "$INSTDIR\easy-rsa\revoke-full.bat" - Delete "$INSTDIR\easy-rsa\serial.start" - - Delete "$INSTDIR\sample-config\*.${PRODUCT_FILE_EXT}" - - RMDir "$INSTDIR\bin" - RMDir "$INSTDIR\config" - RMDir "$INSTDIR\driver" - RMDir "$INSTDIR\easy-rsa" - RMDir "$INSTDIR\sample-config" - RMDir /r "$INSTDIR\log" - RMDir "$INSTDIR" - - !insertmacro DelRegKeyIfUnchanged HKCR ".${SERV_CONFIG_EXT}" "${PRODUCT_NAME}File" - DeleteRegKey HKCR "${PRODUCT_NAME}File" - DeleteRegKey HKLM SOFTWARE\${PRODUCT_NAME} - DeleteRegKey HKCU "Software\${PRODUCT_NAME}" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" - - ;Messagebox MB_OK "IMPORTANT: If you intend on reinstalling ${PRODUCT_NAME} after this uninstall, and you are running Win2K, you are strongly urged to reboot before reinstalling (this is an informational message only, pressing OK will not reboot)." - -SectionEnd diff --git a/install-win32/setpath.nsi b/install-win32/setpath.nsi deleted file mode 100755 index a9626c3..0000000 --- a/install-win32/setpath.nsi +++ /dev/null @@ -1,231 +0,0 @@ -; Modify the user's PATH variable. -; -; Modified by JY to have both a RemoveFromPath -; and an un.RemoveFromPath which are basically -; copies of each other. Why does NSIS demand -; this nonsense? -; -; Modified Feb 14, 2005 by Mathias Sundman: -; Added code to remove the semicolon at the end of the path -; when uninstalling. -; -; Added code to make sure we don't insert an extra semicolon -; before our path if there already exist one at the end of -; the original path. -; -; Removed duplicated "un. and install" functions and made -; macros to duplicate the code instead. - -; example usage -; -;Section "Add to path" -; Push $INSTDIR -; Call AddToPath -;SectionEnd -; -;# ... -; -;Section "uninstall" -; # ... -; Push $INSTDIR -; Call un.RemoveFromPath -; # ... -;SectionEnd - -!verbose 3 -!include "WinMessages.NSH" -!verbose 4 - -;==================================================== -; AddToPath - Adds the given dir to the search path. -; Input - head of the stack -; Note - Win9x systems requires reboot -;==================================================== -Function AddToPath - Exch $0 - Push $1 - Push $2 - - Call IsNT - Pop $1 - StrCmp $1 1 AddToPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" a - FileSeek $1 0 END - GetFullPathName /SHORT $0 $0 - FileWrite $1 "$\r$\nSET PATH=%PATH%;$0$\r$\n" - FileClose $1 - Goto AddToPath_done - - AddToPath_NT: - ReadRegStr $1 HKCU "Environment" "PATH" - StrCpy $2 $1 1 -1 # copy last char - StrCmp $2 ";" 0 +2 # if last char == ; - StrCpy $1 $1 -1 # remove last char - - StrCmp $1 "" AddToPath_NTdoIt - StrCpy $0 "$1;$0" - Goto AddToPath_NTdoIt - AddToPath_NTdoIt: - WriteRegExpandStr HKCU "Environment" "PATH" $0 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - AddToPath_done: - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - -;==================================================== -; RemoveFromPath - Remove a given dir from the path -; Input: head of the stack -;==================================================== -!macro RemoveFromPath un -Function ${un}RemoveFromPath - Exch $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - - Call ${un}IsNT - Pop $1 - StrCmp $1 1 RemoveFromPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" r - GetTempFileName $4 - FileOpen $2 $4 w - GetFullPathName /SHORT $0 $0 - StrCpy $0 "SET PATH=%PATH%;$0" - SetRebootFlag true - Goto RemoveFromPath_dosLoop - - RemoveFromPath_dosLoop: - FileRead $1 $3 - StrCmp $3 "$0$\r$\n" RemoveFromPath_dosLoop - StrCmp $3 "$0$\n" RemoveFromPath_dosLoop - StrCmp $3 "$0" RemoveFromPath_dosLoop - StrCmp $3 "" RemoveFromPath_dosLoopEnd - FileWrite $2 $3 - Goto RemoveFromPath_dosLoop - - RemoveFromPath_dosLoopEnd: - FileClose $2 - FileClose $1 - StrCpy $1 $WINDIR 2 - Delete "$1\autoexec.bat" - CopyFiles /SILENT $4 "$1\autoexec.bat" - Delete $4 - Goto RemoveFromPath_done - - RemoveFromPath_NT: - StrLen $2 $0 - ReadRegStr $1 HKCU "Environment" "PATH" - Push $1 - Push $0 - Call ${un}StrStr ; Find $0 in $1 - Pop $0 ; pos of our dir - IntCmp $0 -1 RemoveFromPath_done - ; else, it is in path - StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir - IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';') - IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon. - StrLen $0 $1 - StrCpy $1 $1 $0 $2 - StrCpy $3 "$3$1" - - StrCpy $5 $3 1 -1 # copy last char - StrCmp $5 ";" 0 +2 # if last char == ; - StrCpy $3 $3 -1 # remove last char - - WriteRegExpandStr HKCU "Environment" "PATH" $3 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - RemoveFromPath_done: - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd -!macroend -!insertmacro RemoveFromPath "" -!insertmacro RemoveFromPath "un." - - -;==================================================== -; StrStr - Finds a given string in another given string. -; Returns -1 if not found and the pos if found. -; Input: head of the stack - string to find -; second in the stack - string to find in -; Output: head of the stack -;==================================================== -!macro StrStr un -Function ${un}StrStr - Push $0 - Exch - Pop $0 ; $0 now have the string to find - Push $1 - Exch 2 - Pop $1 ; $1 now have the string to find in - Exch - Push $2 - Push $3 - Push $4 - Push $5 - - StrCpy $2 -1 - StrLen $3 $0 - StrLen $4 $1 - IntOp $4 $4 - $3 - - StrStr_loop: - IntOp $2 $2 + 1 - IntCmp $2 $4 0 0 StrStrReturn_notFound - StrCpy $5 $1 $3 $2 - StrCmp $5 $0 StrStr_done StrStr_loop - - StrStrReturn_notFound: - StrCpy $2 -1 - - StrStr_done: - Pop $5 - Pop $4 - Pop $3 - Exch $2 - Exch 2 - Pop $0 - Pop $1 -FunctionEnd -!macroend -!insertmacro StrStr "" -!insertmacro StrStr "un." - -;==================================================== -; IsNT - Returns 1 if the current system is NT, 0 -; otherwise. -; Output: head of the stack -;==================================================== -!macro IsNT un -Function ${un}IsNT - Push $0 - ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $0 "" 0 IsNT_yes - ; we are not NT. - Pop $0 - Push 0 - Return - - IsNT_yes: - ; NT!!! - Pop $0 - Push 1 -FunctionEnd -!macroend -!insertmacro IsNT "" -!insertmacro IsNT "un." - diff --git a/install-win32/settings.in b/install-win32/settings.in deleted file mode 100644 index 4a0a564..0000000 --- a/install-win32/settings.in +++ /dev/null @@ -1,71 +0,0 @@ -# Version numbers, settings, and dependencies -# for Windows OpenVPN installer. - -# Get the OpenVPN version number -!include "autodefs/version.in" - -# Branding -!define PRODUCT_NAME "OpenVPN" -!define PRODUCT_UNIX_NAME "openvpn" -!define PRODUCT_FILE_EXT "ovpn" - -# Allow --askpass and --auth-user-pass passwords to be read from a file -;!define ENABLE_PASSWORD_SAVE - -# Include the OpenVPN GUI exe in the installer. -# May be undefined. -!define OPENVPN_GUI_DIR "../openvpn-gui" -!define OPENVPN_GUI "openvpn-gui-1.0.3.exe" - -# Include the OpenVPN XML-based GUI exe in the installer. -# May be undefined. -;!define OPENVPN_XGUI_DIR "../ovpnxml" - -# Prebuilt libraries. DMALLOC is optional. -!define OPENSSL_DIR "../openssl.mingw/openssl-0.9.8o" -!define LZO_DIR "../lzo-2.02" -!define PKCS11_HELPER_DIR "../pkcs11-helper" -;!define DMALLOC_DIR "../dmalloc-5.4.2" - -# Prebuilt TAP drivers and tapinstall -!define TAPBINSRC "../tap_dist" - -# Directory containing python script for signing .exe files -!define SIGNTOOL "../signtool" - -# Optional directory of prebuilt OpenVPN binary components, -# to be used as a source when build-from-scratch prerequisites -# are not met. -;!define GENOUT_PREBUILT "../gen-prebuilt" - -# -j parameter passed to make -!define MAKE_JOBS 1 - -# output directory for built binaries -# and other generated files -!define GENOUT "gen" - -# delete GENOUT directory before starting -# set to "yes" or "no" -!define CLEAN "yes" - -# Don't strip executables and DLLs -;!define NO_STRIP - -; DEBUGGING -- set to something like "-DBG2" -!define OUTFILE_LABEL "" - -; DEBUGGING -- set to something like "DEBUG2" -!define TITLE_LABEL "" - -# include a sample configuration file and key -;!define SAMPCONF_DIR "test-key" -;!define SAMPCONF_CONF "test.ovpn" -;!define SAMPCONF_P12 "test.p12" -;!define SAMPCONF_TA "ta.key" -;!define SAMPCONF_CA "ca.crt" -;!define SAMPCONF_CRT "test.crt" -;!define SAMPCONF_KEY "test.key" - -# Extract files embedded in installer -;!define EXTRACT_FILES diff --git a/install-win32/trans.pl b/install-win32/trans.pl deleted file mode 100644 index 34fd207..0000000 --- a/install-win32/trans.pl +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/perl - -# This script translates a simple definition-based grammar -# to either C, sh, Javascript, or in (in = identity grammar, i.e. -# same grammar as input). -# -# Input grammar: -# (1) comments having ';' or '#' as the first char in the line -# (2) a blank line -# (3) !include "file" -# (4) !define foo bar -# (5) !define foo "bar" -# -# Environmental variables can be used to override a setting. -# The special value "null" causes the variable to be undefined. -# If an environmental value is bracketed, i.e [abc], the brackets -# will be converted to double quotes prior to output. - -sub comment { - my ($cmt) = @_; - print "//$cmt\n" if ($mode =~ /^(c|js|h)$/); - print "#$cmt\n" if ($mode =~ /^(sh|nsi|in)$/); -} - -sub define { - my ($name, $value) = @_; - if ($mode eq "sh") { - $value="true" if !$value; - print "[ -z \"\$$name\" ] && export $name=$value\n"; - print "[ \"\$$name\" = \"$nulltag\" ] && unset $name\n"; - } else { - if ($ENV{$name}) { - $value = $ENV{$name}; - $value = "\"$1\"" if ($value =~ /\[(.*)\]$/); - } - if ($value ne $nulltag) { - print "#define $name $value\n" if ($mode =~ /^(c|h)$/); - print "!define $name $value\n" if ($mode =~ /^(nsi|in)$/); - print "var $name=$value;\n" if ($mode eq "js"); - } else { - print "//#undef $name\n" if ($mode =~ /^(c|h)$/); - print "#!undef $name\n" if ($mode eq "nsi"); - print ";!undef $name\n" if ($mode eq "in"); - print "//undef $name\n" if ($mode eq "js"); - } - } -} - -sub include_file { - local $_; - $include_file_level++; - die "!include file nesting too deep" if ($include_file_level > $max_inc_depth); - my ($parm) = @_; - my $fn = "$incdir/$parm"; - local *IN; - open(IN, "< $fn") or die "cannot open $fn"; - while (<IN>) { - chomp; - if (/^\s*$/) { - print "\n"; - } elsif (/^[#;](.*)$/) { - comment ($1); - } elsif (/^!define\s+(\w+)(?:\s+(.*?))?\s*$/) { - define ($1, $2); - } elsif (/^!include\s+"(.+)"$/) { - include_file ($1); - } else { - die "can't parse this line: $_\n"; - } - } - $include_file_level--; -} - -die "usage: trans <c|h|sh|js|nsi|in> [-I<dir>] [files ...]" if (@ARGV < 1); - -($mode) = shift(@ARGV); -die "mode must be one of c, h, sh, js, nsi, or in" if !($mode =~ /^(c|h|sh|js|nsi|in)$/); - -$nulltag = "null"; -$max_inc_depth = 10; -$include_file_level = 0; -$incdir = "."; - -comment(" This file was automatically generated by trans.pl"); - -while ($arg=shift(@ARGV)) { - if ($arg =~ /^-/) { - if ($arg =~ /^-I(.*)$/) { - $incdir = $1; - } else { - die "unrecognized option: $arg"; - } - } else { - print "\n"; - include_file ($arg); - } -} diff --git a/install-win32/u2d.c b/install-win32/u2d.c deleted file mode 100755 index bf1f5e8..0000000 --- a/install-win32/u2d.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <stdio.h> - -int -main (int argc, char *argv[]) -{ - int c; - int enable = 1; - - while ((c = getchar()) != EOF) - { -#if 0 - if (c == '\r') - enable = 0; - if (enable && c == '\n') - putchar ('\r'); -#endif - putchar (c); - } - return 0; -} diff --git a/install-win32/winconfig b/install-win32/winconfig deleted file mode 100644 index 9d686c9..0000000 --- a/install-win32/winconfig +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# prepare files for building on Windows -# run from top directory: install-win32/winconfig - -rm -rf autodefs -mkdir autodefs - -# build multi-grammar definition files -perl install-win32/m4todef.pl <version.m4 >autodefs/version.in -for g in "h" "sh" "nsi" "in" ; do - perl install-win32/trans.pl $g install-win32/settings.in >autodefs/defs.$g -done - -cat /dev/null >autodefs/guidefs.nsi - -echo '#include "autodefs/defs.h"' >autodefs.h -echo '#include "config.h"' >>autodefs.h diff --git a/ltmain.sh b/ltmain.sh new file mode 100755 index 0000000..d8efb57 --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,8745 @@ +# Generated from ltmain.m4sh. + +# libtool (GNU libtool) 2.2.10 +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 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 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. +# +# 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 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. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --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) +# --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.2.10 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to <bug-libtool@gnu.org>. + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.2.10 +TIMESTAMP="" +package_revision=1.3175 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # 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 +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + 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 + +$lt_unset CDPATH + + +# 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" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${EGREP="/bin/grep -E"} +: ${FGREP="/bin/grep -F"} +: ${GREP="/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/bin/sed"} +: ${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. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# 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"` +} + +# Generated shell functions inserted here. + +# 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,/*$,/,' + +# 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 +} + +# 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 + + # 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 + + # 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 path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + 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' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/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=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && 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_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_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 +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # 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 "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + 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 "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# 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 () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + 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\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# 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 () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + 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. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# 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 () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + 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_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 () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + 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_version +# Echo version message to standard output and exit. +func_version () +{ + $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 $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + 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 --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1." + exit_cmd=exit +} + +exit_cmd=: + + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +# $mode is unset +nonopt= +execute_dlfiles= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +opt_dry_run=false +opt_duplicate_deps=false +opt_silent=false +opt_debug=: + +# 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_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + 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 () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# 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" + + 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 + + # 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 +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # 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 + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + 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 $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + opt_verbose=false + ;; + + --no-quiet|--no-silent) + preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + opt_verbose=: + ;; + + --no-verbose) preserve_args="$preserve_args $opt" + opt_verbose=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --help-all) opt_help=': help-all' ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + 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_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# 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 +$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 +$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 +$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 +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; 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=$mode' for more information." +} + + +# func_lalib_p 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 \ + | $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. +# 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. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# 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. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + 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`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # 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'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "${write_libobj}" + } +} + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + pie_flag="$pie_flag $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_quote_for_eval "$arg" + lastarg="$lastarg $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_quote_for_eval "$lastarg" + base_compile="$base_compile $func_quote_for_eval_result" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + 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" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + 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_dirname_and_basename "$obj" "/" "" + 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 "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + 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 "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # 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 "$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 "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +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 +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." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$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 +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." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + 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 "$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 "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$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 +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." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +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 +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -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 + -Wc,FLAG pass FLAG directly to the compiler + +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'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +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' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +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." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -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 + -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 + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -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 + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -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. + +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 +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 \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +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 +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + echo + $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 + func_mode_help + else + { + func_help noexit + for mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # 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" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + 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'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + 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" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + 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" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + 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 "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + 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 "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 " during execution" + fi + if test -n "$runpath_var"; then + 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" + 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'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + install_shared_prog="$install_shared_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + install_shared_prog="$install_shared_prog -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + 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" + + # 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" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # 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" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # 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" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + '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" + shift + + 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" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # 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 + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + 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 + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + 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="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + 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'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $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" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$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' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $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 "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + 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$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + 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"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + 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 + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + echo >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + echo >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + 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"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # 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 + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $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" + sleep 2 + done + 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 "$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 + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + 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" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + 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}" + cd "$darwin_curdir" + $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 "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# 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 in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# 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. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # 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 +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /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 which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + 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\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + 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\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$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 + fi +fi\ +" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1"; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_result=`cygpath -w "$1" | + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # 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 command is not + # found, the shell will set an exit code of 127 and print + # *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_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`$ECHO "$func_to_host_path_tmp1" | + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result= + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1"; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_pathlist_tmp1=$func_stripname_result + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + func_to_host_pathlist_result=` + ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_result=`cygpath -w -p "$func_to_host_pathlist_tmp1" | + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_append func_to_host_pathlist_result ";$func_to_host_path_result" + fi + fi + fi + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result"; then + func_error "Could not determine the host path(s) corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_append func_to_host_pathlist_result ";" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + 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. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#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 platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# 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__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_pathlist "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_pathlist "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test "$fast_install" = yes; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + intptr_t rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + 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 + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], dumpscript_opt) == 0) + { +EOF + case "$host" in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (strcmp (argv[i], debug_opt) == 0) + { + lt_debug = 1; + continue; + } + 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 + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + 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]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#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; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + 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) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' + + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $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 + # 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 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. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + 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 "$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 + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + 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" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + 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 "$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" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + 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$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + 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) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-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" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -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 + # @file GCC response files + # -tp=* Portland pgcc target processor selection + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + 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" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + 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 "$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" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # 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" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + 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" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + 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\'\` + 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\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # 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_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + 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 "$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" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + 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 "$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" + fi + 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}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + 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 "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_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 + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + 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=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + 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" + 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 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 "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + 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. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $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_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + 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'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_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_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + 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 "$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 + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [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 "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + 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" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + 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 + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + 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_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { 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 + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + 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 + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + 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 "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + 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" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + 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_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_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + 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" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # 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 + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + 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" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + 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 "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + 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 "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + 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:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + 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" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + 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 + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + 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 "$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 "$build_libtool_libs" = yes; then + # Not a shared library + 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 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 "$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 "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { 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 + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + 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" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [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" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + 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 + 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 -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + 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 "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + 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 + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + 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" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + 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" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # 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" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + 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 + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + 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" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + 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" + ;; + 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" + ;; + 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" + ;; + 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" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + 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" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + 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" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + 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" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + 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" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $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 + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + 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" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # 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="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + 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 + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + 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 I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + newdeplibs="$newdeplibs $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + 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 + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + 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" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + newdeplibs="$newdeplibs $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + 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 + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [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 + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + 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" + echo "*** because I did check the linker path looking for a file starting" + 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" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + 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 + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + 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" + echo "*** because I did check the linker path looking for a file starting" + 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" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + 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,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + 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." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + 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" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + 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 "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + 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 "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$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 + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + 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" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + 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" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + 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='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + 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 + fi + 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" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + 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" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # '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. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + 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. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$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 "$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 + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + 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 + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + 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 + do + $ECHO "$obj" >> $output + done + echo ')' >> $output + delfiles="$delfiles $output" + 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 "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + 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 "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # 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\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + 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. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + 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='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + 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"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + 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" + $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" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # '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. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + 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. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + 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 + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$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 + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + 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" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + 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" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # 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\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + 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" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + 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" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + 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]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + 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@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + 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" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + 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" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + 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. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + 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" + 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'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + 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" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + 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 + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + 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" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + 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" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + 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\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + 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=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + 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 "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + 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" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + 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` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # 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` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + 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 "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + 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" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # 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" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# 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 +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + @@ -1,136 +0,0 @@ -/* - * 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-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_LZO_H -#define OPENVPN_LZO_H - -#ifdef USE_LZO - -#ifdef LZO_HEADER_DIR -#include "lzo/lzoutil.h" -#include "lzo/lzo1x.h" -#else -#include "lzoutil.h" -#include "lzo1x.h" -#endif - -#include "buffer.h" -#include "mtu.h" -#include "common.h" -#include "status.h" - -/* LZO flags */ -#define LZO_SELECTED (1<<0) -#define LZO_ON (1<<1) -#define LZO_ADAPTIVE (1<<2) - -/* - * Use LZO compress routine lzo1x_1_15_compress which is described - * as faster but needs a bit more memory than the standard routine. - * Use safe decompress (i.e. check for buffer overflows). - * You may want to use the non-safe version - * of decompress if speed is essential and if you know - * that you will always be using a MAC to verify the - * integrity of incoming packets. - */ -#define LZO_COMPRESS lzo1x_1_15_compress -#define LZO_WORKSPACE LZO1X_1_15_MEM_COMPRESS -#define LZO_DECOMPRESS lzo1x_decompress_safe - -#define LZO_EXTRA_BUFFER(len) ((len)/8 + 128 + 3) /* LZO 2.0 worst case size expansion. */ - -/* - * Don't try to compress any packet smaller than this. - */ -#define COMPRESS_THRESHOLD 100 - -/* - * Length of prepended prefix on LZO packets - */ -#define LZO_PREFIX_LEN 1 - -/* - * Adaptive compress parameters - */ -#define AC_SAMP_SEC 2 /* number of seconds in sample period */ -#define AC_MIN_BYTES 1000 /* sample period must have at least n bytes - to be valid for testing */ -#define AC_SAVE_PCT 5 /* turn off compress if we didn't save at - least this % during sample period */ -#define AC_OFF_SEC 60 /* if we turn off compression, don't do sample - retest for n seconds */ - -struct lzo_adaptive_compress { - bool compress_state; - time_t next; - int n_total; - int n_comp; -}; - -/* - * Compress and Uncompress routines. - */ - -struct lzo_compress_workspace -{ - lzo_voidp wmem; - int wmem_size; - struct lzo_adaptive_compress ac; - unsigned int flags; - bool defined; - - /* statistics */ - counter_type pre_decompress; - counter_type post_decompress; - counter_type pre_compress; - counter_type post_compress; -}; - -void lzo_adjust_frame_parameters(struct frame *frame); - -void lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags); - -void lzo_compress_uninit (struct lzo_compress_workspace *lzowork); - -void lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags); - -void lzo_compress (struct buffer *buf, struct buffer work, - struct lzo_compress_workspace *lzowork, - const struct frame* frame); - -void lzo_decompress (struct buffer *buf, struct buffer work, - struct lzo_compress_workspace *lzowork, - const struct frame* frame); - -void lzo_print_stats (const struct lzo_compress_workspace *lzo_compwork, struct status_output *so); - -static inline bool -lzo_defined (const struct lzo_compress_workspace *lzowork) -{ - return lzowork->defined; -} - - -#endif /* USE_LZO */ -#endif diff --git a/m4/ax_emptyarray.m4 b/m4/ax_emptyarray.m4 new file mode 100644 index 0000000..c6781c1 --- /dev/null +++ b/m4/ax_emptyarray.m4 @@ -0,0 +1,40 @@ +dnl @synopsis AX_EMPTY_ARRAY +dnl +dnl Define EMPTY_ARRAY_SIZE to be either "0" +dnl or "" depending on which syntax the compiler +dnl prefers for empty arrays in structs. +dnl +dnl @version +dnl @author James Yonan <jim@yonan.net> +AC_DEFUN([AX_EMPTY_ARRAY], [ + AS_VAR_PUSHDEF([VAR],[ax_cv_c_empty_array])dnl + AC_CACHE_CHECK( + [for C compiler empty array size], + [VAR], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + , + [[ +struct { int foo; int bar[0]; } mystruct; + ]] + )], + [VAR=0], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + , + [[ +struct { int foo; int bar[]; } mystruct; + ]] + )], + [VAR=], + [AC_MSG_ERROR([C compiler is unable to creaty empty arrays])] + )] + )] + )dnl + AC_DEFINE_UNQUOTED( + [EMPTY_ARRAY_SIZE], + [$VAR], + [Dimension to use for empty array declaration] + )dnl + AS_VAR_POPDEF([VAR])dnl +]) diff --git a/m4/ax_socklen_t.m4 b/m4/ax_socklen_t.m4 new file mode 100644 index 0000000..cd7cad8 --- /dev/null +++ b/m4/ax_socklen_t.m4 @@ -0,0 +1,65 @@ +dnl -- The following is base of curl's acinclude.m4 -- +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. +AC_DEFUN([AX_TYPE_SOCKLEN_T], [ + AC_CHECK_TYPE( + [socklen_t], + , + [ + AS_VAR_PUSHDEF([VAR],[ax_cv_socklen_t_equiv])dnl + AC_CACHE_CHECK( + [for socklen_t equivalent], + [VAR], + [ + #AS_CASE is not supported on <autoconf-2.60 + case "${host}" in + *-mingw*) VAR=int ;; + *) + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long"; do + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <sys/types.h> +#include <sys/socket.h> +int getpeername (int, $arg2 *, $t *); + ]], + [[ +$t len; +getpeername(0,0,&len); + ]] + )], + [VAR="$t"; break] + ) + done + test -n "$VAR" && break + done + ;; + esac + ] + AS_VAR_IF( + [VAR], + [], + [AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])], + [AC_DEFINE_UNQUOTED( + [socklen_t], + [$VAR], + [type to use in place of socklen_t if not defined] + )] + ) + ) + ], + [[ +#include <sys/types.h> +#ifdef WIN32 +#include <ws2tcpip.h> +#else +#include <sys/socket.h> +#endif + ]] + ) +]) diff --git a/m4/ax_varargs.m4 b/m4/ax_varargs.m4 new file mode 100644 index 0000000..c295d21 --- /dev/null +++ b/m4/ax_varargs.m4 @@ -0,0 +1,77 @@ +dnl @synopsis AX_CPP_VARARG_MACRO_GCC +dnl +dnl Test if the preprocessor understands GNU GCC-style vararg macros. +dnl If it does, defines HAVE_CPP_VARARG_MACRO_GCC to 1. +dnl +dnl @version +dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de> +AC_DEFUN([AX_CPP_VARARG_MACRO_GCC], [dnl + AS_VAR_PUSHDEF([VAR], [ax_cv_cpp_vararg_macro_gcc])dnl + AC_CACHE_CHECK( + [for GNU GCC vararg macro support], + [VAR], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#define macro(a, b...) func(a, b) +int func(int a, int b, int c); + ]], + [[ +int i = macro(1, 2, 3); + ]] + )], + [VAR=yes], + [VAR=no] + )] + )dnl + + AS_VAR_IF( + [VAR], + [yes], + [AC_DEFINE( + [HAVE_CPP_VARARG_MACRO_GCC], + [1], + [Define to 1 if your compiler supports GNU GCC-style variadic macros] + )] + )dnl + AS_VAR_POPDEF([VAR])dnl +]) + +dnl @synopsis AX_CPP_VARARG_MACRO_ISO +dnl +dnl Test if the preprocessor understands ISO C 1999 vararg macros. +dnl If it does, defines HAVE_CPP_VARARG_MACRO_ISO to 1. +dnl +dnl @version +dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de> +AC_DEFUN([AX_CPP_VARARG_MACRO_ISO], [dnl + AS_VAR_PUSHDEF([VAR],[ax_cv_cpp_vararg_macro_iso])dnl + AC_CACHE_CHECK( + [for ISO C 1999 vararg macro support], + [VAR], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#define macro(a, ...) func(a, __VA_ARGS__) +int func(int a, int b, int c); + ]], + [[ +int i = macro(1, 2, 3); + ]] + )], + [VAR=yes], + [VAR=no] + )] + )dnl + + AS_VAR_IF( + [VAR], + [yes], + [AC_DEFINE( + [HAVE_CPP_VARARG_MACRO_ISO], + [1], + [Define to 1 if your compiler supports ISO C99 variadic macros] + )] + )dnl + AS_VAR_POPDEF([VAR])dnl +]) diff --git a/m4/libtool.m4 b/m4/libtool.m4 new file mode 100644 index 0000000..8c99a62 --- /dev/null +++ b/m4/libtool.m4 @@ -0,0 +1,7441 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 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. +# +# 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 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 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[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 +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[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])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# 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 + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# 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" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# 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, +# 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" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# 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' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _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 +# 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"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# 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 +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +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' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# 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 +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +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\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +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\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# 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 +# 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). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 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 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# 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 "$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 +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_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 which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$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. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_XSI_SHELLFNS + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + 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 + # 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 + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _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' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + 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}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + 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\"`' + 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" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + 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}" + m4_if([$1], [CXX], +[ 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 + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# 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 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 +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`print -r -- -n 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +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 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" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # 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 + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + 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 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" + fi + ;; +sparc*-*solaris*) + # 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 + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[AC_CHECK_TOOL(AR, ar, false) +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1]) + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +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" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + 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 + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + 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` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + 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` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + 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 + 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"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + 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 + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + 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_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # 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_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [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"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + 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 "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + 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 + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # 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 + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +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 + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + 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 "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +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 in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + 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 "$_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 + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +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 "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +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 +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + 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" ;; + 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 + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # 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` + 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" + 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; + 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; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # 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'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + 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' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + 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}' + 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 + # 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 + : + else + can_build_shared=no + fi + ;; + esac + # 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. + 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}' + 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' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + 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}' + ;; + 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%'\''`; 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}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + 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' + 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" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + 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'\''`~ + 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_overrides_runpath=yes + + 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}' +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}' + ;; + 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}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + 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' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + 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 + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + 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' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + 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 + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + 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' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + 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 "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + 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' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + 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' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux + 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' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + 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}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + 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}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + 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' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # 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 + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # 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 + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + 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' + 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' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + 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 + ;; + +*nto* | *qnx*) + 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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # 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 + 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' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + 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}' + 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" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + 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=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + 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 "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + 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) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + 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=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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + 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' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + 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 + ;; + +uts4*) + version_type=linux + 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 + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +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 "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_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], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# 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_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" + test -z "$ac_dir" && ac_dir=. + 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" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# 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 + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +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 "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +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 + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + 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" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +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 + for ac_dir in $PATH; do + 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" + # 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 "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + 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 + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +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. +# '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 +# 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]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +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. + # 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 + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +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)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method == "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +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" +else + 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 + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + 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 + # Check to see if the nm accepts a BSD-compat flag. + # 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 + 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 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +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 /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# 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 -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 -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= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # 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 + # 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};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {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'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + 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 + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +_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_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_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + 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'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + 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' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + 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 "$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' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # 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' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _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* | pgcpp*) + # Portland Group 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)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + 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'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + 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' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + 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']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + 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' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # 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' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _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) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac +AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + 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 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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _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" + ;; + cygwin* | mingw* | cegcc*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # 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'. + _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 + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # 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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # 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 "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + 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' + # 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' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + 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 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + 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_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; 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' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _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(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + 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 (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(link_all_deplibs, $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' + # 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' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + 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 "$tmp_diet" = no + then + tmp_addflag= + 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' + 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' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--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(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(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' + + 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' + fi + + case $cc_basename in + 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)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $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~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _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' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _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 + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** 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 +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # 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' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _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 + ;; + esac + + 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)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # 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 "$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 + fi + ;; + + aix[[4-9]]*) + 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="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _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 + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _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,' + + 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` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _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_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 + _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 "$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" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _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 "$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' + 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 + # 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 + ;; + + amigaos*) + 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_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + 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. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${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 $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_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' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $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' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + 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' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (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)='$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']) + ;; + esac + fi + 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(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _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 + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $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. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE(int foo(void) {}, + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $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" + 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' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _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 + ;; + + 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 + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + 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_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + 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__`" || 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' + else + 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 + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _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 "$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' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _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 "$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}-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_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' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${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 ${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_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' + ;; + *) + 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' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + 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 is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + 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 + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + 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' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _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 "$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' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # 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(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_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + 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' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + 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' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + 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. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_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 + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [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 + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [fix_srcfile_path], [1], + [Fix the shell variable $srcfile for the compiler]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# 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'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # 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 "$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 "$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 "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# 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'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +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 +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# 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 "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + 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 "$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 "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -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' + + # 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}' + + # 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' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # 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 + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + 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="" + 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 + # 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 + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _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,' + + 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` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _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_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 + _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 "$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" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _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 "$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' + 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 + # 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 + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; 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' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _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(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 (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 + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _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(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _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(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _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 $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. + # + # There doesn't appear to be a way to prevent this compiler from + # 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"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${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 + fi + ;; + esac + ;; + + hpux10*|hpux11*) + 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' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + 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' + ;; + 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}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # 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"' + ;; + *) + 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' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + 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' + # 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' + ;; + 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' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -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 -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_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # 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' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # 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"' + + _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. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # 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' + ;; + *) # 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' + ;; + 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' + ;; + 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`"' + _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' + _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' + _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' + ;; + *) # 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' + ;; + 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' + ;; + 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' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # 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' + ;; + 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 "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' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *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(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(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + 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__`" || 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 + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # 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(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + 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)=' -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_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' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # 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"' + ;; + *) + 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}-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_separator, $1)=: + + # 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 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # 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_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' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # 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' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + 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' + + # 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 "$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 -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 -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 + # platform. + _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 -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 -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' + 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' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _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 -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 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(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_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _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(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_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' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + 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 "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p 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}" + else + _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 + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _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" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _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 +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +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!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# 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'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# 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 "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${F77-"f77"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + 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 "$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 "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# 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'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# 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 "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${FC-"f95"} + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + 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 "$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 "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is 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" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# 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'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC="$lt_save_CC" +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# 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'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +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" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC="$lt_save_CC" +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +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 "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +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 + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $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 $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[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"}, \ + = c,a/b,, \ + && 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 +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. +m4_defun([_LT_PROG_XSI_SHELLFNS], +[case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# 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 () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# 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 () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# 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_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}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# 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 () +{ + # Extract subdirectory from the argument. + 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_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} + +dnl func_dirname_and_basename +dnl A portable version of this function is already defined in general.m4sh +dnl so there is no need for it here. + +# 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 +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[[^=]]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[[^.]]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]+=\$[2]" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]=\$$[1]\$[2]" +} + +_LT_EOF + ;; + esac +]) diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 new file mode 100644 index 0000000..17cfd51 --- /dev/null +++ b/m4/ltoptions.m4 @@ -0,0 +1,369 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# 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 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])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +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 +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + 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 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_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +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.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_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.]) +]) + +dnl aclocal-1.4 backwards compatibility: +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'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +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'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +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'. +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], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + 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," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +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.]) +]) + +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.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# 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'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [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 + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +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.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 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 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 new file mode 100644 index 0000000..93fc771 --- /dev/null +++ b/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 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. + +# Generated from ltversion.in. + +# serial 3175 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.2.10]) +m4_define([LT_PACKAGE_REVISION], [1.3175]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.2.10' +macro_revision='1.3175' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 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 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/m4/pkg.m4 b/m4/pkg.m4 new file mode 100644 index 0000000..9a71878 --- /dev/null +++ b/m4/pkg.m4 @@ -0,0 +1,159 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.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 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/msvc-build.bat b/msvc-build.bat new file mode 100644 index 0000000..fd6d558 --- /dev/null +++ b/msvc-build.bat @@ -0,0 +1,48 @@ +@echo off +rem Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> + +@rem this stupid command needed for SetEnv.cmd to operate +setlocal ENABLEDELAYEDEXPANSION + +cd /d %0\.. +call msvc-env.bat + +set PLATFORMS=Win32 +set CONFIGURATIONS=Release + +if exist "%VCHOME%\vcvarsall.bat" ( + call "%VCHOME%\vcvarsall.bat" +) else if exist "%VCHOME%\bin\vcvars32.bat" ( + call "%VCHOME%\bin\vcvars32.bat" +) else ( + echo Cannot detect visual studio + goto error +) + +msbuild /help > nul 2>&1 +if errorlevel 1 set DO_VCBUILD=1 + +for %%p in (%PLATFORMS%) do ( + for %%c in (%CONFIGURATIONS%) do ( + rmdir /q /s %SOURCEBASE%\%%p\%%c > nul 2>&1 + + if "%DO_VCBUILD%" NEQ "" ( + vcbuild /errfile:error.log /showenv "%SOLUTION%" /rebuild /platform:%%p "%%c|%%p" + for %%f in (error.log) do if %%~zf GTR 0 goto error + ) else ( + msbuild "%SOLUTION%" /p:Configuration="%%c" /p:Platform="%%p" + if errorlevel 1 goto error + ) + ) +) + +exit /b 0 +goto end + +:error +exit /b 1 +goto end + +:end + +endlocal diff --git a/msvc-dev.bat b/msvc-dev.bat new file mode 100644 index 0000000..dbd7be0 --- /dev/null +++ b/msvc-dev.bat @@ -0,0 +1,26 @@ +@echo off + +setlocal +cd /d %0\.. +call msvc-env.bat + +if exist "%VSHOME%\Common7\IDE\VCExpress.exe" ( + set IDE=%VSHOME%\Common7\IDE\VCExpress.exe +) else if exist "%VSHOME%\Common7\IDE\devenv.exe" ( + set IDE=%VSHOME%\Common7\IDE\devenv.exe +) else ( + echo "Cannot detect visual studio environment" + goto error +) +start "" "%IDE%" "%SOLUTION%" + +exit /b 0 +goto end + +:error +exit /b 1 +goto end + +:end + +endlocal diff --git a/msvc-env.bat b/msvc-env.bat new file mode 100644 index 0000000..2dd0f00 --- /dev/null +++ b/msvc-env.bat @@ -0,0 +1,30 @@ +@echo off + +rem Put your own settings at msvc-env-local.bat +if exist msvc-env-local.bat call msvc-env-local.bat + +if "%ProgramFiles(x86)%"=="" set ProgramFiles(x86)=%ProgramFiles% +if "%VSCOMNTOOLS%"=="" SET VSCOMNTOOLS=%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\Tools +if "%VSCOMNTOOLS%"=="" SET VSCOMNTOOLS=%ProgramFiles(x86)%\Microsoft Visual Studio 9.0\Common7\Tools +if "%VSHOME%"=="" SET VSHOME=%VSCOMNTOOLS%\..\.. +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%;_USE_32BIT_TIME_T +set CPPFLAGS=%CPPFLAGS%;%EXTRA_CPPFLAGS% + +if exist config-msvc-local.h set CPPFLAGS="%CPPFLAGS%;HAVE_CONFIG_MSVC_LOCAL_H" + +if "%OPENVPN_DEPROOT%" == "" set OPENVPN_DEPROOT=c:\Temp\openvpn-deps +if "%OPENSSL_HOME%" == "" set OPENSSL_HOME=%OPENVPN_DEPROOT% +if "%LZO_HOME%" == "" set LZO_HOME=%OPENVPN_DEPROOT% +if "%PKCS11H_HOME%" == "" set PKCS11H_HOME=%OPENVPN_DEPROOT% +if "%TAP_WINDOWS_HOME%" == "" set TAP_WINDOWS_HOME=%OPENVPN_DEPROOT% + +if not exist "%OPENSSL_HOME%" echo WARNING: openssl '%OPENSSL_HOME%' does not exist +if not exist "%LZO_HOME%" echo WARNING: lzo '%LZO_HOME%' does not exist +if not exist "%PKCS11H_HOME%" echo WARNING: pkcs11-helper '%PKCS11H_HOME%' does not exist +if not exist "%TAP_WINDOWS_HOME%" echo WARNING: tap-windows '%TAP_WINDOWS_HOME%' does not exist diff --git a/openvpn.sln b/openvpn.sln new file mode 100644 index 0000000..90c01b8 --- /dev/null +++ b/openvpn.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openvpnserv", "src\openvpnserv\openvpnserv.vcxproj", "{9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openvpn", "src\openvpn\openvpn.vcxproj", "{29DF226E-4D4E-440F-ADAF-5829CFD4CA94}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-generate", "build\msvc\msvc-generate\msvc-generate.vcxproj", "{8598C2C8-34C4-47A1-99B0-7C295A890615}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compat", "src\compat\compat.vcxproj", "{4B2E2719-E661-45D7-9203-F6F456B22F19}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}.Debug|Win32.Build.0 = Debug|Win32 + {9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}.Release|Win32.ActiveCfg = Release|Win32 + {9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}.Release|Win32.Build.0 = Release|Win32 + {29DF226E-4D4E-440F-ADAF-5829CFD4CA94}.Debug|Win32.ActiveCfg = Debug|Win32 + {29DF226E-4D4E-440F-ADAF-5829CFD4CA94}.Debug|Win32.Build.0 = Debug|Win32 + {29DF226E-4D4E-440F-ADAF-5829CFD4CA94}.Release|Win32.ActiveCfg = Release|Win32 + {29DF226E-4D4E-440F-ADAF-5829CFD4CA94}.Release|Win32.Build.0 = Release|Win32 + {8598C2C8-34C4-47A1-99B0-7C295A890615}.Debug|Win32.ActiveCfg = Debug|Win32 + {8598C2C8-34C4-47A1-99B0-7C295A890615}.Debug|Win32.Build.0 = Debug|Win32 + {8598C2C8-34C4-47A1-99B0-7C295A890615}.Release|Win32.ActiveCfg = Release|Win32 + {8598C2C8-34C4-47A1-99B0-7C295A890615}.Release|Win32.Build.0 = Release|Win32 + {4B2E2719-E661-45D7-9203-F6F456B22F19}.Debug|Win32.ActiveCfg = Debug|Win32 + {4B2E2719-E661-45D7-9203-F6F456B22F19}.Debug|Win32.Build.0 = Debug|Win32 + {4B2E2719-E661-45D7-9203-F6F456B22F19}.Release|Win32.ActiveCfg = Release|Win32 + {4B2E2719-E661-45D7-9203-F6F456B22F19}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugin/auth-pam/.svnignore b/plugin/auth-pam/.svnignore deleted file mode 100644 index 140f8cf..0000000 --- a/plugin/auth-pam/.svnignore +++ /dev/null @@ -1 +0,0 @@ -*.so diff --git a/plugin/auth-pam/Makefile b/plugin/auth-pam/Makefile deleted file mode 100755 index e69fe3f..0000000 --- a/plugin/auth-pam/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Build the OpenVPN auth-pam plugin module. -# - -# If PAM modules are not linked against libpam.so, set DLOPEN_PAM to 1. This -# must be done on SUSE 9.1, at least. -DLOPEN_PAM=0 - -ifeq ($(DLOPEN_PAM),1) - LIBPAM=-ldl -else - LIBPAM=-lpam -endif - -# This directory is where we will look for openvpn-plugin.h -INCLUDE=-I../.. - -CC_FLAGS=-O2 -Wall -DDLOPEN_PAM=$(DLOPEN_PAM) - -openvpn-auth-pam.so : auth-pam.o pamdl.o - gcc ${CC_FLAGS} -fPIC -shared -Wl,-soname,openvpn-auth-pam.so -o openvpn-auth-pam.so auth-pam.o pamdl.o -lc $(LIBPAM) - -auth-pam.o : auth-pam.c pamdl.h - gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} auth-pam.c - -pamdl.o : pamdl.c pamdl.h - gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} pamdl.c - -clean : - rm -f *.o *.so diff --git a/plugin/down-root/Makefile b/plugin/down-root/Makefile deleted file mode 100755 index 5ce4ffb..0000000 --- a/plugin/down-root/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Build the OpenVPN down-root plugin module. -# - -# This directory is where we will look for openvpn-plugin.h -INCLUDE=-I../.. - -CC_FLAGS=-O2 -Wall - -down-root.so : down-root.o - gcc ${CC_FLAGS} -fPIC -shared -Wl,-soname,openvpn-down-root.so -o openvpn-down-root.so down-root.o -lc - -down-root.o : down-root.c - gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} down-root.c - -clean : - rm -f *.o *.so diff --git a/reliable.h b/reliable.h deleted file mode 100644 index 9cf8eec..0000000 --- a/reliable.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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-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 routines implement a reliability layer on top of UDP, - * so that TLS can be run over UDP. - */ - -#if defined(USE_CRYPTO) && defined(USE_SSL) - -#ifndef RELIABLE_H -#define RELIABLE_H - -#include "basic.h" -#include "buffer.h" -#include "packet_id.h" -#include "session_id.h" -#include "mtu.h" - -#define EXPONENTIAL_BACKOFF - -#define RELIABLE_ACK_SIZE 8 - -struct reliable_ack -{ - int len; - packet_id_type packet_id[RELIABLE_ACK_SIZE]; -}; - -/* no active buffers? */ -static inline bool -reliable_ack_empty (struct reliable_ack *ack) -{ - return !ack->len; -} - -/* get a packet_id from buf */ -bool reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid); - -/* acknowledge a packet_id by adding it to a struct reliable_ack */ -bool reliable_ack_acknowledge_packet_id (struct reliable_ack *ack, packet_id_type pid); - -/* read a packet ID acknowledgement record from buf */ -bool reliable_ack_read (struct reliable_ack *ack, - struct buffer *buf, const struct session_id *sid); - -/* write a packet ID acknowledgement record to buf */ -bool reliable_ack_write (struct reliable_ack *ack, - struct buffer *buf, - const struct session_id *sid, int max, bool prepend); - -/* print a reliable ACK record coming off the wire */ -const char *reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc); - -/* add to extra_frame the maximum number of bytes we will need for reliable_ack_write */ -void reliable_ack_adjust_frame_parameters (struct frame* frame, int max); - -void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc); - -#define RELIABLE_CAPACITY 8 - -struct reliable_entry -{ - bool active; - interval_t timeout; - time_t next_try; - packet_id_type packet_id; - int opcode; - struct buffer buf; -}; - -struct reliable -{ - int size; - interval_t initial_timeout; - packet_id_type packet_id; - int offset; - bool hold; /* don't xmit until reliable_schedule_now is called */ - struct reliable_entry array[RELIABLE_CAPACITY]; -}; - -void reliable_debug_print (const struct reliable *rel, char *desc); - -/* set sending timeout (after this time we send again until ACK) */ -static inline void -reliable_set_timeout (struct reliable *rel, interval_t timeout) -{ - rel->initial_timeout = timeout; -} - -void reliable_init (struct reliable *rel, int buf_size, int offset, int array_size, bool hold); - -void reliable_free (struct reliable *rel); - -/* no active buffers? */ -bool reliable_empty (const struct reliable *rel); - -/* in how many seconds should we wake up to check for timeout */ -interval_t reliable_send_timeout (const struct reliable *rel); - -/* del acknowledged items from send buf */ -void reliable_send_purge (struct reliable *rel, struct reliable_ack *ack); - -/* true if at least one free buffer available */ -bool reliable_can_get (const struct reliable *rel); - -/* make sure that incoming packet ID isn't a replay */ -bool reliable_not_replay (const struct reliable *rel, packet_id_type id); - -/* make sure that incoming packet ID won't deadlock the receive buffer */ -bool reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id); - -/* grab a free buffer */ -struct buffer *reliable_get_buf (struct reliable *rel); - -/* grab a free buffer, fail if buffer clogged by unacknowledged low packet IDs */ -struct buffer *reliable_get_buf_output_sequenced (struct reliable *rel); - -/* get active buffer for next sequentially increasing key ID */ -struct buffer *reliable_get_buf_sequenced (struct reliable *rel); - -/* return true if reliable_send would return a non-NULL result */ -bool reliable_can_send (const struct reliable *rel); - -/* return next buffer to send to remote */ -struct buffer *reliable_send (struct reliable *rel, int *opcode); - -/* schedule all pending packets for immediate retransmit */ -void reliable_schedule_now (struct reliable *rel); - -/* enable an incoming buffer previously returned by a get function as active */ -void reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf, - packet_id_type pid, int opcode); - -/* enable an outgoing buffer previously returned by a get function as active. */ -void reliable_mark_active_outgoing (struct reliable *rel, struct buffer *buf, int opcode); - -/* delete a buffer previously activated by reliable_mark_active() */ -void reliable_mark_deleted (struct reliable *rel, struct buffer *buf, bool inc_pid); - -#endif /* RELIABLE_H */ -#endif /* USE_CRYPTO && USE_SSL */ diff --git a/sample-keys/ta.key b/sample-keys/ta.key deleted file mode 100644 index 4d6656b..0000000 --- a/sample-keys/ta.key +++ /dev/null @@ -1,21 +0,0 @@ -# -# 2048 bit OpenVPN static key -# ------BEGIN OpenVPN Static key V1----- -0ced1f4037e2f0313eac5002536e69fd -50cd49736a392ce423df01e9692e34f0 -fa2b1e9bcc0a3ec17bfcabf660cd3c44 -7bab4b01a0f0af075262d513657ed9b3 -f5fa96e93b00a96fb3177569d4e1f432 -d3f1c72da118496a723329ab1d3b2dee -c9d9180bc07ff10b0537da11fcd2632a -e67adc78c1feda90db8eb7858320d5bb -e3edf64e0e8ee951b9a1bc6e0606d7c8 -90b6481d2d7d4508282fa16b9402eeaf -7d32c3bf61ccf98f1f7ac3de55da0351 -a4f23623f3a9e38d49e6a8aec4173cb2 -3687d72d42f910b1dd7c688e4e509d81 -024c1d82c22f1277cd6c8ce71cf4bb60 -953c45659cdc7dbb88f45fcd90a60f61 -753a63ed08cc974a57d36f743a30b0a3 ------END OpenVPN Static key V1----- diff --git a/sample/Makefile.am b/sample/Makefile.am new file mode 100644 index 0000000..be30c88 --- /dev/null +++ b/sample/Makefile.am @@ -0,0 +1,34 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + sample-plugins \ + sample-config-files \ + sample-windows \ + sample-keys \ + sample-scripts + +if WIN32 +sample_DATA = \ + client.ovpn \ + server.ovpn \ + sample-windows/sample.ovpn + +client.ovpn: sample-config-files/client.conf + -rm -f client.ovpn + cp "$(srcdir)/sample-config-files/client.conf" client.ovpn +server.ovpn: sample-config-files/server.conf + -rm -f server.ovpn + cp "$(srcdir)/sample-config-files/server.conf" server.ovpn +endif diff --git a/images/Makefile.in b/sample/Makefile.in index afda84e..320f763 100644 --- a/images/Makefile.in +++ b/sample/Makefile.in @@ -23,20 +23,7 @@ # 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 +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> # VPATH = @srcdir@ @@ -58,12 +45,16 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = images -DIST_COMMON = $(am__dist_image_DATA_DIST) $(am__dist_noinst_DATA_DIST) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in +subdir = sample +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac +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 @@ -72,7 +63,6 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = -am__dist_image_DATA_DIST = install-whirl.bmp icon.ico am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -94,12 +84,13 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(imagedir)" -am__dist_noinst_DATA_DIST = install-whirl.bmp icon.ico -DATA = $(dist_image_DATA) $(dist_noinst_DATA) +am__installdirs = "$(DESTDIR)$(sampledir)" +DATA = $(sample_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -112,11 +103,17 @@ 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@ @@ -125,15 +122,40 @@ 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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ MAKEINFO = @MAKEINFO@ MAN2HTML = @MAN2HTML@ 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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -142,19 +164,35 @@ 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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ -TAP_ID = @TAP_ID@ -TAP_WIN32_MIN_MAJOR = @TAP_WIN32_MIN_MAJOR@ -TAP_WIN32_MIN_MINOR = @TAP_WIN32_MIN_MINOR@ +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@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ @@ -189,9 +227,11 @@ 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@ @@ -200,15 +240,21 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -win32datadir = @win32datadir@ -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -images = \ - install-whirl.bmp \ - icon.ico - -@WIN32_TRUE@imagedir = $(win32datadir)/images -@WIN32_TRUE@dist_image_DATA = $(images) -@WIN32_FALSE@dist_noinst_DATA = $(images) +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + sample-plugins \ + sample-config-files \ + sample-windows \ + sample-keys \ + sample-scripts + +@WIN32_TRUE@sample_DATA = \ +@WIN32_TRUE@ client.ovpn \ +@WIN32_TRUE@ server.ovpn \ +@WIN32_TRUE@ sample-windows/sample.ovpn + all: all-am .SUFFIXES: @@ -221,9 +267,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu images/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu sample/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu images/Makefile + $(AUTOMAKE) --gnu sample/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -242,26 +288,32 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-dist_imageDATA: $(dist_image_DATA) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-sampleDATA: $(sample_DATA) @$(NORMAL_INSTALL) - test -z "$(imagedir)" || $(MKDIR_P) "$(DESTDIR)$(imagedir)" - @list='$(dist_image_DATA)'; test -n "$(imagedir)" || list=; \ + test -z "$(sampledir)" || $(MKDIR_P) "$(DESTDIR)$(sampledir)" + @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(imagedir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(imagedir)" || exit $$?; \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sampledir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(sampledir)" || exit $$?; \ done -uninstall-dist_imageDATA: +uninstall-sampleDATA: @$(NORMAL_UNINSTALL) - @list='$(dist_image_DATA)'; test -n "$(imagedir)" || list=; \ + @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(imagedir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(imagedir)" && rm -f $$files + echo " ( cd '$(DESTDIR)$(sampledir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sampledir)" && rm -f $$files tags: TAGS TAGS: @@ -303,7 +355,7 @@ check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: - for dir in "$(DESTDIR)$(imagedir)"; do \ + for dir in "$(DESTDIR)$(sampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -334,7 +386,7 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile @@ -352,7 +404,7 @@ info: info-am info-am: -install-data-am: install-dist_imageDATA +install-data-am: install-sampleDATA install-dvi: install-dvi-am @@ -386,7 +438,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-generic +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -396,22 +448,29 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_imageDATA +uninstall-am: uninstall-sampleDATA .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_imageDATA 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 pdf \ - pdf-am ps ps-am uninstall uninstall-am \ - uninstall-dist_imageDATA - +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + 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-sampleDATA \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-sampleDATA + + +@WIN32_TRUE@client.ovpn: sample-config-files/client.conf +@WIN32_TRUE@ -rm -f client.ovpn +@WIN32_TRUE@ cp "$(srcdir)/sample-config-files/client.conf" client.ovpn +@WIN32_TRUE@server.ovpn: sample-config-files/server.conf +@WIN32_TRUE@ -rm -f server.ovpn +@WIN32_TRUE@ cp "$(srcdir)/sample-config-files/server.conf" server.ovpn # 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/sample-config-files/README b/sample/sample-config-files/README index d53ac79..d53ac79 100644 --- a/sample-config-files/README +++ b/sample/sample-config-files/README diff --git a/sample-config-files/client.conf b/sample/sample-config-files/client.conf index 58b2038..58b2038 100644 --- a/sample-config-files/client.conf +++ b/sample/sample-config-files/client.conf diff --git a/sample-config-files/firewall.sh b/sample/sample-config-files/firewall.sh index 19d75ee..19d75ee 100755 --- a/sample-config-files/firewall.sh +++ b/sample/sample-config-files/firewall.sh diff --git a/sample-config-files/home.up b/sample/sample-config-files/home.up index 9c347cc..9c347cc 100755 --- a/sample-config-files/home.up +++ b/sample/sample-config-files/home.up diff --git a/sample-config-files/loopback-client b/sample/sample-config-files/loopback-client index d7f59e6..d7f59e6 100644 --- a/sample-config-files/loopback-client +++ b/sample/sample-config-files/loopback-client diff --git a/sample-config-files/loopback-server b/sample/sample-config-files/loopback-server index 9d21bce..9d21bce 100644 --- a/sample-config-files/loopback-server +++ b/sample/sample-config-files/loopback-server diff --git a/sample-config-files/office.up b/sample/sample-config-files/office.up index 74a71a3..74a71a3 100755 --- a/sample-config-files/office.up +++ b/sample/sample-config-files/office.up diff --git a/sample-config-files/openvpn-shutdown.sh b/sample/sample-config-files/openvpn-shutdown.sh index 8ed2d1d..8ed2d1d 100755 --- a/sample-config-files/openvpn-shutdown.sh +++ b/sample/sample-config-files/openvpn-shutdown.sh diff --git a/sample-config-files/openvpn-startup.sh b/sample/sample-config-files/openvpn-startup.sh index 0ee006b..0ee006b 100755 --- a/sample-config-files/openvpn-startup.sh +++ b/sample/sample-config-files/openvpn-startup.sh diff --git a/sample-config-files/server.conf b/sample/sample-config-files/server.conf index f483b6b..f483b6b 100644 --- a/sample-config-files/server.conf +++ b/sample/sample-config-files/server.conf diff --git a/sample-config-files/static-home.conf b/sample/sample-config-files/static-home.conf index c966687..c966687 100644 --- a/sample-config-files/static-home.conf +++ b/sample/sample-config-files/static-home.conf diff --git a/sample-config-files/static-office.conf b/sample/sample-config-files/static-office.conf index 68030cc..68030cc 100644 --- a/sample-config-files/static-office.conf +++ b/sample/sample-config-files/static-office.conf diff --git a/sample-config-files/tls-home.conf b/sample/sample-config-files/tls-home.conf index daa4ea1..daa4ea1 100644 --- a/sample-config-files/tls-home.conf +++ b/sample/sample-config-files/tls-home.conf diff --git a/sample-config-files/tls-office.conf b/sample/sample-config-files/tls-office.conf index f790f46..f790f46 100644 --- a/sample-config-files/tls-office.conf +++ b/sample/sample-config-files/tls-office.conf diff --git a/sample-config-files/xinetd-client-config b/sample/sample-config-files/xinetd-client-config index 03c5c1f..03c5c1f 100644 --- a/sample-config-files/xinetd-client-config +++ b/sample/sample-config-files/xinetd-client-config diff --git a/sample-config-files/xinetd-server-config b/sample/sample-config-files/xinetd-server-config index 803a6f8..803a6f8 100644 --- a/sample-config-files/xinetd-server-config +++ b/sample/sample-config-files/xinetd-server-config diff --git a/sample-keys/README b/sample/sample-keys/README index 1cd473a..1cd473a 100644 --- a/sample-keys/README +++ b/sample/sample-keys/README diff --git a/sample-keys/ca.crt b/sample/sample-keys/ca.crt index e063ccc..e063ccc 100644 --- a/sample-keys/ca.crt +++ b/sample/sample-keys/ca.crt diff --git a/sample-keys/ca.key b/sample/sample-keys/ca.key index b4bf792..b4bf792 100644 --- a/sample-keys/ca.key +++ b/sample/sample-keys/ca.key diff --git a/sample-keys/client.crt b/sample/sample-keys/client.crt index c047446..c047446 100644 --- a/sample-keys/client.crt +++ b/sample/sample-keys/client.crt diff --git a/sample-keys/client.key b/sample/sample-keys/client.key index 17b9509..17b9509 100644 --- a/sample-keys/client.key +++ b/sample/sample-keys/client.key diff --git a/sample-keys/dh1024.pem b/sample/sample-keys/dh1024.pem index 7ce05f0..7ce05f0 100644 --- a/sample-keys/dh1024.pem +++ b/sample/sample-keys/dh1024.pem diff --git a/sample-keys/pass.crt b/sample/sample-keys/pass.crt index 8bb7b17..8bb7b17 100644 --- a/sample-keys/pass.crt +++ b/sample/sample-keys/pass.crt diff --git a/sample-keys/pass.key b/sample/sample-keys/pass.key index 4916364..4916364 100644 --- a/sample-keys/pass.key +++ b/sample/sample-keys/pass.key diff --git a/sample-keys/pkcs12.p12 b/sample/sample-keys/pkcs12.p12 Binary files differindex 253d408..253d408 100644 --- a/sample-keys/pkcs12.p12 +++ b/sample/sample-keys/pkcs12.p12 diff --git a/sample-keys/server.crt b/sample/sample-keys/server.crt index 28bb4d9..28bb4d9 100644 --- a/sample-keys/server.crt +++ b/sample/sample-keys/server.crt diff --git a/sample-keys/server.key b/sample/sample-keys/server.key index 976acab..976acab 100644 --- a/sample-keys/server.key +++ b/sample/sample-keys/server.key diff --git a/plugin/defer/README b/sample/sample-plugins/defer/README index d8990f8..d8990f8 100644 --- a/plugin/defer/README +++ b/sample/sample-plugins/defer/README diff --git a/sample/sample-plugins/defer/build b/sample/sample-plugins/defer/build new file mode 100755 index 0000000..0612c08 --- /dev/null +++ b/sample/sample-plugins/defer/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../../../include}" + +CC="${CC:-gcc}" +CFLAGS="${CFLAGS:--O2 -Wall -g}" + +$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ +$CC $CFLAGS -fPIC -shared ${LDFLAS} -Wl,-soname,$1.so -o $1.so $1.o -lc diff --git a/plugin/defer/simple.c b/sample/sample-plugins/defer/simple.c index 6539865..6539865 100644 --- a/plugin/defer/simple.c +++ b/sample/sample-plugins/defer/simple.c diff --git a/plugin/defer/simple.def b/sample/sample-plugins/defer/simple.def index a87507d..a87507d 100755 --- a/plugin/defer/simple.def +++ b/sample/sample-plugins/defer/simple.def diff --git a/plugin/examples/winbuild b/sample/sample-plugins/defer/winbuild index 97e724a..82927d9 100755 --- a/plugin/examples/winbuild +++ b/sample/sample-plugins/defer/winbuild @@ -5,7 +5,7 @@ # # This directory is where we will look for openvpn-plugin.h -INCLUDE="-I.." +INCLUDE="-I../../../build" CC_FLAGS="-O2 -Wall" diff --git a/plugin/examples/build b/sample/sample-plugins/log/build index 5907afa..bbb05f7 100755 --- a/plugin/examples/build +++ b/sample/sample-plugins/log/build @@ -6,9 +6,10 @@ # # This directory is where we will look for openvpn-plugin.h -INCLUDE="-I../.." +CPPFLAGS="${CPPFLAGS:--I../../..}" -CC_FLAGS="-O2 -Wall -g" +CC="${CC:-gcc}" +CFLAGS="${CFLAGS:--O2 -Wall -g}" -gcc $CC_FLAGS -fPIC -c $INCLUDE $1.c && \ -gcc $CC_FLAGS -fPIC -shared -Wl,-soname,$1.so -o $1.so $1.o -lc +$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/plugin/examples/log.c b/sample/sample-plugins/log/log.c index 1cc4650..1cc4650 100644 --- a/plugin/examples/log.c +++ b/sample/sample-plugins/log/log.c diff --git a/sample/sample-plugins/log/log_v3.c b/sample/sample-plugins/log/log_v3.c new file mode 100644 index 0000000..742c756 --- /dev/null +++ b/sample/sample-plugins/log/log_v3.c @@ -0,0 +1,247 @@ +/* + * 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-2009 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.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 plugin is similar to simple.c, except it also logs extra information + * to stdout for every plugin method called by OpenVPN. The only difference + * between this (log_v3.c) and log.c is that this module uses the v3 plug-in + * API. + * + * See the README file for build instructions. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define ENABLE_SSL + +#include "openvpn-plugin.h" + +/* + * Our context, where we keep our state. + */ +struct plugin_context { + const char *username; + const char *password; +}; + +/* + * 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 v3structver, + struct openvpn_plugin_args_open_in const *args, + struct openvpn_plugin_args_open_return *ret) +{ + struct plugin_context *context = NULL; + + /* Check that we are API compatible */ + if( v3structver != OPENVPN_PLUGINv3_STRUCTVER ) { + return OPENVPN_PLUGIN_FUNC_ERROR; + } + + /* Which callbacks to intercept. */ + ret->type_mask = + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ROUTE_UP) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_IPCHANGE) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_VERIFY) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); + + + /* Allocate our context */ + context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); + + /* Set the username/password we will require. */ + context->username = "foo"; + context->password = "bar"; + + /* Point the global context handle to our newly created context */ + ret->handle = (void *) context; + + return OPENVPN_PLUGIN_FUNC_SUCCESS; +} + +void +show (const int type, const char *argv[], const char *envp[]) +{ + size_t i; + switch (type) + { + case OPENVPN_PLUGIN_UP: + printf ("OPENVPN_PLUGIN_UP\n"); + break; + case OPENVPN_PLUGIN_DOWN: + printf ("OPENVPN_PLUGIN_DOWN\n"); + break; + case OPENVPN_PLUGIN_ROUTE_UP: + printf ("OPENVPN_PLUGIN_ROUTE_UP\n"); + break; + case OPENVPN_PLUGIN_IPCHANGE: + printf ("OPENVPN_PLUGIN_IPCHANGE\n"); + break; + case OPENVPN_PLUGIN_TLS_VERIFY: + printf ("OPENVPN_PLUGIN_TLS_VERIFY\n"); + break; + case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: + printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n"); + break; + case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: + printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n"); + break; + case OPENVPN_PLUGIN_CLIENT_DISCONNECT: + printf ("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n"); + break; + case OPENVPN_PLUGIN_LEARN_ADDRESS: + printf ("OPENVPN_PLUGIN_LEARN_ADDRESS\n"); + break; + case OPENVPN_PLUGIN_TLS_FINAL: + printf ("OPENVPN_PLUGIN_TLS_FINAL\n"); + break; + default: + printf ("OPENVPN_PLUGIN_?\n"); + break; + } + + printf ("ARGV\n"); + for (i = 0; argv[i] != NULL; ++i) + printf ("%d '%s'\n", (int)i, argv[i]); + + printf ("ENVP\n"); + for (i = 0; envp[i] != NULL; ++i) + printf ("%d '%s'\n", (int)i, envp[i]); +} + +static void +x509_print_info (X509 *x509crt) +{ + int i, n; + int fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME *x509_name; + X509_NAME_ENTRY *ent; + const char *objbuf; + unsigned char *buf; + + x509_name = X509_get_subject_name (x509crt); + n = X509_NAME_entry_count (x509_name); + for (i = 0; i < n; ++i) + { + ent = X509_NAME_get_entry (x509_name, i); + if (!ent) + continue; + fn = X509_NAME_ENTRY_get_object (ent); + if (!fn) + continue; + val = X509_NAME_ENTRY_get_data (ent); + if (!val) + continue; + fn_nid = OBJ_obj2nid (fn); + if (fn_nid == NID_undef) + continue; + objbuf = OBJ_nid2sn (fn_nid); + if (!objbuf) + continue; + 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) + continue; + + printf("X509 %s: %s\n", objbuf, (char *)buf); + OPENSSL_free (buf); + } +} + + + +OPENVPN_EXPORT int +openvpn_plugin_func_v3 (const int version, + struct openvpn_plugin_args_func_in const *args, + struct openvpn_plugin_args_func_return *retptr) +{ + struct plugin_context *context = (struct plugin_context *) args->handle; + + printf("\nopenvpn_plugin_func_v3() :::::>> "); + show (args->type, args->argv, args->envp); + + /* Dump some X509 information if we're in the TLS_VERIFY phase */ + if ((args->type == OPENVPN_PLUGIN_TLS_VERIFY) && args->current_cert ) { + printf("---- X509 Subject information ----\n"); + printf("Certificate depth: %i\n", args->current_cert_depth); + x509_print_info(args->current_cert); + printf("----------------------------------\n"); + } + + /* check entered username/password against what we require */ + if (args->type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) + { + /* get username/password from envp string array */ + const char *username = get_env ("username", args->envp); + const char *password = get_env ("password", args->envp); + + if (username && !strcmp (username, context->username) + && password && !strcmp (password, context->password)) + return OPENVPN_PLUGIN_FUNC_SUCCESS; + else + return OPENVPN_PLUGIN_FUNC_ERROR; + } + else + return OPENVPN_PLUGIN_FUNC_SUCCESS; +} + +OPENVPN_EXPORT void +openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) +{ + struct plugin_context *context = (struct plugin_context *) handle; + free (context); +} diff --git a/plugin/defer/winbuild b/sample/sample-plugins/log/winbuild index 97e724a..decf05f 100755 --- a/plugin/defer/winbuild +++ b/sample/sample-plugins/log/winbuild @@ -5,7 +5,7 @@ # # This directory is where we will look for openvpn-plugin.h -INCLUDE="-I.." +INCLUDE="-I../../../include" CC_FLAGS="-O2 -Wall" diff --git a/plugin/examples/README b/sample/sample-plugins/simple/README index 4400cd3..4400cd3 100644 --- a/plugin/examples/README +++ b/sample/sample-plugins/simple/README diff --git a/plugin/defer/build b/sample/sample-plugins/simple/build index 5907afa..bbb05f7 100755 --- a/plugin/defer/build +++ b/sample/sample-plugins/simple/build @@ -6,9 +6,10 @@ # # This directory is where we will look for openvpn-plugin.h -INCLUDE="-I../.." +CPPFLAGS="${CPPFLAGS:--I../../..}" -CC_FLAGS="-O2 -Wall -g" +CC="${CC:-gcc}" +CFLAGS="${CFLAGS:--O2 -Wall -g}" -gcc $CC_FLAGS -fPIC -c $INCLUDE $1.c && \ -gcc $CC_FLAGS -fPIC -shared -Wl,-soname,$1.so -o $1.so $1.o -lc +$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/plugin/examples/simple.c b/sample/sample-plugins/simple/simple.c index f26d89f..f26d89f 100644 --- a/plugin/examples/simple.c +++ b/sample/sample-plugins/simple/simple.c diff --git a/plugin/examples/simple.def b/sample/sample-plugins/simple/simple.def index a87507d..a87507d 100755 --- a/plugin/examples/simple.def +++ b/sample/sample-plugins/simple/simple.def diff --git a/sample/sample-plugins/simple/winbuild b/sample/sample-plugins/simple/winbuild new file mode 100755 index 0000000..decf05f --- /dev/null +++ b/sample/sample-plugins/simple/winbuild @@ -0,0 +1,18 @@ +# +# Build an OpenVPN plugin module on Windows/MinGW. +# 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 +INCLUDE="-I../../../include" + +CC_FLAGS="-O2 -Wall" + +gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c +gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o +rm junk.tmp +dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def +rm base.tmp +gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp +rm temp.exp diff --git a/sample-scripts/auth-pam.pl b/sample/sample-scripts/auth-pam.pl index 5333bad..5333bad 100755 --- a/sample-scripts/auth-pam.pl +++ b/sample/sample-scripts/auth-pam.pl diff --git a/sample-scripts/bridge-start b/sample/sample-scripts/bridge-start index d20a260..d20a260 100755 --- a/sample-scripts/bridge-start +++ b/sample/sample-scripts/bridge-start diff --git a/sample-scripts/bridge-stop b/sample/sample-scripts/bridge-stop index 8192779..8192779 100755 --- a/sample-scripts/bridge-stop +++ b/sample/sample-scripts/bridge-stop diff --git a/sample-scripts/ucn.pl b/sample/sample-scripts/ucn.pl index 6d708f8..6d708f8 100755 --- a/sample-scripts/ucn.pl +++ b/sample/sample-scripts/ucn.pl diff --git a/sample-scripts/verify-cn b/sample/sample-scripts/verify-cn index f9fea0f..6e747ef 100755 --- a/sample-scripts/verify-cn +++ b/sample/sample-scripts/verify-cn @@ -3,7 +3,7 @@ # verify-cn -- a sample OpenVPN tls-verify script # # Return 0 if cn matches the common name component of -# X509_NAME_oneline, 1 otherwise. +# subject, 1 otherwise. # # For example in OpenVPN, you could use the directive: # @@ -13,7 +13,7 @@ # the client common name is listed on a line in the # allowed_clients file. -die "usage: verify-cn cnfile certificate_depth X509_NAME_oneline" if (@ARGV != 3); +die "usage: verify-cn cnfile certificate_depth subject" if (@ARGV != 3); # Parse out arguments: # cnfile -- The file containing the list of common names, one per @@ -37,7 +37,7 @@ if ($depth == 0) { # If so, parse out the common name substring in # the X509 subject string. - if ($x509 =~ /\/CN=([^\/]+)/) { + if ($x509 =~ / CN=([^,]+)/) { $cn = $1; # Accept the connection if the X509 common name # string matches the passed cn argument. diff --git a/install-win32/sample.ovpn b/sample/sample-windows/sample.ovpn index 5accd57..5accd57 100755 --- a/install-win32/sample.ovpn +++ b/sample/sample-windows/sample.ovpn diff --git a/service-win32/Makefile.am b/service-win32/Makefile.am deleted file mode 100644 index 4e4f55e..0000000 --- a/service-win32/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -# -# 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-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 -# - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -if WIN32 - -sbin_PROGRAMS = openvpnserv - -openvpnserv_SOURCES = \ - openvpnserv.c \ - service.h service.c - -else - -dist_noinst_DATA = \ - openvpnserv.c \ - service.h service.c - -endif diff --git a/service-win32/msvc.mak b/service-win32/msvc.mak deleted file mode 100644 index ba4bab7..0000000 --- a/service-win32/msvc.mak +++ /dev/null @@ -1,30 +0,0 @@ -# This makefile builds the OpenVPN service wrapper for Windows in the -# Visual Studio 2008 environment. - -# Some of these libs may not be needed -LIBS = ws2_32.lib crypt32.lib iphlpapi.lib winmm.lib user32.lib gdi32.lib advapi32.lib wininet.lib -EXE = openvpnserv.exe - -CPP=cl.exe -CPP_ARG_COMMON=/nologo /W3 -DWIN32 -DWIN32_LEAN_AND_MEAN -D_CONSOLE -D_MBCS -D_CRT_SECURE_NO_DEPRECATE /FD /c -I".." -CPP_PROJ=$(CPP_ARG_COMMON) /O2 /MD -DNDEBUG - -LINK32=link.exe -LINK32_FLAGS=/nologo /subsystem:console /incremental:no - -OBJS = \ - openvpnserv.obj \ - service.obj - -openvpnserv : $(OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) "/out:$(EXE)" $(LIBS) $(OBJS) -<< - -clean : - del /Q $(OBJS) $(EXE) *.idb *.pdb - -.c.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..c04468a --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,15 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = compat openvpn openvpnserv plugins diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..d5cced6 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,613 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +VPATH = @srcdir@ +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 = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +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@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = compat openvpn openvpnserv 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) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/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. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive 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-recursive \ + 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/src/compat/Makefile.am b/src/compat/Makefile.am new file mode 100644 index 0000000..7ad4452 --- /dev/null +++ b/src/compat/Makefile.am @@ -0,0 +1,29 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + compat.vcxproj \ + compat.vcxproj.filters + +noinst_LTLIBRARIES = libcompat.la + +libcompat_la_SOURCES = \ + compat.h \ + compat-stdbool.h \ + compat-dirname.c \ + compat-basename.c \ + compat-gettimeofday.c \ + compat-daemon.c \ + compat-inet_ntop.c \ + compat-inet_pton.c diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in new file mode 100644 index 0000000..c9e8f3b --- /dev/null +++ b/src/compat/Makefile.in @@ -0,0 +1,546 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +VPATH = @srcdir@ +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 = src/compat +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +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 +libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libcompat_la_SOURCES) +DIST_SOURCES = $(libcompat_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + compat.vcxproj \ + compat.vcxproj.filters + +noinst_LTLIBRARIES = libcompat.la +libcompat_la_SOURCES = \ + compat.h \ + compat-stdbool.h \ + compat-dirname.c \ + compat-basename.c \ + compat-gettimeofday.c \ + compat-daemon.c \ + compat-inet_ntop.c \ + compat-inet_pton.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) --gnu src/compat/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/compat/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-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) + $(LINK) $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-basename.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-daemon.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-dirname.Plo@am__quote@ +@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@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + 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: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags 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 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/src/compat/compat-basename.c b/src/compat/compat-basename.c new file mode 100644 index 0000000..a057691 --- /dev/null +++ b/src/compat/compat-basename.c @@ -0,0 +1,50 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 + +#ifndef HAVE_BASENAME + +#include "compat.h" +#include <string.h> + +/* Modified version based on glibc-2.14.1 by Roland McGrath <roland@gnu.org> + * This version is extended to handle both / and \ in path names + */ +char * +basename (char *filename) +{ + char *p = strrchr (filename, '/'); + if (!p) { + /* If NULL, check for \ instead ... might be Windows a path */ + p = strrchr (filename, '\\'); + } + return p ? p + 1 : (char *) filename; +} + +#endif /* HAVE_BASENAME */ diff --git a/src/compat/compat-daemon.c b/src/compat/compat-daemon.c new file mode 100644 index 0000000..dde96a2 --- /dev/null +++ b/src/compat/compat-daemon.c @@ -0,0 +1,100 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 + +#ifndef HAVE_DAEMON + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif + +int +daemon(int nochdir, int noclose) +{ +#if defined(HAVE_FORK) && defined(HAVE_SETSID) + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + chdir("/"); + + if (!noclose) { +#if defined(HAVE_DUP) && defined(HAVE_DUP2) + int fd; + if ((fd = open ("/dev/null", O_RDWR, 0)) != -1) { + dup2 (fd, 0); + dup2 (fd, 1); + dup2 (fd, 2); + if (fd > 2) { + close (fd); + } + } +#endif + } + + return 0; +#else + (void)nochdir; + (void)noclose; + errno = EFAULT; + return -1; +#endif +} + +#endif + diff --git a/src/compat/compat-dirname.c b/src/compat/compat-dirname.c new file mode 100644 index 0000000..8878595 --- /dev/null +++ b/src/compat/compat-dirname.c @@ -0,0 +1,119 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 + + +#ifndef HAVE_DIRNAME + +#include "compat.h" +#include <string.h> + +/* Unoptimised version of glibc memrchr(). + * This is considered fast enough, as only this compat + * version of dirname() depends on it. + */ +static const char * +__memrchr(const char *str, int c, size_t n) +{ + const char *end = str; + + end += n - 1; /* Go to the end of the string */ + while (end >= str) { + if(c == *end) + return end; + else + end--; + } + return NULL; +} + +/* Modified version based on glibc-2.14.1 by Ulrich Drepper <drepper@akkadia.org> + * This version is extended to handle both / and \ in path names. + */ +char * +dirname (char *path) +{ + static const char dot[] = "."; + char *last_slash; + char separator = '/'; + + /* Find last '/'. */ + last_slash = path != NULL ? strrchr (path, '/') : NULL; + /* If NULL, check for \ instead ... might be Windows a path */ + if (!last_slash) { + last_slash = path != NULL ? strrchr (path, '\\') : NULL; + separator = last_slash ? '\\' : '/'; /* Change the separator if \ was found */ + } + + if (last_slash != NULL && last_slash != path && last_slash[1] == '\0') { + /* Determine whether all remaining characters are slashes. */ + char *runp; + + for (runp = last_slash; runp != path; --runp) + if (runp[-1] != separator) + break; + + /* The '/' is the last character, we have to look further. */ + if (runp != path) + last_slash = (char *) __memrchr (path, separator, runp - path); + } + + if (last_slash != NULL) { + /* Determine whether all remaining characters are slashes. */ + char *runp; + + for (runp = last_slash; runp != path; --runp) + if (runp[-1] != separator) + break; + + /* Terminate the path. */ + if (runp == path) { + /* The last slash is the first character in the string. We have to + return "/". As a special case we have to return "//" if there + are exactly two slashes at the beginning of the string. See + XBD 4.10 Path Name Resolution for more information. */ + if (last_slash == path + 1) + ++last_slash; + else + last_slash = path + 1; + } + else + last_slash = runp; + + last_slash[0] = '\0'; + } else + /* This assignment is ill-designed but the XPG specs require to + return a string containing "." in any case no directory part is + found and so a static and constant string is required. */ + path = (char *) dot; + + return path; +} + +#endif /* HAVE_DIRNAME */ diff --git a/src/compat/compat-gettimeofday.c b/src/compat/compat-gettimeofday.c new file mode 100644 index 0000000..0f32d5d --- /dev/null +++ b/src/compat/compat-gettimeofday.c @@ -0,0 +1,131 @@ +/* + * 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-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 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifndef HAVE_GETTIMEOFDAY + +#include "compat.h" + +#ifdef WIN32 +/* + * NOTICE: mingw has much faster gettimeofday! + * autoconf will set HAVE_GETTIMEOFDAY + */ + +#include <windows.h> +#include <time.h> + +static time_t gtc_base = 0; +static DWORD gtc_last = 0; +static time_t last_sec = 0; +static unsigned int last_msec = 0; +static int bt_last = 0; + +static void +gettimeofday_calibrate (void) +{ + const time_t t = time(NULL); + const DWORD gtc = GetTickCount(); + gtc_base = t - gtc/1000; + gtc_last = gtc; +} + +/* + * Rewritten by JY for OpenVPN 2.1, after I realized that + * QueryPerformanceCounter takes nearly 2 orders of magnitude + * more processor cycles than GetTickCount. + */ +int +gettimeofday (struct timeval *tv, void *tz) +{ + const DWORD gtc = GetTickCount(); + int bt = 0; + time_t sec; + unsigned int msec; + const int backtrack_hold_seconds = 10; + + (void)tz; + + /* recalibrate at the dreaded 49.7 day mark */ + if (!gtc_base || gtc < gtc_last) + gettimeofday_calibrate (); + gtc_last = gtc; + + sec = gtc_base + gtc / 1000; + msec = gtc % 1000; + + if (sec == last_sec) + { + if (msec < last_msec) + { + msec = last_msec; + bt = 1; + } + } + else if (sec < last_sec) + { + /* We try to dampen out backtracks of less than backtrack_hold_seconds. + Larger backtracks will be passed through and dealt with by the + TIME_BACKTRACK_PROTECTION code (if enabled) */ + if (sec > last_sec - backtrack_hold_seconds) + { + sec = last_sec; + msec = last_msec; + } + bt = 1; + } + + tv->tv_sec = (long)last_sec = (long)sec; + tv->tv_usec = (last_msec = msec) * 1000; + + if (bt && !bt_last) + gettimeofday_calibrate (); + bt_last = bt; + + return 0; +} + +#else + +#ifdef HAVE_TIME_H +#include <time.h> +#endif + +int +gettimeofday (struct timeval *tv, void *tz) +{ + (void)tz; + tv->tv_sec = time(NULL); + tv->tv_usec = 0; + return 0; +} + +#endif /* WIN32 */ + +#endif /* HAVE_GETTIMEOFDAY */ diff --git a/src/compat/compat-inet_ntop.c b/src/compat/compat-inet_ntop.c new file mode 100644 index 0000000..0d52142 --- /dev/null +++ b/src/compat/compat-inet_ntop.c @@ -0,0 +1,76 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 + +#ifndef HAVE_INET_NTOP + +#include "compat.h" + +#ifdef WIN32 + +#include <windows.h> + +/* + * inet_ntop() and inet_pton() wrap-implementations using + * WSAAddressToString() and WSAStringToAddress() functions + * + * this is needed as long as we support running OpenVPN on WinXP + */ + +const char * +inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + struct sockaddr_storage ss; + unsigned long s = size; + + ZeroMemory(&ss, sizeof(ss)); + ss.ss_family = af; + + switch(af) { + case AF_INET: + ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; + break; + case AF_INET6: + ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; + break; + default: + return NULL; + } + /* cannot direclty use &size because of strict aliasing rules */ + return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? + dst : NULL; +} + +#else + +#error no emulation for inet_ntop + +#endif + +#endif diff --git a/src/compat/compat-inet_pton.c b/src/compat/compat-inet_pton.c new file mode 100644 index 0000000..cdc8d4b --- /dev/null +++ b/src/compat/compat-inet_pton.c @@ -0,0 +1,79 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 + +#ifndef HAVE_INET_PTON + +#include "compat.h" + +#ifdef WIN32 + +#include <windows.h> +#include <string.h> + +/* + * inet_ntop() and inet_pton() wrap-implementations using + * WSAAddressToString() and WSAStringToAddress() functions + * + * this is needed as long as we support running OpenVPN on WinXP + */ + + +int +inet_pton(int af, const char *src, void *dst) +{ + struct sockaddr_storage ss; + int size = sizeof(ss); + char src_copy[INET6_ADDRSTRLEN+1]; + + ZeroMemory(&ss, sizeof(ss)); + /* stupid non-const API */ + strncpy (src_copy, src, INET6_ADDRSTRLEN+1); + src_copy[INET6_ADDRSTRLEN] = 0; + + if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { + switch(af) { + case AF_INET: + *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; + return 1; + case AF_INET6: + *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; + return 1; + } + } + return 0; +} + +#else + +#error no emulation for inet_ntop + +#endif + +#endif diff --git a/src/compat/compat-stdbool.h b/src/compat/compat-stdbool.h new file mode 100644 index 0000000..9941218 --- /dev/null +++ b/src/compat/compat-stdbool.h @@ -0,0 +1,12 @@ +#ifndef __COMPAT_STDBOOL_H +#define __COMPAT_STDBOOL_H + +#ifdef HAVE_STDBOOL_H +#include <stdbool.h> +#else +typedef int bool; +#define false 0 +#define true 1 +#endif + +#endif diff --git a/src/compat/compat.h b/src/compat/compat.h new file mode 100644 index 0000000..021573e --- /dev/null +++ b/src/compat/compat.h @@ -0,0 +1,68 @@ +/* + * 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) 2011 - David Sommerseth <davids@redhat.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 COMPAT_H +#define COMPAT_H + +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif + +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#ifndef HAVE_DIRNAME +char * dirname(char *str); +#endif /* HAVE_DIRNAME */ + +#ifndef HAVE_BASENAME +char * basename(char *str); +#endif /* HAVE_BASENAME */ + +#ifndef HAVE_GETTIMEOFDAY +int gettimeofday (struct timeval *tv, void *tz); +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +#ifndef HAVE_INET_NTOP +const char * inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +#ifndef HAVE_INET_PTON +int inet_pton(int af, const char *src, void *dst); +#endif + +#endif /* COMPAT_H */ diff --git a/src/compat/compat.vcxproj b/src/compat/compat.vcxproj new file mode 100644 index 0000000..42979c1 --- /dev/null +++ b/src/compat/compat.vcxproj @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4B2E2719-E661-45D7-9203-F6F456B22F19}</ProjectGuid> + <RootNamespace>compat</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(SOURCEBASE);$(SOURCEBASE)/include;$(OPENSSL_HOME)/include;$(LZO_HOME)/include;$(PKCS11H_HOME)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>$(SOURCEBASE);$(SOURCEBASE)/include;$(OPENSSL_HOME)/include;$(LZO_HOME)/include;$(PKCS11H_HOME)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="compat-basename.c" /> + <ClCompile Include="compat-dirname.c" /> + <ClCompile Include="compat-gettimeofday.c" /> + <ClCompile Include="compat-inet_ntop.c" /> + <ClCompile Include="compat-inet_pton.c" /> + <ClCompile Include="compat-daemon.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="compat.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/compat/compat.vcxproj.filters b/src/compat/compat.vcxproj.filters new file mode 100644 index 0000000..00bb0ff --- /dev/null +++ b/src/compat/compat.vcxproj.filters @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="compat-basename.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="compat-dirname.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="compat-gettimeofday.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="compat-inet_ntop.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="compat-inet_pton.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="compat-daemon.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="compat.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am new file mode 100644 index 0000000..5d38628 --- /dev/null +++ b/src/openvpn/Makefile.am @@ -0,0 +1,126 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +include $(top_srcdir)/build/ltrc.inc + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + openvpn.vcxproj \ + openvpn.vcxproj.filters + +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/compat + +AM_CFLAGS = \ + $(TAP_CFLAGS) \ + $(OPTIONAL_CRYPTO_CFLAGS) \ + $(OPTIONAL_LZO_CFLAGS) \ + $(OPTIONAL_PKCS11_HELPER_CFLAGS) +if WIN32 +# we want unicode entry point but not the macro +AM_CFLAGS += -municode -UUNICODE +endif + +sbin_PROGRAMS = openvpn + +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 crypto_backend.h \ + crypto_openssl.c crypto_openssl.h \ + crypto_polarssl.c crypto_polarssl.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.c \ + cryptoapi.h cryptoapi.c +openvpn_LDADD = \ + $(top_builddir)/src/compat/libcompat.la \ + $(SOCKETS_LIBS) \ + $(OPTIONAL_LZO_LIBS) \ + $(OPTIONAL_PKCS11_HELPER_LIBS) \ + $(OPTIONAL_CRYPTO_LIBS) \ + $(OPTIONAL_SELINUX_LIBS) \ + $(OPTIONAL_DL_LIBS) +if WIN32 +openvpn_SOURCES += openvpn_win32_resources.rc +openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm +endif diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in new file mode 100644 index 0000000..d5f21c4 --- /dev/null +++ b/src/openvpn/Makefile.in @@ -0,0 +1,758 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +# +# 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) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +# Required to build Windows resource file + +VPATH = @srcdir@ +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@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/build/ltrc.inc +# 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 -lwinmm +subdir = src/openvpn +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 +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 \ + 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.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) \ + 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) \ + win32.$(OBJEXT) cryptoapi.$(OBJEXT) $(am__objects_1) +openvpn_OBJECTS = $(am_openvpn_OBJECTS) +am__DEPENDENCIES_1 = +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) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(openvpn_SOURCES) +DIST_SOURCES = $(am__openvpn_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) + +LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + openvpn.vcxproj \ + openvpn.vcxproj.filters + +INCLUDES = \ + -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 \ + crypto_backend.h crypto_openssl.c crypto_openssl.h \ + crypto_polarssl.c crypto_polarssl.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.c cryptoapi.h cryptoapi.c \ + $(am__append_2) +openvpn_LDADD = $(top_builddir)/src/compat/libcompat.la \ + $(SOCKETS_LIBS) $(OPTIONAL_LZO_LIBS) \ + $(OPTIONAL_PKCS11_HELPER_LIBS) $(OPTIONAL_CRYPTO_LIBS) \ + $(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_DL_LIBS) $(am__append_3) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .mc .o .obj .rc +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(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) --gnu src/openvpn/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/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): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_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 +openvpn$(EXEEXT): $(openvpn_OBJECTS) $(openvpn_DEPENDENCIES) + @rm -f openvpn$(EXEEXT) + $(LINK) $(openvpn_OBJECTS) $(openvpn_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.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)/console.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.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@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmisc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forward.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fragment.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gremlin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpdigest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lladdr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mroute.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mss.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mstats.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtcp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mudp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occ.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet_id.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ping.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_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@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reliable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_id.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shaper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_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_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)/tun.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + 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-sbinPROGRAMS + +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: uninstall-sbinPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS ctags 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-sbinPROGRAMS 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 uninstall uninstall-am uninstall-sbinPROGRAMS + + +.rc.lo: + $(LTRCCOMPILE) -i "$<" -o "$@" + +.rc.o: + $(RCCOMPILE) -i "$<" -o "$@" + +.mc.rc: + $(WINDMC) "$<" + +# 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/base64.c b/src/openvpn/base64.c index 3449ae5..bb89aae 100644 --- a/base64.c +++ b/src/openvpn/base64.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,9 +31,15 @@ * SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) +#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY) #include "base64.h" @@ -41,15 +47,21 @@ static char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - +/* + * base64 encode input data of length size to malloced + * buffer which is returned as *str. Returns string + * length of *str. + */ int -base64_encode(const void *data, int size, char **str) +openvpn_base64_encode(const void *data, int size, char **str) { char *s, *p; int i; int c; const unsigned char *q; + if (size < 0) + return -1; p = s = (char *) malloc(size * 4 / 3 + 4); if (p == NULL) return -1; @@ -113,24 +125,41 @@ token_decode(const char *token) return DECODE_ERROR; return (marker << 24) | val; } - +/* + * Decode base64 str, outputting data to buffer + * at data of length size. Return length of + * decoded data written or -1 on error or overflow. + */ int -base64_decode(const char *str, void *data) +openvpn_base64_decode(const char *str, void *data, int size) { const char *p; unsigned char *q; + unsigned char *e = NULL; q = data; + if (size >= 0) + e = q + size; for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { unsigned int val = token_decode(p); unsigned int marker = (val >> 24) & 0xff; if (val == DECODE_ERROR) return -1; + if (e && q >= e) + return -1; *q++ = (val >> 16) & 0xff; if (marker < 2) + { + if (e && q >= e) + return -1; *q++ = (val >> 8) & 0xff; + } if (marker < 1) + { + if (e && q >= e) + return -1; *q++ = val & 0xff; + } } return q - (unsigned char *) data; } diff --git a/base64.h b/src/openvpn/base64.h index 968d18d..28a9677 100644 --- a/base64.h +++ b/src/openvpn/base64.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -34,10 +34,10 @@ #ifndef _BASE64_H_ #define _BASE64_H_ -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) +#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY) -int base64_encode(const void *data, int size, char **str); -int base64_decode(const char *str, void *data); +int openvpn_base64_encode(const void *data, int size, char **str); +int openvpn_base64_decode(const char *str, void *data, int size); #endif diff --git a/basic.h b/src/openvpn/basic.h index 88539e2..298cf10 100644 --- a/basic.h +++ b/src/openvpn/basic.h @@ -25,19 +25,6 @@ #ifndef BASIC_H #define BASIC_H -/* bool definitions */ -#ifndef bool -#define bool int -#endif - -#ifndef true -#define true 1 -#endif - -#ifndef false -#define false 0 -#endif - #define BOOL_CAST(x) ((x) ? (true) : (false)) /* size of an array */ @@ -46,4 +33,6 @@ /* clear an object */ #define CLEAR(x) memset(&(x), 0, sizeof(x)) +#define IPV4_NETMASK_HOST 0xffffffffU + #endif diff --git a/buffer.c b/src/openvpn/buffer.c index e0a9a96..56d14b1 100644 --- a/buffer.c +++ b/src/openvpn/buffer.c @@ -22,12 +22,19 @@ * 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" #include "common.h" #include "buffer.h" #include "error.h" #include "mtu.h" +#include "misc.h" #include "memdbg.h" @@ -54,11 +61,21 @@ alloc_buf_debug (size_t size, const char *file, int line) alloc_buf (size_t size) #endif { + struct buffer buf; + + if (!buf_size_valid (size)) + buf_size_error (size); + buf.capacity = (int)size; + buf.offset = 0; + buf.len = 0; #ifdef DMALLOC - return alloc_buf_gc_debug (size, NULL, file, line); + buf.data = openvpn_dmalloc (file, line, size); #else - return alloc_buf_gc (size, NULL); + buf.data = calloc (1, size); #endif + check_malloc_return(buf.data); + + return buf; } struct buffer @@ -214,26 +231,45 @@ buf_printf (struct buffer *buf, const char *format, ...) return ret; } +bool +buf_puts(struct buffer *buf, const char *str) +{ + int ret = false; + uint8_t *ptr = BEND (buf); + int cap = buf_forward_capacity (buf); + if (cap > 0) + { + strncpynt ((char *)ptr,str, cap); + *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */ + buf->len += (int) strlen ((char *)ptr); + ret = true; + } + return ret; +} + + /* * This is necessary due to certain buggy implementations of snprintf, * that don't guarantee null termination for size > 0. * + * Return false on overflow. + * * This function is duplicated into service-win32/openvpnserv.c * Any modifications here should be done to the other place as well. */ -int openvpn_snprintf(char *str, size_t size, const char *format, ...) +bool openvpn_snprintf(char *str, size_t size, const char *format, ...) { va_list arglist; - int ret = 0; + int len = -1; if (size > 0) { va_start (arglist, format); - ret = vsnprintf (str, size, format, arglist); + len = vsnprintf (str, size, format, arglist); va_end (arglist); str[size - 1] = 0; } - return ret; + return (len >= 0 && len < size); } /* @@ -291,28 +327,19 @@ gc_malloc (size_t size, bool clear, struct gc_arena *a) #endif { void *ret; - if (a) - { - struct gc_entry *e; -#ifdef DMALLOC - e = (struct gc_entry *) openvpn_dmalloc (file, line, size + sizeof (struct gc_entry)); -#else - e = (struct gc_entry *) malloc (size + sizeof (struct gc_entry)); -#endif - check_malloc_return (e); - ret = (char *) e + sizeof (struct gc_entry); - e->next = a->list; - a->list = e; - } - else - { + struct gc_entry *e; + ASSERT (NULL != a); + #ifdef DMALLOC - ret = openvpn_dmalloc (file, line, size); + e = (struct gc_entry *) openvpn_dmalloc (file, line, size + sizeof (struct gc_entry)); #else - ret = malloc (size); + e = (struct gc_entry *) malloc (size + sizeof (struct gc_entry)); #endif - check_malloc_return (ret); - } + check_malloc_return (e); + ret = (char *) e + sizeof (struct gc_entry); + e->next = a->list; + a->list = e; + #ifndef ZERO_BUFFER_ON_ALLOC if (clear) #endif @@ -505,11 +532,25 @@ string_alloc (const char *str, struct gc_arena *gc) const int n = strlen (str) + 1; char *ret; + if (gc) { #ifdef DMALLOC - ret = (char *) gc_malloc_debug (n, false, gc, file, line); + ret = (char *) gc_malloc_debug (n, false, gc, file, line); #else - ret = (char *) gc_malloc (n, false, gc); + ret = (char *) gc_malloc (n, false, gc); #endif + } else { + /* If there are no garbage collector available, it's expected + * that the caller cleans up afterwards. This is coherent with the + * earlier behaviour when gc_malloc() would be called with gc == NULL + */ +#ifdef DMALLOC + ret = openvpn_dmalloc (file, line, n); + memset(ret, 0, n); +#else + ret = calloc(1, n); +#endif + check_malloc_return(ret); + } memcpy (ret, str, n); return ret; } @@ -701,7 +742,7 @@ char_class (const unsigned char c, const unsigned int flags) return true; if ((flags & CC_DIGIT) && isdigit (c)) return true; - if ((flags & CC_PRINT) && isprint (c)) + if ((flags & CC_PRINT) && (c >= 32 && c != 127)) /* allow ascii non-control and UTF-8, consider DEL to be a control */ return true; if ((flags & CC_PUNCT) && ispunct (c)) return true; @@ -741,6 +782,16 @@ char_class (const unsigned char c, const unsigned int flags) return true; if ((flags & CC_EQUAL) && c == '=') return true; + if ((flags & CC_LESS_THAN) && c == '<') + return true; + if ((flags & CC_GREATER_THAN) && c == '>') + return true; + if ((flags & CC_PIPE) && c == '|') + return true; + if ((flags & CC_QUESTION_MARK) && c == '?') + return true; + if ((flags & CC_ASTERISK) && c == '*') + return true; return false; } @@ -904,7 +955,7 @@ buffer_list_free (struct buffer_list *ol) bool buffer_list_defined (const struct buffer_list *ol) { - return ol->head != NULL; + return ol && ol->head != NULL; } void @@ -1039,7 +1090,7 @@ buffer_list_advance (struct buffer_list *ol, int n) struct buffer_list * buffer_list_file (const char *fn, int max_line_len) { - FILE *fp = fopen (fn, "r"); + FILE *fp = platform_fopen (fn, "r"); struct buffer_list *bl = NULL; if (fp) diff --git a/buffer.h b/src/openvpn/buffer.h index 3b24d09..5e11de0 100644 --- a/buffer.h +++ b/src/openvpn/buffer.h @@ -26,6 +26,7 @@ #define BUFFER_H #include "basic.h" +#include "error.h" #define BUF_SIZE_MAX 1000000 @@ -42,14 +43,30 @@ #define BUF_INIT_TRACKING #endif -/* basic buffer class for OpenVPN */ - +/**************************************************************************/ +/** + * Wrapper structure for dynamically allocated memory. + * + * The actual content stored in a \c buffer structure starts at the memory + * location \c buffer.data \c + \c buffer.offset, and has a length of \c + * buffer.len bytes. This, together with the space available before and + * after the content, is represented in the pseudocode below: +@code +uint8_t *content_start = buffer.data + buffer.offset; +uint8_t *content_end = buffer.data + buffer.offset + buffer.len; +int prepend_capacity = buffer.offset; +int append_capacity = buffer.capacity - (buffer.offset + buffer.len); +@endcode + */ struct buffer { - int capacity; /* size of buffer allocated by malloc */ - int offset; /* data starts at data + offset, offset > 0 to allow for efficient prepending */ - int len; /* length of data that starts at data + offset */ - uint8_t *data; + int capacity; /**< Size in bytes of memory allocated by + * \c malloc(). */ + int offset; /**< Offset in bytes of the actual content + * within the allocated memory. */ + int len; /**< Length in bytes of the actual content + * within the allocated memory. */ + uint8_t *data; /**< Pointer to the allocated memory. */ #ifdef BUF_INIT_TRACKING const char *debug_file; @@ -57,18 +74,41 @@ struct buffer #endif }; -/* for garbage collection */ +/**************************************************************************/ +/** + * Garbage collection entry for one dynamically allocated block of memory. + * + * This structure represents one link in the linked list contained in a \c + * gc_arena structure. Each time the \c gc_malloc() function is called, + * it allocates \c sizeof(gc_entry) + the requested number of bytes. The + * \c gc_entry is then stored as a header in front of the memory address + * returned to the caller. + */ struct gc_entry { - struct gc_entry *next; + struct gc_entry *next; /**< Pointer to the next item in the + * linked list. */ }; + +/** + * Garbage collection arena used to keep track of dynamically allocated + * memory. + * + * This structure contains a linked list of \c gc_entry structures. When + * a block of memory is allocated using the \c gc_malloc() function, the + * allocation is registered in the function's \c gc_arena argument. All + * the dynamically allocated memory registered in a \c gc_arena can be + * freed using the \c gc_free() function. + */ struct gc_arena { - struct gc_entry *list; + struct gc_entry *list; /**< First element of the linked list of + * \c gc_entry structures. */ }; + #define BPTR(buf) (buf_bptr(buf)) #define BEND(buf) (buf_bend(buf)) #define BLAST(buf) (buf_blast(buf)) @@ -272,16 +312,29 @@ has_digit (const unsigned char* src) */ bool buf_printf (struct buffer *buf, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 2, 3))) +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format (gnu_printf, 2, 3))) +#else + __attribute__ ((format (__printf__, 2, 3))) +#endif #endif ; /* + * puts append to a buffer with overflow check + */ +bool buf_puts (struct buffer *buf, const char *str); + +/* * Like snprintf but guarantees null termination for size > 0 */ -int openvpn_snprintf(char *str, size_t size, const char *format, ...) +bool openvpn_snprintf(char *str, size_t size, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format (gnu_printf, 3, 4))) +#else + __attribute__ ((format (__printf__, 3, 4))) +#endif #endif ; @@ -683,6 +736,11 @@ const char *np (const char *str); #define CC_REVERSE_QUOTE (1<<23) #define CC_AT (1<<24) #define CC_EQUAL (1<<25) +#define CC_LESS_THAN (1<<26) +#define CC_GREATER_THAN (1<<27) +#define CC_PIPE (1<<28) +#define CC_QUESTION_MARK (1<<29) +#define CC_ASTERISK (1<<30) /* macro classes */ #define CC_NAME (CC_ALNUM|CC_UNDERBAR) @@ -766,8 +824,6 @@ gc_reset (struct gc_arena *a) * Allocate memory to hold a structure */ -void out_of_memory (void); - #define ALLOC_OBJ(dptr, type) \ { \ check_malloc_return ((dptr) = (type *) malloc (sizeof (type))); \ @@ -818,7 +874,6 @@ void out_of_memory (void); static inline void check_malloc_return (void *p) { - void out_of_memory (void); if (!p) out_of_memory (); } diff --git a/circ_list.h b/src/openvpn/circ_list.h index 583701a..583701a 100644 --- a/circ_list.h +++ b/src/openvpn/circ_list.h diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c new file mode 100644 index 0000000..af75fc9 --- /dev/null +++ b/src/openvpn/clinat.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 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#if defined(ENABLE_CLIENT_NAT) + +#include "clinat.h" +#include "proto.h" +#include "socket.h" +#include "memdbg.h" + +static bool +add_entry(struct client_nat_option_list *dest, + const struct client_nat_entry *e) +{ + if (dest->n >= MAX_CLIENT_NAT) + { + msg (M_WARN, "WARNING: client-nat table overflow (max %d entries)", MAX_CLIENT_NAT); + return false; + } + else + { + dest->entries[dest->n++] = *e; + return true; + } +} + +void +print_client_nat_list(const struct client_nat_option_list *list, int msglevel) +{ + struct gc_arena gc = gc_new (); + int i; + + msg (msglevel, "*** CNAT list"); + if (list) + { + for (i = 0; i < list->n; ++i) + { + const struct client_nat_entry *e = &list->entries[i]; + msg (msglevel, " CNAT[%d] t=%d %s/%s/%s", + i, + e->type, + print_in_addr_t (e->network, IA_NET_ORDER, &gc), + print_in_addr_t (e->netmask, IA_NET_ORDER, &gc), + print_in_addr_t (e->foreign_network, IA_NET_ORDER, &gc)); + } + } + gc_free (&gc); +} + +struct client_nat_option_list * +new_client_nat_list (struct gc_arena *gc) +{ + struct client_nat_option_list *ret; + ALLOC_OBJ_CLEAR_GC (ret, struct client_nat_option_list, gc); + return ret; +} + +struct client_nat_option_list * +clone_client_nat_option_list (const struct client_nat_option_list *src, struct gc_arena *gc) +{ + struct client_nat_option_list *ret; + ALLOC_OBJ_GC (ret, struct client_nat_option_list, gc); + *ret = *src; + return ret; +} + +void +copy_client_nat_option_list (struct client_nat_option_list *dest, + const struct client_nat_option_list *src) +{ + int i; + for (i = 0; i < src->n; ++i) + { + if (!add_entry(dest, &src->entries[i])) + break; + } +} + +void +add_client_nat_to_option_list (struct client_nat_option_list *dest, + const char *type, + const char *network, + const char *netmask, + const char *foreign_network, + int msglevel) +{ + struct client_nat_entry e; + bool ok; + + if (!strcmp(type, "snat")) + e.type = CN_SNAT; + else if (!strcmp(type, "dnat")) + e.type = CN_DNAT; + else + { + msg(msglevel, "client-nat: type must be 'snat' or 'dnat'"); + return; + } + + e.network = getaddr(0, network, 0, &ok, NULL); + if (!ok) + { + msg(msglevel, "client-nat: bad network: %s", network); + return; + } + e.netmask = getaddr(0, netmask, 0, &ok, NULL); + if (!ok) + { + msg(msglevel, "client-nat: bad netmask: %s", netmask); + return; + } + e.foreign_network = getaddr(0, foreign_network, 0, &ok, NULL); + if (!ok) + { + msg(msglevel, "client-nat: bad foreign network: %s", foreign_network); + return; + } + + add_entry(dest, &e); +} + +#if 0 +static void +print_checksum (struct openvpn_iphdr *iph, const char *prefix) +{ + uint16_t *sptr; + unsigned int sum = 0; + int i = 0; + for (sptr = (uint16_t *)iph; (uint8_t *)sptr < (uint8_t *)iph + sizeof(struct openvpn_iphdr); sptr++) + { + i += 1; + sum += *sptr; + } + msg (M_INFO, "** CKSUM[%d] %s %08x", i, prefix, sum); +} +#endif + +static void +print_pkt (struct openvpn_iphdr *iph, const char *prefix, const int direction, const int msglevel) +{ + struct gc_arena gc = gc_new (); + + char *dirstr = "???"; + if (direction == CN_OUTGOING) + dirstr = "OUT"; + else if (direction == CN_INCOMING) + dirstr = "IN"; + + msg(msglevel, "** CNAT %s %s %s -> %s", + dirstr, + prefix, + print_in_addr_t (iph->saddr, IA_NET_ORDER, &gc), + print_in_addr_t (iph->daddr, IA_NET_ORDER, &gc)); + + gc_free (&gc); +} + +void +client_nat_transform (const struct client_nat_option_list *list, + struct buffer *ipbuf, + const int direction) +{ + struct ip_tcp_udp_hdr *h = (struct ip_tcp_udp_hdr *) BPTR (ipbuf); + int i; + uint32_t addr, *addr_ptr; + const uint32_t *from, *to; + int accumulate = 0; + unsigned int amask; + unsigned int alog = 0; + + if (check_debug_level (D_CLIENT_NAT)) + print_pkt (&h->ip, "BEFORE", direction, D_CLIENT_NAT); + + for (i = 0; i < list->n; ++i) + { + const struct client_nat_entry *e = &list->entries[i]; /* current NAT rule */ + if (e->type ^ direction) + { + addr = *(addr_ptr = &h->ip.daddr); + amask = 2; + } + else + { + addr = *(addr_ptr = &h->ip.saddr); + amask = 1; + } + if (direction) + { + from = &e->foreign_network; + to = &e->network; + } + else + { + from = &e->network; + to = &e->foreign_network; + } + + if (((addr & e->netmask) == *from) && !(amask & alog)) + { + /* pre-adjust IP checksum */ + ADD_CHECKSUM_32(accumulate, addr); + + /* do NAT transform */ + addr = (addr & ~e->netmask) | *to; + + /* post-adjust IP checksum */ + SUB_CHECKSUM_32(accumulate, addr); + + /* write the modified address to packet */ + *addr_ptr = addr; + + /* mark as modified */ + alog |= amask; + } + } + if (alog) + { + if (check_debug_level (D_CLIENT_NAT)) + print_pkt (&h->ip, "AFTER", direction, D_CLIENT_NAT); + + ADJUST_CHECKSUM(accumulate, h->ip.check); + + if (h->ip.protocol == OPENVPN_IPPROTO_TCP) + { + if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_tcphdr)) + { + ADJUST_CHECKSUM(accumulate, h->u.tcp.check); + } + } + else if (h->ip.protocol == OPENVPN_IPPROTO_UDP) + { + if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_udphdr)) + { + ADJUST_CHECKSUM(accumulate, h->u.udp.check); + } + } + } +} + +#endif diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h new file mode 100644 index 0000000..d55a727 --- /dev/null +++ b/src/openvpn/clinat.h @@ -0,0 +1,65 @@ +/* + * 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 + */ + +#if !defined(CLINAT_H) && defined(ENABLE_CLIENT_NAT) +#define CLINAT_H + +#include "buffer.h" + +#define MAX_CLIENT_NAT 64 + +#define CN_OUTGOING 0 +#define CN_INCOMING 1 + +struct client_nat_entry { +# define CN_SNAT 0 +# define CN_DNAT 1 + int type; + in_addr_t network; + in_addr_t netmask; + in_addr_t foreign_network; +}; + +struct client_nat_option_list { + int n; + struct client_nat_entry entries[MAX_CLIENT_NAT]; +}; + +struct client_nat_option_list *new_client_nat_list (struct gc_arena *gc); +struct client_nat_option_list *clone_client_nat_option_list (const struct client_nat_option_list *src, struct gc_arena *gc); +void copy_client_nat_option_list (struct client_nat_option_list *dest, const struct client_nat_option_list *src); +void print_client_nat_list(const struct client_nat_option_list *list, int msglevel); + +void add_client_nat_to_option_list (struct client_nat_option_list *dest, + const char *type, + const char *network, + const char *netmask, + const char *foreign_network, + int msglevel); + +void client_nat_transform (const struct client_nat_option_list *list, + struct buffer *ipbuf, + const int direction); + +#endif diff --git a/common.h b/src/openvpn/common.h index ff3a0d5..dd2c83f 100644 --- a/common.h +++ b/src/openvpn/common.h @@ -87,12 +87,15 @@ typedef unsigned long ptr_type; #define PUSH_BUNDLE_SIZE 1024 /* + * In how many seconds does client re-send PUSH_REQUEST if we haven't yet received a reply + */ +#define PUSH_REQUEST_INTERVAL 5 + +/* * A sort of pseudo-filename for data provided inline within * the configuration file. */ -#if ENABLE_INLINE_FILES #define INLINE_FILE_TAG "[[INLINE]]" -#endif /* * Script security warning diff --git a/src/openvpn/console.c b/src/openvpn/console.c new file mode 100644 index 0000000..afda8ca --- /dev/null +++ b/src/openvpn/console.c @@ -0,0 +1,238 @@ +/* + * 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-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 + */ + +#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 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 () +{ + struct stat a, b; + + /* We simply test whether the systemd cgroup hierarchy is + * mounted */ + + return (lstat("/sys/fs/cgroup", &a) == 0) + && (lstat("/sys/fs/cgroup/systemd", &b) == 0) + && (a.st_dev != b.st_dev); + +} + +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, "/bin/systemd-ask-password"); + argv_printf_cat (&argv, "%s", prompt); + + if ((std_out = openvpn_popen (&argv, NULL)) < 0) { + return false; + } + CLEAR (*input); + if (read (std_out, input, capacity) != 0) + { + chomp (input); + ret = true; + } + 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) +{ + 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 + +#if defined(WIN32) + return get_console_input_win32 (prompt, echo, input, capacity); +#elif defined(HAVE_GETPASS) + 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; +} diff --git a/memcmp.c b/src/openvpn/console.h index d921aac..268f3fe 100644 --- a/memcmp.c +++ b/src/openvpn/console.h @@ -1,6 +1,6 @@ /* * OpenVPN -- An application to securely tunnel IP networks - * over a single TCP/UDP port, with support for SSL/TLS-based + * over a single UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. @@ -22,22 +22,12 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "syshead.h" +#ifndef CONSOLE_H +#define CONSOLE_H -#include "memdbg.h" +#include "basic.h" -int -memcmp (const void *s1, const void *s2, size_t n) -{ - unsigned const char *p1 = s1, *p2 = s2; - int d; +bool +get_console_input (const char *prompt, const bool echo, char *input, const int capacity); - if (n) - while (n-- > 0) - { - d = *p1++ - *p2++; - if (d != 0) - return d; - } - return 0; -} +#endif diff --git a/crypto.c b/src/openvpn/crypto.c index 5cfc34a..ac2eecd 100644 --- a/crypto.c +++ b/src/openvpn/crypto.c @@ -6,6 +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> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -22,9 +23,15 @@ * 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_CRYPTO +#ifdef ENABLE_CRYPTO #include "crypto.h" #include "error.h" @@ -33,18 +40,6 @@ #include "memdbg.h" /* - * Check for key size creepage. - */ - -#if MAX_CIPHER_KEY_LENGTH < EVP_MAX_KEY_LENGTH -#warning Some OpenSSL EVP ciphers now support key lengths greater than MAX_CIPHER_KEY_LENGTH -- consider increasing MAX_CIPHER_KEY_LENGTH -#endif - -#if MAX_HMAC_KEY_LENGTH < EVP_MAX_MD_SIZE -#warning Some OpenSSL HMAC message digests now support key lengths greater than MAX_HMAC_KEY_LENGTH -- consider increasing MAX_HMAC_KEY_LENGTH -#endif - -/* * Encryption and Compression Routines. * * On entry, buf contains the input data and length. @@ -85,12 +80,12 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, /* Do Encrypt from buf -> work */ if (ctx->cipher) { - uint8_t iv_buf[EVP_MAX_IV_LENGTH]; - const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher); - const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher); + uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; + const int iv_size = cipher_ctx_iv_length (ctx->cipher); + const unsigned int mode = cipher_ctx_mode (ctx->cipher); int outlen; - if (mode == EVP_CIPH_CBC_MODE) + if (mode == OPENVPN_MODE_CBC) { CLEAR (iv_buf); @@ -106,7 +101,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } } - else if (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE) + else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB) { struct packet_id_net pin; struct buffer b; @@ -135,10 +130,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, format_hex (BPTR (buf), BLEN (buf), 80, &gc)); /* cipher_ctx was already initialized with key & keylen */ - ASSERT (EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_ENCRYPT)); + ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf)); /* Buffer overflow check */ - if (!buf_safe (&work, buf->len + EVP_CIPHER_CTX_block_size (ctx->cipher))) + 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 cbs=%d", buf->capacity, @@ -147,16 +142,16 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, work.capacity, work.offset, work.len, - EVP_CIPHER_CTX_block_size (ctx->cipher)); + cipher_ctx_block_size (ctx->cipher)); goto err; } /* Encrypt packet ID, payload */ - ASSERT (EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); + ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); work.len += outlen; /* Flush the encryption buffer */ - ASSERT (EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen)); + ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen)); work.len += outlen; ASSERT (outlen == iv_size); @@ -185,15 +180,13 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, /* HMAC the ciphertext (or plaintext if !cipher) */ if (ctx->hmac) { - int hmac_len; - uint8_t *output; + uint8_t *output = NULL; - HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL); - HMAC_Update (ctx->hmac, BPTR (&work), BLEN (&work)); - output = buf_prepend (&work, HMAC_size (ctx->hmac)); + 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_Final (ctx->hmac, output, (unsigned int *)&hmac_len); - ASSERT (hmac_len == HMAC_size (ctx->hmac)); + hmac_ctx_final (ctx->hmac, output); } *buf = work; @@ -202,8 +195,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, gc_free (&gc); return; - err: - ERR_clear_error (); +err: + crypto_clear_error(); buf->len = 0; gc_free (&gc); return; @@ -237,21 +230,18 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, { int hmac_len; uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ - int in_hmac_len; - HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL); + hmac_ctx_reset(ctx->hmac); /* Assume the length of the input HMAC */ - hmac_len = HMAC_size (ctx->hmac); + hmac_len = hmac_ctx_size (ctx->hmac); /* Authentication fails if insufficient data in packet for HMAC */ if (buf->len < hmac_len) CRYPT_ERROR ("missing authentication info"); - HMAC_Update (ctx->hmac, BPTR (buf) + hmac_len, - BLEN (buf) - hmac_len); - HMAC_Final (ctx->hmac, local_hmac, (unsigned int *)&in_hmac_len); - ASSERT (hmac_len == in_hmac_len); + hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len); + hmac_ctx_final (ctx->hmac, local_hmac); /* Compare locally computed HMAC with packet HMAC */ if (memcmp (local_hmac, BPTR (buf), hmac_len)) @@ -264,9 +254,9 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, if (ctx->cipher) { - const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher); - const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher); - uint8_t iv_buf[EVP_MAX_IV_LENGTH]; + const unsigned int mode = cipher_ctx_mode (ctx->cipher); + const int iv_size = cipher_ctx_iv_length (ctx->cipher); + uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; int outlen; /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */ @@ -290,7 +280,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, CRYPT_ERROR ("missing payload"); /* ctx->cipher was already initialized with key & keylen */ - if (!EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_DECRYPT)) + if (!cipher_ctx_reset (ctx->cipher, iv_buf)) CRYPT_ERROR ("cipher init failed"); /* Buffer overflow check (should never happen) */ @@ -298,12 +288,12 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, CRYPT_ERROR ("buffer overflow"); /* Decrypt packet ID, payload */ - if (!EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) + if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) CRYPT_ERROR ("cipher update failed"); work.len += outlen; /* Flush the decryption buffer */ - if (!EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen)) + if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen)) CRYPT_ERROR ("cipher final failed"); work.len += outlen; @@ -312,7 +302,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, /* Get packet ID from plaintext buffer or IV, depending on cipher mode */ { - if (mode == EVP_CIPH_CBC_MODE) + if (mode == OPENVPN_MODE_CBC) { if (opt->packet_id) { @@ -321,7 +311,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, have_pin = true; } } - else if (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE) + else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB) { struct buffer b; @@ -374,7 +364,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, return true; error_exit: - ERR_clear_error (); + crypto_clear_error(); buf->len = 0; gc_free (&gc); return false; @@ -394,103 +384,11 @@ crypto_adjust_frame_parameters(struct frame *frame, { frame_add_to_extra_frame (frame, (packet_id ? packet_id_size (packet_id_long_form) : 0) + - ((cipher_defined && use_iv) ? EVP_CIPHER_iv_length (kt->cipher) : 0) + - (cipher_defined ? EVP_CIPHER_block_size (kt->cipher) : 0) + /* worst case padding expansion */ + ((cipher_defined && use_iv) ? cipher_kt_iv_size (kt->cipher) : 0) + + (cipher_defined ? cipher_kt_block_size (kt->cipher) : 0) + /* worst case padding expansion */ kt->hmac_length); } -static const EVP_CIPHER * -get_cipher (const char *ciphername) -{ - const EVP_CIPHER *cipher = NULL; - ASSERT (ciphername); - cipher = EVP_get_cipherbyname (ciphername); - if ( !(cipher && cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher))))) - msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); - 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); - return cipher; -} - -static const EVP_MD * -get_md (const char *digest) -{ - const EVP_MD *md = NULL; - ASSERT (digest); - md = EVP_get_digestbyname (digest); - if (!md) - msg (M_SSLERR, "Message hash algorithm '%s' not found", digest); - if (EVP_MD_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, - EVP_MD_size (md), - MAX_HMAC_KEY_LENGTH); - return md; -} - -static void -init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - struct key *key, const struct key_type *kt, int enc, - const char *prefix) -{ - struct gc_arena gc = gc_new (); - - EVP_CIPHER_CTX_init (ctx); - if (!EVP_CipherInit_ov (ctx, cipher, NULL, NULL, enc)) - msg (M_SSLERR, "EVP cipher init #1"); -#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH - if (!EVP_CIPHER_CTX_set_key_length (ctx, kt->cipher_length)) - msg (M_SSLERR, "EVP set key size"); -#endif - if (!EVP_CipherInit_ov (ctx, NULL, key->cipher, NULL, enc)) - msg (M_SSLERR, "EVP cipher init #2"); - - msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key", - prefix, - OBJ_nid2sn (EVP_CIPHER_CTX_nid (ctx)), - EVP_CIPHER_CTX_key_length (ctx) * 8); - - /* make sure we used a big enough key */ - ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= kt->cipher_length); - - 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, - EVP_CIPHER_CTX_block_size (ctx), - EVP_CIPHER_CTX_iv_length (ctx)); - - gc_free (&gc); -} - -static void -init_hmac (HMAC_CTX *ctx, const EVP_MD *digest, - struct key *key, const struct key_type *kt, const char *prefix) -{ - struct gc_arena gc = gc_new (); - - HMAC_CTX_init (ctx); - HMAC_Init_ex (ctx, key->hmac, kt->hmac_length, digest, NULL); - msg (D_HANDSHAKE, - "%s: Using %d bit message hash '%s' for HMAC authentication", - prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (digest))); - - /* make sure we used a big enough key */ - ASSERT (HMAC_size (ctx) <= kt->hmac_length); - - dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix, - format_hex (key->hmac, kt->hmac_length, 0, &gc)); - dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d", - prefix, - EVP_MD_size (digest), - EVP_MD_block_size (digest)); - - gc_free (&gc); -} - /* * Build a struct key_type. */ @@ -503,17 +401,17 @@ init_key_type (struct key_type *kt, const char *ciphername, CLEAR (*kt); if (ciphername && ciphername_defined) { - kt->cipher = get_cipher (ciphername); - kt->cipher_length = EVP_CIPHER_key_length (kt->cipher); + kt->cipher = cipher_kt_get (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 */ { - const unsigned int mode = EVP_CIPHER_mode (kt->cipher); - if (!(mode == EVP_CIPH_CBC_MODE + const unsigned int mode = cipher_kt_mode (kt->cipher); + if (!(mode == OPENVPN_MODE_CBC #ifdef ALLOW_NON_CBC_CIPHERS - || (cfb_ofb_allowed && (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE)) + || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)) #endif )) #ifdef ENABLE_SMALL @@ -530,8 +428,8 @@ init_key_type (struct key_type *kt, const char *ciphername, } if (authname && authname_defined) { - kt->digest = get_md (authname); - kt->hmac_length = EVP_MD_size (kt->digest); + kt->digest = md_kt_get (authname); + kt->hmac_length = md_kt_size (kt->digest); } else { @@ -540,52 +438,52 @@ init_key_type (struct key_type *kt, const char *ciphername, } } -const char * -kt_cipher_name (const struct key_type *kt) -{ - if (kt->cipher) - return EVP_CIPHER_name (kt->cipher); - else - return "[null-cipher]"; -} - -const char * -kt_digest_name (const struct key_type *kt) -{ - if (kt->digest) - return EVP_MD_name (kt->digest); - else - return "[null-digest]"; -} - -int -kt_key_size (const struct key_type *kt) -{ - if (kt->cipher_length) - return kt->cipher_length * 8; - else if (kt->cipher) - return EVP_CIPHER_key_length (kt->cipher) * 8; - else - return 0; -} - /* given a key and key_type, build a key_ctx */ void init_key_ctx (struct key_ctx *ctx, struct key *key, const struct key_type *kt, int enc, const char *prefix) { + struct gc_arena gc = gc_new (); CLEAR (*ctx); if (kt->cipher && kt->cipher_length > 0) { - ALLOC_OBJ (ctx->cipher, EVP_CIPHER_CTX); - init_cipher (ctx->cipher, kt->cipher, key, kt, enc, prefix); + + ALLOC_OBJ(ctx->cipher, cipher_ctx_t); + cipher_ctx_init (ctx->cipher, key->cipher, kt->cipher_length, + kt->cipher, enc); + + msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key", + prefix, + 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)); } if (kt->digest && kt->hmac_length > 0) { - ALLOC_OBJ (ctx->hmac, HMAC_CTX); - init_hmac (ctx->hmac, kt->digest, key, kt, prefix); + ALLOC_OBJ(ctx->hmac, hmac_ctx_t); + hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest); + + msg (D_HANDSHAKE, + "%s: Using %d bit message hash '%s' for HMAC authentication", + prefix, md_kt_size(kt->digest) * 8, md_kt_name(kt->digest)); + + dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix, + format_hex (key->hmac, kt->hmac_length, 0, &gc)); + + dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d", + prefix, + md_kt_size(kt->digest), + hmac_ctx_size(ctx->hmac)); + } + gc_free (&gc); } void @@ -593,14 +491,14 @@ free_key_ctx (struct key_ctx *ctx) { if (ctx->cipher) { - EVP_CIPHER_CTX_cleanup (ctx->cipher); - free (ctx->cipher); + cipher_ctx_cleanup(ctx->cipher); + free(ctx->cipher); ctx->cipher = NULL; } if (ctx->hmac) { - HMAC_CTX_cleanup (ctx->hmac); - free (ctx->hmac); + hmac_ctx_cleanup(ctx->hmac); + free(ctx->hmac); ctx->hmac = NULL; } } @@ -612,83 +510,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx) free_key_ctx(&ctx->decrypt); } -/* - * Return number of DES cblocks for the current - * key type or 0 if not a DES cipher. - */ -static int -n_DES_cblocks (const struct key_type *kt) -{ - int ret = 0; - const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt->cipher)); - if (name) - { - if (!strncmp (name, "DES-", 4)) - { - ret = EVP_CIPHER_key_length (kt->cipher) / sizeof (DES_cblock); - } - else if (!strncmp (name, "DESX-", 5)) - { - ret = 1; - } - } - dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret); - return ret; -} - -static bool -check_key_DES (struct key *key, const struct key_type *kt, int ndc) -{ - int i; - struct buffer b; - - buf_set_read (&b, key->cipher, kt->cipher_length); - - for (i = 0; i < ndc; ++i) - { - DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock)); - if (!dc) - { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); - goto err; - } - if (DES_is_weak_key(dc)) - { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); - goto err; - } - if (!DES_check_key_parity (dc)) - { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); - goto err; - } - } - return true; - - err: - ERR_clear_error (); - return false; -} - -static void -fixup_key_DES (struct key *key, const struct key_type *kt, int ndc) -{ - int i; - struct buffer b; - - buf_set_read (&b, key->cipher, kt->cipher_length); - for (i = 0; i < ndc; ++i) - { - DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock)); - if (!dc) - { - msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material"); - ERR_clear_error (); - return; - } - DES_set_odd_parity (dc); - } -} static bool key_is_zero (struct key *key, const struct key_type *kt) @@ -719,9 +540,9 @@ check_key (struct key *key, const struct key_type *kt) * Check for weak or semi-weak DES keys. */ { - const int ndc = n_DES_cblocks (kt); + const int ndc = key_des_num_cblocks (kt->cipher); if (ndc) - return check_key_DES (key, kt, ndc); + return key_des_check (key->cipher, kt->cipher_length, ndc); else return true; } @@ -746,10 +567,10 @@ fixup_key (struct key *key, const struct key_type *kt) #ifdef ENABLE_DEBUG const struct key orig = *key; #endif - const int ndc = n_DES_cblocks (kt); + const int ndc = key_des_num_cblocks (kt->cipher); if (ndc) - fixup_key_DES (key, kt, ndc); + key_des_fixup (key->cipher, kt->cipher_length, ndc); #ifdef ENABLE_DEBUG if (check_debug_level (D_CRYPTO_DEBUG)) @@ -774,11 +595,11 @@ check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use bool cfb_ofb_mode (const struct key_type* kt) { - if (kt->cipher) { - const unsigned int mode = EVP_CIPHER_mode (kt->cipher); - return mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE; - } else - return false; + if (kt && kt->cipher) { + const unsigned int mode = cipher_kt_mode (kt->cipher); + return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB; + } + return false; } /* @@ -803,8 +624,8 @@ generate_key_random (struct key *key, const struct key_type *kt) if (kt->digest && kt->hmac_length > 0 && kt->hmac_length <= hmac_len) hmac_len = kt->hmac_length; } - if (!RAND_bytes (key->cipher, cipher_len) - || !RAND_bytes (key->hmac, hmac_len)) + if (!rand_bytes (key->cipher, cipher_len) + || !rand_bytes (key->hmac, hmac_len)) msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation"); dmsg (D_SHOW_KEY_SOURCE, "Cipher source entropy: %s", format_hex (key->cipher, cipher_len, 0, &gc)); @@ -870,7 +691,7 @@ test_crypto (const struct crypto_options *co, struct frame* frame) ASSERT (buf_init (&src, 0)); ASSERT (i <= src.capacity); src.len = i; - ASSERT (RAND_pseudo_bytes (BPTR (&src), BLEN (&src))); + ASSERT (rand_bytes (BPTR (&src), BLEN (&src))); /* copy source to input buf */ buf = work; @@ -897,7 +718,7 @@ test_crypto (const struct crypto_options *co, struct frame* frame) gc_free (&gc); } -#ifdef USE_SSL +#ifdef ENABLE_SSL void get_tls_handshake_key (const struct key_type *key_type, @@ -916,7 +737,6 @@ get_tls_handshake_key (const struct key_type *key_type, kt.cipher_length = 0; kt.cipher = NULL; -#if ENABLE_INLINE_FILES if (flags & GHK_INLINE) { /* key was specified inline, key text is in passphrase_file */ @@ -929,7 +749,6 @@ get_tls_handshake_key (const struct key_type *key_type, msg (M_FATAL, "INLINE tls-auth file lacks the requisite 2 keys"); } else -#endif { /* first try to parse as an OpenVPN static key file */ read_key_file (&key2, passphrase_file, 0); @@ -969,9 +788,9 @@ get_tls_handshake_key (const struct key_type *key_type, /* initialize hmac key in both directions */ - init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, DO_ENCRYPT, + 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, DO_DECRYPT, + init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT, "Incoming Control Channel Authentication"); CLEAR (key2); @@ -1036,7 +855,6 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags) * Key can be provided as a filename in 'file' or if RKF_INLINE * is set, the actual key data itself in ascii form. */ -#if ENABLE_INLINE_FILES if (flags & RKF_INLINE) /* 'file' is a string containing ascii representation of key */ { size = strlen (file) + 1; @@ -1044,10 +862,9 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags) error_filename = INLINE_FILE_TAG; } else /* 'file' is a filename which refers to a file containing the ascii key */ -#endif { in = alloc_buf_gc (2048, &gc); - fd = open (file, O_RDONLY); + fd = platform_open (file, O_RDONLY, 0); if (fd == -1) msg (M_ERR, "Cannot open file key file '%s'", file); size = read (fd, in.data, in.capacity); @@ -1158,9 +975,7 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags) } /* zero file read buffer if not an inline file */ -#if ENABLE_INLINE_FILES if (!(flags & RKF_INLINE)) -#endif buf_clear (&in); if (key2->n) @@ -1191,24 +1006,24 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags) int read_passphrase_hash (const char *passphrase_file, - const EVP_MD *digest, + const md_kt_t *digest, uint8_t *output, int len) { unsigned int outlen = 0; - EVP_MD_CTX md; + md_ctx_t md; - ASSERT (len >= EVP_MD_size (digest)); + ASSERT (len >= md_kt_size(digest)); memset (output, 0, len); - EVP_DigestInit (&md, digest); + md_ctx_init(&md, digest); /* read passphrase file */ { const int min_passphrase_size = 8; uint8_t buf[64]; int total_size = 0; - int fd = open (passphrase_file, O_RDONLY); + int fd = platform_open (passphrase_file, O_RDONLY, 0); if (fd == -1) msg (M_ERR, "Cannot open passphrase file: '%s'", passphrase_file); @@ -1221,7 +1036,7 @@ read_passphrase_hash (const char *passphrase_file, if (size == -1) msg (M_ERR, "Read error on passphrase file: '%s'", passphrase_file); - EVP_DigestUpdate (&md, buf, size); + md_ctx_update(&md, buf, size); total_size += size; } close (fd); @@ -1233,10 +1048,9 @@ read_passphrase_hash (const char *passphrase_file, "Passphrase file '%s' is too small (must have at least %d characters)", passphrase_file, min_passphrase_size); } - - EVP_DigestFinal (&md, output, &outlen); - EVP_MD_CTX_cleanup (&md); - return outlen; + md_ctx_final(&md, output); + md_ctx_cleanup(&md); + return md_kt_size(digest); } /* @@ -1259,7 +1073,7 @@ write_key_file (const int nkeys, const char *filename) const int bytes_per_line = 16; /* open key file */ - fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); + fd = platform_open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (fd == -1) msg (M_ERR, "Cannot open shared secret file '%s' for write", filename); @@ -1462,225 +1276,50 @@ key_len_err: return 0; } -void -show_available_ciphers () -{ - int nid; - - -#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 - - for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ - { - const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); - if (cipher && cipher_ok (OBJ_nid2sn (nid))) - { - const unsigned int mode = EVP_CIPHER_mode (cipher); - if (mode == EVP_CIPH_CBC_MODE -#ifdef ALLOW_NON_CBC_CIPHERS - || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE -#endif - ) - printf ("%s %d bit default key (%s)\n", - OBJ_nid2sn (nid), - EVP_CIPHER_key_length (cipher) * 8, - ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? - "variable" : "fixed")); - } - } - printf ("\n"); -} - -void -show_available_digests () -{ - int nid; - -#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 - - for (nid = 0; nid < 10000; ++nid) - { - const EVP_MD *digest = EVP_get_digestbynid (nid); - if (digest) - { - printf ("%s %d bit digest size\n", - OBJ_nid2sn (nid), EVP_MD_size (digest) * 8); - } - } - printf ("\n"); -} - -void -show_available_engines () -{ -#if CRYPTO_ENGINE - ENGINE *e; - - printf ("OpenSSL Crypto Engines\n\n"); - - ENGINE_load_builtin_engines (); - - e = ENGINE_get_first (); - while (e) - { - printf ("%s [%s]\n", - ENGINE_get_name (e), - ENGINE_get_id (e)); - e = ENGINE_get_next (e); - } - ENGINE_cleanup (); -#else - printf ("Sorry, OpenSSL hardware crypto engine functionality is not available.\n"); -#endif -} - /* - * Enable crypto acceleration, if available + * 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. */ -static bool engine_initialized = false; /* GLOBAL */ - -#if CRYPTO_ENGINE +static uint8_t *nonce_data = NULL; /* GLOBAL */ +static const md_kt_t *nonce_md = NULL; /* GLOBAL */ +static int nonce_secret_len = 0; /* GLOBAL */ -static ENGINE *engine_persist = NULL; /* GLOBAL */ - -/* Try to load an engine in a shareable library */ -static ENGINE * -try_load_engine (const char *engine) -{ - ENGINE *e = ENGINE_by_id ("dynamic"); - if (e) - { - if (!ENGINE_ctrl_cmd_string (e, "SO_PATH", engine, 0) - || !ENGINE_ctrl_cmd_string (e, "LOAD", NULL, 0)) - { - ENGINE_free (e); - e = NULL; - } - } - return e; -} - -static ENGINE * -setup_engine (const char *engine) -{ - ENGINE *e = NULL; - - ENGINE_load_builtin_engines (); - - if (engine) - { - if (strcmp (engine, "auto") == 0) - { - msg (M_INFO, "Initializing OpenSSL auto engine support"); - ENGINE_register_all_complete (); - return NULL; - } - if ((e = ENGINE_by_id (engine)) == NULL - && (e = try_load_engine (engine)) == NULL) - { - msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine); - } - - if (!ENGINE_set_default (e, ENGINE_METHOD_ALL)) - { - msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'", - engine); - } - - msg (M_INFO, "Initializing OpenSSL support for engine '%s'", - ENGINE_get_id (e)); - } - return e; -} -#endif - -void -init_crypto_lib_engine (const char *engine_name) +/* Reset the nonce value, also done periodically to refresh entropy */ +static void +prng_reset_nonce () { - if (!engine_initialized) - { -#if CRYPTO_ENGINE - ASSERT (engine_name); - ASSERT (!engine_persist); - engine_persist = setup_engine (engine_name); + const int size = md_kt_size (nonce_md) + nonce_secret_len; +#if 1 /* Must be 1 for real usage */ + if (!rand_bytes (nonce_data, size)) + msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for PRNG"); #else - msg (M_WARN, "Note: OpenSSL hardware crypto engine functionality is not available"); -#endif - engine_initialized = true; - } -} - -/* - * This routine should have additional OpenSSL crypto library initialisations - * used by both crypto and ssl components of OpenVPN. - */ -void init_crypto_lib () -{ -} - -void uninit_crypto_lib () -{ -#if CRYPTO_ENGINE - if (engine_initialized) + /* Only for testing -- will cause a predictable PRNG sequence */ { - ENGINE_cleanup (); - engine_persist = NULL; - engine_initialized = false; + int i; + for (i = 0; i < size; ++i) + nonce_data[i] = (uint8_t) i; } #endif - prng_uninit (); } -/* - * 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. - */ - -static uint8_t *nonce_data; /* GLOBAL */ -static const EVP_MD *nonce_md = NULL; /* GLOBAL */ -static int nonce_secret_len; /* GLOBAL */ - void prng_init (const char *md_name, const int nonce_secret_len_parm) { prng_uninit (); - nonce_md = md_name ? get_md (md_name) : NULL; + nonce_md = md_name ? md_kt_get (md_name) : NULL; if (nonce_md) { ASSERT (nonce_secret_len_parm >= NONCE_SECRET_LEN_MIN && nonce_secret_len_parm <= NONCE_SECRET_LEN_MAX); nonce_secret_len = nonce_secret_len_parm; { - const int size = EVP_MD_size (nonce_md) + nonce_secret_len; - dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", EVP_MD_name (nonce_md), size); + const int size = md_kt_size(nonce_md) + nonce_secret_len; + dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", md_kt_name(nonce_md), size); nonce_data = (uint8_t*) malloc (size); check_malloc_return (nonce_data); -#if 1 /* Must be 1 for real usage */ - if (!RAND_bytes (nonce_data, size)) - msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for PRNG"); -#else - /* Only for testing -- will cause a predictable PRNG sequence */ - { - int i; - for (i = 0; i < size; ++i) - nonce_data[i] = (uint8_t) i; - } -#endif + prng_reset_nonce(); } } } @@ -1697,26 +1336,30 @@ prng_uninit (void) void prng_bytes (uint8_t *output, int len) { + static size_t processed = 0; + if (nonce_md) { - EVP_MD_CTX ctx; - const int md_size = EVP_MD_size (nonce_md); + const int md_size = md_kt_size (nonce_md); while (len > 0) { unsigned int outlen = 0; const int blen = min_int (len, md_size); - EVP_DigestInit (&ctx, nonce_md); - EVP_DigestUpdate (&ctx, nonce_data, md_size + nonce_secret_len); - EVP_DigestFinal (&ctx, nonce_data, &outlen); - ASSERT (outlen == md_size); - EVP_MD_CTX_cleanup (&ctx); + md_full(nonce_md, nonce_data, md_size + nonce_secret_len, nonce_data); memcpy (output, nonce_data, blen); output += blen; len -= blen; + + /* Ensure that random data is reset regularly */ + processed += blen; + if(processed > PRNG_NONCE_RESET_BYTES) { + prng_reset_nonce(); + processed = 0; + } } } else - RAND_bytes (output, len); + rand_bytes (output, len); } /* an analogue to the random() function, but use prng_bytes */ @@ -1730,90 +1373,57 @@ get_random() return l; } -const char * -md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc) -{ - uint8_t digest[MD5_DIGEST_LENGTH]; - MD5 (buf, len, digest); - return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc); -} - -/* - * OpenSSL memory debugging. If dmalloc debugging is enabled, tell - * OpenSSL to use our private malloc/realloc/free functions so that - * we can dispatch them to dmalloc. - */ - -#ifdef DMALLOC - -static void * -crypto_malloc (size_t size, const char *file, int line) -{ - return dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0); -} - -static void * -crypto_realloc (void *ptr, size_t size, const char *file, int line) -{ - return dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0); -} - -static void -crypto_free (void *ptr) -{ - dmalloc_free (__FILE__, __LINE__, ptr, DMALLOC_FUNC_FREE); -} - -void -openssl_dmalloc_init (void) -{ - CRYPTO_set_mem_ex_functions (crypto_malloc, - crypto_realloc, - crypto_free); -} - -#endif /* DMALLOC */ - -#ifndef USE_SSL +#ifndef ENABLE_SSL void init_ssl_lib (void) { - ERR_load_crypto_strings (); - OpenSSL_add_all_algorithms (); - init_crypto_lib (); + crypto_init_lib (); } void free_ssl_lib (void) { - uninit_crypto_lib (); - EVP_cleanup (); - ERR_free_strings (); + crypto_uninit_lib (); + prng_uninit(); } -#endif /* USE_SSL */ +#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) { - MD5_Init (&s->ctx); + const md_kt_t *md5_kt = md_kt_get("MD5"); + + md_ctx_init(&s->ctx, md5_kt); } void md5_state_update (struct md5_state *s, void *data, size_t len) { - MD5_Update (&s->ctx, data, len); + md_ctx_update(&s->ctx, data, len); } void md5_state_final (struct md5_state *s, struct md5_digest *out) { - MD5_Final (out->digest, &s->ctx); + md_ctx_final(&s->ctx, out->digest); + md_ctx_cleanup(&s->ctx); } void @@ -1838,4 +1448,4 @@ md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2) return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0; } -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h new file mode 100644 index 0000000..3b4b88e --- /dev/null +++ b/src/openvpn/crypto.h @@ -0,0 +1,398 @@ +/* + * 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 Module + */ + +#ifndef CRYPTO_H +#define CRYPTO_H + +#ifdef ENABLE_CRYPTO + +#define ALLOW_NON_CBC_CIPHERS + +#include "crypto_backend.h" +#include "basic.h" +#include "buffer.h" +#include "packet_id.h" +#include "mtu.h" + +/* + * Defines a key type and key length for both cipher and HMAC. + */ +struct key_type +{ + uint8_t cipher_length; /**< Cipher length, in bytes */ + uint8_t hmac_length; /**< HMAC length, in bytes */ + const cipher_kt_t *cipher; /**< Cipher static parameters */ + const md_kt_t *digest; /**< Message digest static parameters */ +}; + +/** + * Container for unidirectional cipher and HMAC %key material. + * @ingroup control_processor + */ +struct key +{ + uint8_t cipher[MAX_CIPHER_KEY_LENGTH]; + /**< %Key material for cipher operations. */ + uint8_t hmac[MAX_HMAC_KEY_LENGTH]; + /**< %Key material for HMAC operations. */ +}; + + +/** + * Container for one set of OpenSSL 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. */ +}; + +#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */ +#define KEY_DIRECTION_NORMAL 1 /* encrypt with keys[0], decrypt with keys[1] */ +#define KEY_DIRECTION_INVERSE 2 /* encrypt with keys[1], decrypt with keys[0] */ + +/** + * Container for bidirectional cipher and HMAC %key material. + * @ingroup control_processor + */ +struct key2 +{ + int n; /**< The number of \c key objects stored + * in the \c key2.keys array. */ + struct key keys[2]; /**< Two unidirectional sets of %key + * material. */ +}; + +/** + * %Key ordering of the \c key2.keys array. + * @ingroup control_processor + * + * This structure takes care of correct ordering when using unidirectional + * or bidirectional %key material, and allows the same shared secret %key + * file to be loaded in the same way by client and server by having one of + * the hosts use an reversed ordering. + */ +struct key_direction_state +{ + int out_key; /**< Index into the \c key2.keys array for + * the sending direction. */ + int in_key; /**< Index into the \c key2.keys array for + * the receiving direction. */ + int need_keys; /**< The number of key objects necessary + * to support both sending and + * receiving. + * + * This will be 1 if the same keys are + * used in both directions, or 2 if + * there are two sets of unidirectional + * keys. */ +}; + +/** + * Container for two sets of OpenSSL cipher and/or HMAC contexts for both + * sending and receiving directions. + * @ingroup control_processor + */ +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. */ +}; + +/** + * Security parameter state for processing data channel packets. + * @ingroup data_crypto + */ +struct crypto_options +{ + 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 + * sending and receiving directions. */ + struct packet_id_persist *pid_persist; + /**< Persistent packet ID state for + * keeping state between successive + * OpenVPN process startups. */ + +# define CO_PACKET_ID_LONG_FORM (1<<0) + /**< Bit-flag indicating whether to use + * OpenVPN's long packet ID format. */ +# define CO_USE_IV (1<<1) + /**< Bit-flag indicating whether to + * generate a pseudo-random IV for each + * packet being encrypted. */ +# define CO_IGNORE_PACKET_ID (1<<2) + /**< Bit-flag indicating whether to ignore + * the packet ID of a received packet. + * This flag is used during processing + * of the first packet received from a + * client. */ +# define CO_MUTE_REPLAY_WARNINGS (1<<3) + /**< Bit-flag indicating not to display + * replay warnings. */ + unsigned int flags; /**< Bit-flags determining behavior of + * security operation functions. */ +}; + +#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); + +int write_key_file (const int nkeys, const char *filename); + +int read_passphrase_hash (const char *passphrase_file, + const md_kt_t *digest, + uint8_t *output, + int len); + +void generate_key_random (struct key *key, const struct key_type *kt); + +void check_replay_iv_consistency(const struct key_type *kt, bool packet_id, bool use_iv); + +bool check_key (struct key *key, const struct key_type *kt); + +void fixup_key (struct key *key, const struct key_type *kt); + +bool write_key (const struct key *key, const struct key_type *kt, + struct buffer *buf); + +int read_key (struct key *key, const struct key_type *kt, struct buffer *buf); + +bool cfb_ofb_mode (const struct key_type* kt); + +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); + +/* + * Key context functions + */ + +void init_key_ctx (struct key_ctx *ctx, struct key *key, + const struct key_type *kt, int enc, + const char *prefix); + +void free_key_ctx (struct key_ctx *ctx); + +void free_key_ctx_bi (struct key_ctx_bi *ctx); + + +/**************************************************************************/ +/** @name Functions for performing security operations on data channel packets + * @{ */ + +/** + * Encrypt and HMAC sign a packet so that it can be sent as a data channel + * VPN tunnel packet to a remote OpenVPN peer. + * @ingroup data_crypto + * + * This function handles encryption and HMAC signing of a data channel + * packet before it is sent to its remote OpenVPN peer. It receives the + * necessary security parameters in the \a opt argument, which should have + * been set to the correct values by the \c tls_pre_encrypt() function. + * + * This function calls the \c EVP_Cipher* and \c HMAC_* functions of the + * OpenSSL library to perform the actual security operations. + * + * If an error occurs during processing, then the \a buf %buffer is set to + * empty. + * + * @param buf - The %buffer containing the packet on which to + * perform security operations. + * @param work - A 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); + + +/** + * HMAC verify and decrypt a data channel packet received from a remote + * OpenVPN peer. + * @ingroup data_crypto + * + * This function handles authenticating and decrypting a data channel + * packet received from a remote OpenVPN peer. It receives the necessary + * security parameters in the \a opt argument, which should have been set + * to the correct values by the \c tls_pre_decrypt() function. + * + * This function calls the \c EVP_Cipher* and \c HMAC_* functions of the + * OpenSSL library to perform the actual security operations. + * + * If an error occurs during processing, then the \a buf %buffer is set to + * empty. + * + * @param buf - The %buffer containing the packet received from a + * remote OpenVPN peer on which to perform security + * operations. + * @param work - A working %buffer. + * @param opt - The security parameter state for this VPN tunnel. + * @param frame - The packet geometry parameters for this VPN + * tunnel. + * + * @return + * @li True, if the packet was authenticated and decrypted successfully. + * @li False, if an error occurred. \n On return, the \a buf argument will + * point to the resulting %buffer. This %buffer will either contain + * the plaintext packet ready for further processing, or be empty if + * an error occurred. + */ +bool openvpn_decrypt (struct buffer *buf, struct buffer work, + const struct crypto_options *opt, + const struct frame* frame); + +/** @} name Functions for performing security operations on data channel packets */ + +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); + + +/* Minimum length of the nonce used by the PRNG */ +#define NONCE_SECRET_LEN_MIN 16 + +/* Maximum length of the nonce used by the PRNG */ +#define NONCE_SECRET_LEN_MAX 64 + +/** Number of bytes of random to allow before resetting the nonce */ +#define PRNG_NONCE_RESET_BYTES 1024 + +/** + * Pseudo-random number generator initialisation. + * (see \c prng_rand_bytes()) + * + * @param md_name Name of the message digest to use + * @param nonce_secret_len_param Length of the nonce to use + */ +void prng_init (const char *md_name, const int nonce_secret_len_parm); + +/* + * Message digest-based pseudo random number generator. + * + * If the PRNG was initialised with a certain message digest, uses the digest + * to calculate the next random number, and prevent depletion of the entropy + * pool. + * + * This PRNG is aimed at IV generation and similar miscellaneous tasks. Use + * \c rand_bytes() for higher-assurance functionality. + * + * Retrieves len bytes of pseudo random data, and places it in output. + * + * @param output Output buffer + * @param len Length of the output buffer + */ +void prng_bytes (uint8_t *output, int len); + +void prng_uninit (); + +void test_crypto (const struct crypto_options *co, struct frame* f); + + +/* key direction functions */ + +void key_direction_state_init (struct key_direction_state *kds, int key_direction); + +void verify_fix_key2 (struct key2 *key2, const struct key_type *kt, const char *shared_secret_file); + +void must_have_n_keys (const char *filename, const char *option, const struct key2 *key2, int n); + +int ascii2keydirection (int msglevel, const char *str); + +const char *keydirection2ascii (int kd, bool remote); + +/* print keys */ +void key2_print (const struct key2* k, + const struct key_type *kt, + 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 */ + +/* + * md5 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 + */ + +static inline bool +key_ctx_bi_defined(const struct key_ctx_bi* key) +{ + return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac; +} + + +#endif /* ENABLE_CRYPTO */ +#endif /* CRYPTO_H */ diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h new file mode 100644 index 0000000..1eac611 --- /dev/null +++ b/src/openvpn/crypto_backend.h @@ -0,0 +1,488 @@ +/* + * 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 SSL library-specific backend interface + */ + +#ifndef CRYPTO_BACKEND_H_ +#define CRYPTO_BACKEND_H_ + +#ifdef ENABLE_CRYPTO_OPENSSL +#include "crypto_openssl.h" +#endif +#ifdef ENABLE_CRYPTO_POLARSSL +#include "crypto_polarssl.h" +#endif +#include "basic.h" + + +/* + * This routine should have additional OpenSSL crypto library initialisations + * used by both crypto and ssl components of OpenVPN. + */ +void crypto_init_lib (void); + +void crypto_uninit_lib (void); + +void crypto_clear_error (void); + +/* + * Initialise the given named crypto engine. + */ +void crypto_init_lib_engine (const char *engine_name); + +#ifdef DMALLOC +/* + * OpenSSL memory debugging. If dmalloc debugging is enabled, tell + * OpenSSL to use our private malloc/realloc/free functions so that + * we can dispatch them to dmalloc. + */ +void crypto_init_dmalloc (void); +#endif /* DMALLOC */ + +void show_available_ciphers (void); + +void show_available_digests (void); + +void show_available_engines (void); + +/* + * + * 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. + * + */ + +/** + * Wrapper for secure random number generator. Retrieves len bytes of random + * data, and places it in output. + * + * @param output Output buffer + * @param len Length of the output buffer, in bytes + * + * @return \c 1 on success, \c 0 on failure + */ +int rand_bytes (uint8_t *output, int len); + +/* + * + * Key functions, allow manipulation of keys. + * + */ + + +/** + * Return number of DES cblocks (1 cblock = length of a single-DES key) for the + * current key type or 0 if not a DES cipher. + * + * @param kt Type of key + * + * @return Number of DES cblocks that the key consists of, or 0. + */ +int key_des_num_cblocks (const cipher_kt_t *kt); + +/* + * Check the given DES key. Checks the given key's length, weakness and parity. + * + * @param key Key to check + * @param key_len Length of the key, in bytes + * @param ndc Number of DES cblocks that the key is made up of. + * + * @return \c true if the key is valid, \c false otherwise. + */ +bool key_des_check (uint8_t *key, int key_len, int ndc); + +/* + * Fix the given DES key, setting its parity to odd. + * + * @param key Key to check + * @param key_len Length of the key, in bytes + * @param ndc Number of DES cblocks that the key is made up of. + */ +void key_des_fixup (uint8_t *key, int key_len, int ndc); + +/** + * Encrypt the given block, using DES ECB mode + * + * @param key DES key to use. + * @param src Buffer containing the 8-byte source. + * @param dst Buffer containing the 8-byte destination + */ +void cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], + unsigned char src[DES_KEY_LENGTH], + unsigned char dst[DES_KEY_LENGTH]); + +/* + * + * Generic cipher key type functions + * + */ +/* + * Max size in bytes of any cipher key that might conceivably be used. + * + * This value is checked at compile time in crypto.c to make sure + * it is always at least EVP_MAX_KEY_LENGTH. + * + * We define our own value, since this parameter + * is used to control the size of static key files. + * If the OpenSSL library increases EVP_MAX_KEY_LENGTH, + * we don't want our key files to be suddenly rendered + * unusable. + */ +#define MAX_CIPHER_KEY_LENGTH 64 + +/** + * Return cipher parameters, based on the given cipher name. The + * contents of these parameters are library-specific, and can be used to + * initialise encryption/decryption. + * + * @param ciphername Name of the cipher to retrieve parameters for (e.g. + * \c AES-128-CBC). + * + * @return A statically allocated structure containing parameters + * for the given cipher. + */ +const cipher_kt_t * cipher_kt_get (const char *ciphername); + +/** + * Retrieve a string describing the cipher (e.g. \c AES-128-CBC). + * + * @param cipher_kt Static cipher parameters + * + * @return a statically allocated string describing the cipher. + */ +const char * cipher_kt_name (const cipher_kt_t *cipher_kt); + +/** + * Returns the size of keys used by the cipher, in bytes. If the cipher has a + * variable key size, return the default key size. + * + * @param cipher_kt Static cipher parameters + * + * @return (Default) size of keys used by the cipher, in bytes. + */ +int cipher_kt_key_size (const cipher_kt_t *cipher_kt); + +/** + * Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is + * used. + * + * @param cipher_kt Static cipher parameters + * + * @return Size of the IV, in bytes, or 0 if the cipher does not + * use an IV. + */ +int cipher_kt_iv_size (const cipher_kt_t *cipher_kt); + +/** + * Returns the block size of the cipher, in bytes. + * + * @param cipher_kt Static cipher parameters + * + * @return Block size, in bytes. + */ +int cipher_kt_block_size (const cipher_kt_t *cipher_kt); + +/** + * Returns the mode that the cipher runs in. + * + * @param cipher_kt Static cipher parameters + * + * @return Cipher mode, either \c OPENVPN_MODE_CBC, \c + * OPENVPN_MODE_OFB or \c OPENVPN_MODE_CFB + */ +int cipher_kt_mode (const cipher_kt_t *cipher_kt); + + +/** + * + * Generic cipher functions + * + */ + +/** + * Initialise a cipher context, based on the given key and key type. + * + * @param ctx Cipher context. May not be NULL + * @param key Buffer containing the key to use + * @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). + */ +void cipher_ctx_init (cipher_ctx_t *ctx, uint8_t *key, int key_len, + const cipher_kt_t *kt, int enc); + +/** + * Cleanup the specified context. + * + * @param ctx Cipher context to cleanup. + */ +void cipher_ctx_cleanup (cipher_ctx_t *ctx); + +/** + * Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is + * used. + * + * @param ctx The cipher's context + * + * @return Size of the IV, in bytes, or \c 0 if the cipher does not + * use an IV or ctx was NULL. + */ +int cipher_ctx_iv_length (const cipher_ctx_t *ctx); + +/** + * Returns the block size of the cipher, in bytes. + * + * @param ctx The cipher's context + * + * @return Block size, in bytes, or 0 if ctx was NULL. + */ +int cipher_ctx_block_size (const cipher_ctx_t *ctx); + +/** + * Returns the mode that the cipher runs in. + * + * @param ctx Cipher's context. May not be NULL. + * + * @return Cipher mode, either \c OPENVPN_MODE_CBC, \c + * OPENVPN_MODE_OFB or \c OPENVPN_MODE_CFB + */ +int cipher_ctx_mode (const cipher_ctx_t *ctx); + +/** + * Resets the given cipher context, setting the IV to the specified value. + * Preserves the associated key information. + * + * @param ctx Cipher's context. May not be NULL. + * @param iv_buf The IV to use. + * + * @return \c 0 on failure, \c 1 on success. + */ +int cipher_ctx_reset (cipher_ctx_t *ctx, uint8_t *iv_buf); + +/** + * Updates the given cipher context, encrypting data in the source buffer, and + * placing any complete blocks in the destination buffer. + * + * Note that if a complete block cannot be written, data is cached in the + * context, and emitted at a later call to \c cipher_ctx_update, or by a call + * to \c cipher_ctx_final(). This implies that dst should have enough room for + * src_len + \c cipher_ctx_block_size() - 1. + * + * @param ctx Cipher's context. May not be NULL. + * @param dst Destination buffer + * @param dst_len Length of the destination buffer, in bytes + * @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 (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, + uint8_t *src, int src_len); + +/** + * Pads the final cipher block using PKCS padding, and output to the destination + * buffer. + * + * @param ctx Cipher's context. May not be NULL. + * @param dst Destination buffer + * @param dst_len Length of the destination buffer, in bytes + * + * @return \c 0 on failure, \c 1 on success. + */ +int cipher_ctx_final (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len); + +/* + * + * Generic message digest information functions + * + */ + +/* + * Max size in bytes of any HMAC key that might conceivably be used. + * + * This value is checked at compile time in crypto.c to make sure + * it is always at least EVP_MAX_MD_SIZE. We define our own value + * for the same reason as above. + */ +#define MAX_HMAC_KEY_LENGTH 64 + +/** + * Return message digest parameters, based on the given digest name. The + * contents of these parameters are library-specific, and can be used to + * initialise HMAC or message digest operations. + * + * @param digest Name of the digest to retrieve parameters for (e.g. + * \c MD5). + * + * @return A statically allocated structure containing parameters + * for the given message digest. + */ +const md_kt_t * md_kt_get (const char *digest); + +/** + * Retrieve a string describing the digest digest (e.g. \c SHA1). + * + * @param kt Static message digest parameters + * + * @return Statically allocated string describing the message + * digest. + */ +const char * md_kt_name (const md_kt_t *kt); + +/** + * Returns the size of the message digest, in bytes. + * + * @param kt Static message digest parameters + * + * @return Message digest size, in bytes, or 0 if ctx was NULL. + */ +int md_kt_size (const md_kt_t *kt); + + +/* + * + * Generic message digest functions + * + */ + +/* + * Calculates the message digest for the given buffer. + * + * @param kt Static message digest parameters + * @param src Buffer to digest. May not be NULL. + * @param src_len The length of the incoming buffer. + * @param dst Buffer to write the message digest to. May not be NULL. + * + * @return \c 1 on success, \c 0 on failure + */ +int md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst); + +/* + * Initialises the given message digest context. + * + * @param ctx Message digest context + * @param kt Static message digest parameters + */ +void md_ctx_init (md_ctx_t *ctx, const md_kt_t *kt); + +/* + * Free the given message digest context. + * + * @param ctx Message digest context + */ +void md_ctx_cleanup(md_ctx_t *ctx); + +/* + * Returns the size of the message digest output by the given context + * + * @param ctx Message digest context. + * + * @return Size of the message digest, or \0 if ctx is NULL. + */ +int md_ctx_size (const md_ctx_t *ctx); + +/* + * Process the given data for use in the message digest. + * + * @param ctx Message digest context. May not be NULL. + * @param src Buffer to digest. May not be NULL. + * @param src_len The length of the incoming buffer. + */ +void md_ctx_update (md_ctx_t *ctx, const uint8_t *src, int src_len); + +/* + * Output the message digest to the given buffer. + * + * @param ctx Message digest context. May not be NULL. + * @param dst Buffer to write the message digest to. May not be NULL. + */ +void md_ctx_final (md_ctx_t *ctx, uint8_t *dst); + + +/* + * + * Generic HMAC functions + * + */ + +/* + * Initialises the given HMAC context, using the given digest + * and key. + * + * @param ctx HMAC context to intialise + * @param key The key to use for the HMAC + * @param key_len The key length to use + * @param kt Static message digest parameters + * + */ +void hmac_ctx_init (hmac_ctx_t *ctx, const uint8_t *key, int key_length, + const md_kt_t *kt); + +/* + * Free the given HMAC context. + * + * @param ctx HMAC context + */ +void hmac_ctx_cleanup(hmac_ctx_t *ctx); + +/* + * Returns the size of the HMAC output by the given HMAC Context + * + * @param ctx HMAC context. + * + * @return Size of the HMAC, or \0 if ctx is NULL. + */ +int hmac_ctx_size (const hmac_ctx_t *ctx); + +/* + * Resets the given HMAC context, preserving the associated key information + * + * @param ctx HMAC context. May not be NULL. + */ +void hmac_ctx_reset (hmac_ctx_t *ctx); + +/* + * Process the given data for use in the HMAC. + * + * @param ctx HMAC context. May not be NULL. + * @param src The buffer to HMAC. May not be NULL. + * @param src_len The length of the incoming buffer. + */ +void hmac_ctx_update (hmac_ctx_t *ctx, const uint8_t *src, int src_len); + +/* + * Output the HMAC to the given buffer. + * + * @param ctx HMAC context. May not be NULL. + * @param dst buffer to write the HMAC to. May not be NULL. + */ +void hmac_ctx_final (hmac_ctx_t *ctx, uint8_t *dst); + +#endif /* CRYPTO_BACKEND_H_ */ diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c new file mode 100644 index 0000000..5342502 --- /dev/null +++ b/src/openvpn/crypto_openssl.c @@ -0,0 +1,753 @@ +/* + * 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 OpenSSL-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_OPENSSL) + +#include "basic.h" +#include "buffer.h" +#include "integer.h" +#include "crypto_backend.h" +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/des.h> + +/* + * Check for key size creepage. + */ + +#if MAX_CIPHER_KEY_LENGTH < EVP_MAX_KEY_LENGTH +#warning Some OpenSSL EVP ciphers now support key lengths greater than MAX_CIPHER_KEY_LENGTH -- consider increasing MAX_CIPHER_KEY_LENGTH +#endif + +#if MAX_HMAC_KEY_LENGTH < EVP_MAX_MD_SIZE +#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 + +static inline int +EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) +{ + return EVP_CipherInit (ctx, type, key, iv, enc); +} + +static inline int +EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) +{ + return EVP_CipherUpdate (ctx, out, outl, in, inl); +} + +static inline bool +cipher_ok (const char* name) +{ + return true; +} + +#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> + +static bool engine_initialized = false; /* GLOBAL */ + +static ENGINE *engine_persist = NULL; /* GLOBAL */ + +/* Try to load an engine in a shareable library */ +static ENGINE * +try_load_engine (const char *engine) +{ + ENGINE *e = ENGINE_by_id ("dynamic"); + if (e) + { + if (!ENGINE_ctrl_cmd_string (e, "SO_PATH", engine, 0) + || !ENGINE_ctrl_cmd_string (e, "LOAD", NULL, 0)) + { + ENGINE_free (e); + e = NULL; + } + } + return e; +} + +static ENGINE * +setup_engine (const char *engine) +{ + ENGINE *e = NULL; + + ENGINE_load_builtin_engines (); + + if (engine) + { + if (strcmp (engine, "auto") == 0) + { + msg (M_INFO, "Initializing OpenSSL auto engine support"); + ENGINE_register_all_complete (); + return NULL; + } + if ((e = ENGINE_by_id (engine)) == NULL + && (e = try_load_engine (engine)) == NULL) + { + msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine); + } + + if (!ENGINE_set_default (e, ENGINE_METHOD_ALL)) + { + msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'", + engine); + } + + msg (M_INFO, "Initializing OpenSSL support for engine '%s'", + ENGINE_get_id (e)); + } + return e; +} + +#endif /* HAVE_OPENSSL_ENGINE */ + +void +crypto_init_lib_engine (const char *engine_name) +{ +#if HAVE_OPENSSL_ENGINE + if (!engine_initialized) + { + ASSERT (engine_name); + ASSERT (!engine_persist); + engine_persist = setup_engine (engine_name); + engine_initialized = true; + } +#else + msg (M_WARN, "Note: OpenSSL hardware crypto engine functionality is not available"); +#endif +} + +/* + * + * Functions related to the core crypto library + * + */ + +void +crypto_init_lib (void) +{ +#ifndef USE_SSL +#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 + * memory leaks on program termination. + */ + +#ifdef CRYPTO_MDEBUG + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); +#endif +} + +void +crypto_uninit_lib (void) +{ +#ifndef USE_SSL + EVP_cleanup (); +#ifndef ENABLE_SMALL + ERR_free_strings (); +#endif +#endif + +#ifdef CRYPTO_MDEBUG + FILE* fp = fopen ("sdlog", "w"); + ASSERT (fp); + CRYPTO_mem_leaks_fp (fp); + fclose (fp); +#endif + +#if HAVE_OPENSSL_ENGINE + if (engine_initialized) + { + ENGINE_cleanup (); + engine_persist = NULL; + engine_initialized = false; + } +#endif +} + +void +crypto_clear_error (void) +{ + ERR_clear_error (); +} + +/* + * + * OpenSSL memory debugging. If dmalloc debugging is enabled, tell + * OpenSSL to use our private malloc/realloc/free functions so that + * we can dispatch them to dmalloc. + * + */ + +#ifdef DMALLOC +static void * +crypto_malloc (size_t size, const char *file, int line) +{ + return dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0); +} + +static void * +crypto_realloc (void *ptr, size_t size, const char *file, int line) +{ + return dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0); +} + +static void +crypto_free (void *ptr) +{ + dmalloc_free (__FILE__, __LINE__, ptr, DMALLOC_FUNC_FREE); +} + +void +crypto_init_dmalloc (void) +{ + CRYPTO_set_mem_ex_functions (crypto_malloc, + crypto_realloc, + crypto_free); +} +#endif /* DMALLOC */ + +void +show_available_ciphers () +{ + int nid; + +#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 + + for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ + { + const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); + if (cipher && cipher_ok (OBJ_nid2sn (nid))) + { + const unsigned int mode = EVP_CIPHER_mode (cipher); + if (mode == EVP_CIPH_CBC_MODE +#ifdef ALLOW_NON_CBC_CIPHERS + || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE +#endif + ) + printf ("%s %d bit default key (%s)\n", + OBJ_nid2sn (nid), + EVP_CIPHER_key_length (cipher) * 8, + ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? + "variable" : "fixed")); + } + } + printf ("\n"); +} + +void +show_available_digests () +{ + int nid; + +#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 + + for (nid = 0; nid < 10000; ++nid) + { + const EVP_MD *digest = EVP_get_digestbynid (nid); + if (digest) + { + printf ("%s %d bit digest size\n", + OBJ_nid2sn (nid), EVP_MD_size (digest) * 8); + } + } + printf ("\n"); +} + +void +show_available_engines () +{ +#if HAVE_OPENSSL_ENGINE /* Only defined for OpenSSL */ + ENGINE *e; + + printf ("OpenSSL Crypto Engines\n\n"); + + ENGINE_load_builtin_engines (); + + e = ENGINE_get_first (); + while (e) + { + printf ("%s [%s]\n", + ENGINE_get_name (e), + ENGINE_get_id (e)); + e = ENGINE_get_next (e); + } + ENGINE_cleanup (); +#else + printf ("Sorry, OpenSSL hardware crypto engine functionality is not available.\n"); +#endif +} + +/* + * + * 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. + * + */ + +int rand_bytes(uint8_t *output, int len) +{ + return RAND_bytes (output, len); +} + +/* + * + * Key functions, allow manipulation of keys. + * + */ + + +int +key_des_num_cblocks (const EVP_CIPHER *kt) +{ + int ret = 0; + const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt)); + if (name) + { + if (!strncmp (name, "DES-", 4)) + { + ret = EVP_CIPHER_key_length (kt) / sizeof (DES_cblock); + } + else if (!strncmp (name, "DESX-", 5)) + { + ret = 1; + } + } + 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) + { + DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock)); + if (!dc) + { + msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); + goto err; + } + if (DES_is_weak_key(dc)) + { + msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); + goto err; + } + if (!DES_check_key_parity (dc)) + { + msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); + goto err; + } + } + return true; + + err: + ERR_clear_error (); + 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) + { + DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock)); + if (!dc) + { + msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material"); + ERR_clear_error (); + return; + } + DES_set_odd_parity (dc); + } +} + + +/* + * + * Generic cipher key type functions + * + */ + + +const EVP_CIPHER * +cipher_kt_get (const char *ciphername) +{ + const EVP_CIPHER *cipher = NULL; + + ASSERT (ciphername); + + cipher = EVP_get_cipherbyname (ciphername); + + if ((NULL == cipher) || !cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher)))) + msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); + + 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); + + return cipher; +} + +const char * +cipher_kt_name (const EVP_CIPHER *cipher_kt) +{ + if (NULL == cipher_kt) + return "[null-cipher]"; + return EVP_CIPHER_name (cipher_kt); +} + +int +cipher_kt_key_size (const EVP_CIPHER *cipher_kt) +{ + return EVP_CIPHER_key_length (cipher_kt); +} + +int +cipher_kt_iv_size (const EVP_CIPHER *cipher_kt) +{ + return EVP_CIPHER_iv_length (cipher_kt); +} + +int +cipher_kt_block_size (const EVP_CIPHER *cipher_kt) +{ + return EVP_CIPHER_block_size (cipher_kt); +} + +int +cipher_kt_mode (const EVP_CIPHER *cipher_kt) +{ + ASSERT(NULL != cipher_kt); + return EVP_CIPHER_mode (cipher_kt); +} + +/* + * + * Generic cipher context functions + * + */ + + +void +cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, + const EVP_CIPHER *kt, int enc) +{ + ASSERT(NULL != kt && NULL != ctx); + + CLEAR (*ctx); + + EVP_CIPHER_CTX_init (ctx); + if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc)) + msg (M_SSLERR, "EVP cipher init #1"); +#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH + if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) + msg (M_SSLERR, "EVP set key size"); +#endif + if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc)) + msg (M_SSLERR, "EVP cipher init #2"); + + /* make sure we used a big enough key */ + ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= key_len); +} + +void +cipher_ctx_cleanup (EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_cleanup (ctx); +} + +int +cipher_ctx_iv_length (const EVP_CIPHER_CTX *ctx) +{ + return EVP_CIPHER_CTX_iv_length (ctx); +} + +int +cipher_ctx_block_size(const EVP_CIPHER_CTX *ctx) +{ + return EVP_CIPHER_CTX_block_size (ctx); +} + +int +cipher_ctx_mode (const EVP_CIPHER_CTX *ctx) +{ + return EVP_CIPHER_CTX_mode (ctx); +} + +int +cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) +{ + return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1); +} + +int +cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, + uint8_t *src, int src_len) +{ + return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len); +} + +int +cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len) +{ + return EVP_CipherFinal (ctx, dst, dst_len); +} + + +void +cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], + unsigned char *src, + unsigned char *dst) +{ + DES_key_schedule sched; + + DES_set_key_unchecked((DES_cblock*)key, &sched); + DES_ecb_encrypt((DES_cblock *)src, (DES_cblock *)dst, &sched, DES_ENCRYPT); +} + +/* + * + * Generic message digest information functions + * + */ + + +const EVP_MD * +md_kt_get (const char *digest) +{ + const EVP_MD *md = NULL; + ASSERT (digest); + md = EVP_get_digestbyname (digest); + if (!md) + msg (M_SSLERR, "Message hash algorithm '%s' not found", digest); + if (EVP_MD_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, + EVP_MD_size (md), + MAX_HMAC_KEY_LENGTH); + return md; +} + +const char * +md_kt_name (const EVP_MD *kt) +{ + if (NULL == kt) + return "[null-digest]"; + return EVP_MD_name (kt); +} + +int +md_kt_size (const EVP_MD *kt) +{ + return EVP_MD_size(kt); +} + + +/* + * + * Generic message digest functions + * + */ + +int +md_full (const EVP_MD *kt, const uint8_t *src, int src_len, uint8_t *dst) +{ + unsigned int in_md_len = 0; + + return EVP_Digest(src, src_len, dst, &in_md_len, kt, NULL); +} + +void +md_ctx_init (EVP_MD_CTX *ctx, const EVP_MD *kt) +{ + ASSERT(NULL != ctx && NULL != kt); + + CLEAR (*ctx); + + EVP_MD_CTX_init (ctx); + EVP_DigestInit(ctx, kt); +} + +void +md_ctx_cleanup(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); +} + +int +md_ctx_size (const EVP_MD_CTX *ctx) +{ + return EVP_MD_CTX_size(ctx); +} + +void +md_ctx_update (EVP_MD_CTX *ctx, const uint8_t *src, int src_len) +{ + EVP_DigestUpdate(ctx, src, src_len); +} + +void +md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst) +{ + unsigned int in_md_len = 0; + + EVP_DigestFinal(ctx, dst, &in_md_len); +} + + +/* + * + * Generic HMAC functions + * + */ + + +void +hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len, + const EVP_MD *kt) +{ + ASSERT(NULL != kt && NULL != ctx); + + CLEAR(*ctx); + + HMAC_CTX_init (ctx); + HMAC_Init_ex (ctx, key, key_len, kt, NULL); + + /* make sure we used a big enough key */ + ASSERT (HMAC_size (ctx) <= key_len); +} + +void +hmac_ctx_cleanup(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup (ctx); +} + +int +hmac_ctx_size (const HMAC_CTX *ctx) +{ + return HMAC_size (ctx); +} + +void +hmac_ctx_reset (HMAC_CTX *ctx) +{ + HMAC_Init_ex (ctx, NULL, 0, NULL, NULL); +} + +void +hmac_ctx_update (HMAC_CTX *ctx, const uint8_t *src, int src_len) +{ + HMAC_Update (ctx, src, src_len); +} + +void +hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst) +{ + unsigned int in_hmac_len = 0; + + HMAC_Final (ctx, dst, &in_hmac_len); +} + +#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_OPENSSL */ diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h new file mode 100644 index 0000000..f883c2a --- /dev/null +++ b/src/openvpn/crypto_openssl.h @@ -0,0 +1,73 @@ +/* + * 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 OpenSSL-specific backend interface + */ + +#ifndef CRYPTO_OPENSSL_H_ +#define CRYPTO_OPENSSL_H_ + +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/md5.h> + +/** Generic cipher key type %context. */ +typedef EVP_CIPHER cipher_kt_t; + +/** Generic message digest key type %context. */ +typedef EVP_MD md_kt_t; + +/** Generic cipher %context. */ +typedef EVP_CIPHER_CTX cipher_ctx_t; + +/** Generic message digest %context. */ +typedef EVP_MD_CTX md_ctx_t; + +/** Generic HMAC %context. */ +typedef HMAC_CTX hmac_ctx_t; + +/** Maximum length of an IV */ +#define OPENVPN_MAX_IV_LENGTH EVP_MAX_IV_LENGTH + +/** Cipher is in CBC mode */ +#define OPENVPN_MODE_CBC EVP_CIPH_CBC_MODE + +/** Cipher is in OFB mode */ +#define OPENVPN_MODE_OFB EVP_CIPH_OFB_MODE + +/** Cipher is in CFB mode */ +#define OPENVPN_MODE_CFB EVP_CIPH_CFB_MODE + +/** Cipher should encrypt */ +#define OPENVPN_OP_ENCRYPT 1 + +/** Cipher should decrypt */ +#define OPENVPN_OP_DECRYPT 0 + +#define DES_KEY_LENGTH 8 +#define MD4_DIGEST_LENGTH 16 + +#endif /* CRYPTO_OPENSSL_H_ */ diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c new file mode 100644 index 0000000..3978a3c --- /dev/null +++ b/src/openvpn/crypto_polarssl.c @@ -0,0 +1,605 @@ +/* + * 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/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) +{ +} + +#ifdef DMALLOC +void +crypto_init_dmalloc (void) +{ + msg (M_ERR, "Error: dmalloc support is not available for PolarSSL."); +} +#endif /* DMALLOC */ + +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", + info->name, info->key_length); + + 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 (0 != 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 cipher_kt->name; +} + +int +cipher_kt_key_size (const cipher_info_t *cipher_kt) +{ + if (NULL == cipher_kt) + return 0; + 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; +} + + +/* + * + * 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 (0 != cipher_init_ctx(ctx, kt)) + msg (M_FATAL, "PolarSSL cipher context init #1"); + + if (0 != 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(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); +} + +int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf) +{ + return 0 == cipher_reset(ctx, iv_buf); +} + +int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len, + uint8_t *src, int src_len) +{ + int retval = 0; + size_t s_dst_len = *dst_len; + + retval = cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len); + + *dst_len = s_dst_len; + + return 0 == retval; +} + +int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len) +{ + int retval = 0; + size_t s_dst_len = *dst_len; + + retval = cipher_finish(ctx, dst, &s_dst_len); + *dst_len = s_dst_len; + + return 0 == retval; +} + +void +cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], + unsigned char *src, + unsigned char *dst) +{ + des_context ctx; + + des_setkey_enc(&ctx, key); + 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)); + ASSERT(0 == md_free_ctx(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) +{ + ASSERT(0 == md_free_ctx(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/crypto_polarssl.h b/src/openvpn/crypto_polarssl.h new file mode 100644 index 0000000..bfabb91 --- /dev/null +++ b/src/openvpn/crypto_polarssl.h @@ -0,0 +1,95 @@ +/* + * 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 + */ + +#ifndef CRYPTO_POLARSSL_H_ +#define CRYPTO_POLARSSL_H_ + +#include <polarssl/version.h> +#include <polarssl/cipher.h> +#include <polarssl/md.h> +#include <polarssl/ctr_drbg.h> + +/** Generic cipher key type %context. */ +typedef cipher_info_t cipher_kt_t; + +/** Generic message digest key type %context. */ +typedef md_info_t md_kt_t; + +/** Generic cipher %context. */ +typedef cipher_context_t cipher_ctx_t; + +/** Generic message digest %context. */ +typedef md_context_t md_ctx_t; + +/** Generic HMAC %context. */ +typedef md_context_t hmac_ctx_t; + +/** Maximum length of an IV */ +#define OPENVPN_MAX_IV_LENGTH POLARSSL_MAX_IV_LENGTH + +/** Cipher is in CBC mode */ +#define OPENVPN_MODE_CBC POLARSSL_MODE_CBC + +/** Cipher is in OFB mode */ +#define OPENVPN_MODE_OFB POLARSSL_MODE_OFB + +/** Cipher is in CFB mode */ +#define OPENVPN_MODE_CFB POLARSSL_MODE_CFB128 + +/** Cipher should encrypt */ +#define OPENVPN_OP_ENCRYPT POLARSSL_ENCRYPT + +/** Cipher should decrypt */ +#define OPENVPN_OP_DECRYPT POLARSSL_DECRYPT + +#define MD4_DIGEST_LENGTH 16 +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define DES_KEY_LENGTH 8 + +/** + * Returns a singleton instance of the PolarSSL random number generator. + * + * For PolarSSL 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(); + +#ifdef ENABLE_PREDICTION_RESISTANCE +/** + * Enable prediction resistance on the random number generator. + */ +void rand_ctx_enable_prediction_resistance(); +#endif + +#endif /* CRYPTO_POLARSSL_H_ */ diff --git a/cryptoapi.c b/src/openvpn/cryptoapi.c index 3365cd7..b7fc11e 100644 --- a/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -28,9 +28,15 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#if defined(WIN32) && defined(USE_CRYPTO) && defined(USE_SSL) +#ifdef ENABLE_CRYPTOAPI #include <openssl/ssl.h> #include <openssl/err.h> @@ -40,21 +46,23 @@ #include <ctype.h> #include <assert.h> -#ifdef __MINGW32_VERSION -/* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1 - * anyway. This is a hack around that problem. */ -#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5) +/* MinGW w32api 3.17 is still incomplete when it comes to CryptoAPI while + * MinGW32-w64 defines all macros used. This is a hack around that problem. + */ +#ifndef CERT_SYSTEM_STORE_LOCATION_SHIFT #define CERT_SYSTEM_STORE_LOCATION_SHIFT 16 +#endif +#ifndef CERT_SYSTEM_STORE_CURRENT_USER_ID #define CERT_SYSTEM_STORE_CURRENT_USER_ID 1 +#endif +#ifndef CERT_SYSTEM_STORE_CURRENT_USER #define CERT_SYSTEM_STORE_CURRENT_USER (CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT) +#endif +#ifndef CERT_STORE_READONLY_FLAG #define CERT_STORE_READONLY_FLAG 0x00008000 +#endif +#ifndef CERT_STORE_OPEN_EXISTING_FLAG #define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 -#define CRYPT_ACQUIRE_COMPARE_KEY_FLAG 0x00000004 -static HINSTANCE crypt32dll = NULL; -static BOOL WINAPI (*OpenVPNCryptAcquireCertificatePrivateKey) (PCCERT_CONTEXT pCert, DWORD dwFlags, - void *pvReserved, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec, BOOL *pfCallerFreeProv) = NULL; -#else -#define OpenVPNCryptAcquireCertificatePrivateKey CryptAcquireCertificatePrivateKey #endif /* Size of an SSL signature: MD5+SHA1 */ @@ -379,26 +387,7 @@ int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) } /* set up stuff to use the private key */ -#ifdef __MINGW32_VERSION - /* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1 - * anyway. This is a hack around that problem. */ - if (crypt32dll == NULL) { - crypt32dll = LoadLibrary("crypt32"); - if (crypt32dll == NULL) { - CRYPTOAPIerr(CRYPTOAPI_F_LOAD_LIBRARY); - goto err; - } - } - if (OpenVPNCryptAcquireCertificatePrivateKey == NULL) { - OpenVPNCryptAcquireCertificatePrivateKey = GetProcAddress(crypt32dll, - "CryptAcquireCertificatePrivateKey"); - if (OpenVPNCryptAcquireCertificatePrivateKey == NULL) { - CRYPTOAPIerr(CRYPTOAPI_F_GET_PROC_ADDRESS); - goto err; - } - } -#endif - if (!OpenVPNCryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, + if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) { /* if we don't have a smart card reader here, and we try to access a * smart card certificate, we get: diff --git a/cryptoapi.h b/src/openvpn/cryptoapi.h index 8ac6db3..8ac6db3 100644 --- a/cryptoapi.h +++ b/src/openvpn/cryptoapi.h diff --git a/dhcp.c b/src/openvpn/dhcp.c index 3474a17..8d0b18a 100644 --- a/dhcp.c +++ b/src/openvpn/dhcp.c @@ -22,6 +22,12 @@ * 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" #include "dhcp.h" @@ -66,20 +72,20 @@ get_dhcp_message_type (const struct dhcp *dhcp, const int optlen) } static in_addr_t -do_extract (struct dhcp *dhcp, const int optlen) +do_extract (struct dhcp *dhcp, int optlen) { uint8_t *p = (uint8_t *) (dhcp + 1); int i; in_addr_t ret = 0; - for (i = 0; i < optlen; ++i) + for (i = 0; i < optlen; ) { const uint8_t type = p[i]; const int room = optlen - i; if (type == DHCP_END) break; else if (type == DHCP_PAD) - ; + ++i; else if (type == DHCP_ROUTER) { if (room >= 2) @@ -87,23 +93,39 @@ do_extract (struct dhcp *dhcp, const int optlen) const int len = p[i+1]; /* get option length */ if (len <= (room-2)) { + /* get router IP address */ if (!ret && len >= 4 && (len & 3) == 0) { - memcpy (&ret, p+i+2, 4); /* get router IP address */ + memcpy (&ret, p+i+2, 4); ret = ntohl (ret); } - memset (p+i, DHCP_PAD, len+2); /* delete the router option by padding it out */ + { + /* delete the router option */ + uint8_t *dest = p + i; + const int owlen = len + 2; /* len of data to overwrite */ + uint8_t *src = dest + owlen; + uint8_t *end = p + optlen; + const int movlen = end - src; + if (movlen > 0) + memmove(dest, src, movlen); /* overwrite router option */ + memset(end - owlen, DHCP_PAD, owlen); /* pad tail */ + } } - i += (len + 1); /* advance to next option */ + else + break; } + else + break; } - else /* some other option */ + else /* some other option */ { if (room >= 2) { - const int len = p[i+1]; /* get option length */ - i += (len + 1); /* advance to next option */ + const int len = p[i+1]; /* get option length */ + i += (len + 2); /* advance to next option */ } + else + break; } } return ret; @@ -157,27 +179,34 @@ dhcp_extract_router_msg (struct buffer *ipbuf) && df->ip.protocol == OPENVPN_IPPROTO_UDP && df->udp.source == htons (BOOTPS_PORT) && df->udp.dest == htons (BOOTPC_PORT) - && df->dhcp.op == BOOTREPLY - && get_dhcp_message_type (&df->dhcp, optlen) == DHCPACK) + && df->dhcp.op == BOOTREPLY) { - /* get the router IP address while padding out all DHCP router options */ - const in_addr_t ret = do_extract (&df->dhcp, optlen); - - /* recompute the UDP checksum */ - df->udp.check = htons (udp_checksum ((uint8_t *) &df->udp, - sizeof (struct openvpn_udphdr) + sizeof (struct dhcp) + optlen, - (uint8_t *)&df->ip.saddr, - (uint8_t *)&df->ip.daddr)); - - if (ret) + const int message_type = get_dhcp_message_type (&df->dhcp, optlen); + if (message_type == DHCPACK || message_type == DHCPOFFER) { - struct gc_arena gc = gc_new (); - msg (D_ROUTE, "Extracted DHCP router address: %s", print_in_addr_t (ret, 0, &gc)); - gc_free (&gc); - } + /* get the router IP address while padding out all DHCP router options */ + const in_addr_t ret = do_extract (&df->dhcp, optlen); + + /* recompute the UDP checksum */ + df->udp.check = 0; + df->udp.check = htons (udp_checksum ((uint8_t *) &df->udp, + sizeof (struct openvpn_udphdr) + sizeof (struct dhcp) + optlen, + (uint8_t *)&df->ip.saddr, + (uint8_t *)&df->ip.daddr)); + + /* only return the extracted Router address if DHCPACK */ + if (message_type == DHCPACK) + { + if (ret) + { + struct gc_arena gc = gc_new (); + msg (D_ROUTE, "Extracted DHCP router address: %s", print_in_addr_t (ret, 0, &gc)); + gc_free (&gc); + } - return ret; + return ret; + } + } } - else - return 0; + return 0; } diff --git a/dhcp.h b/src/openvpn/dhcp.h index e823a4a..e823a4a 100644 --- a/dhcp.h +++ b/src/openvpn/dhcp.h diff --git a/errlevel.h b/src/openvpn/errlevel.h index 75c3194..3ee4ebc 100644 --- a/errlevel.h +++ b/src/openvpn/errlevel.h @@ -71,9 +71,7 @@ #define D_ALIGN_ERRORS LOGLEV(1, 14, M_NONFATAL) /* show bad struct alignments */ #define D_HANDSHAKE LOGLEV(2, 20, 0) /* show data & control channel handshakes */ -#define D_MTU_INFO LOGLEV(2, 21, 0) /* show terse MTU info */ #define D_CLOSE LOGLEV(2, 22, 0) /* show socket and TUN/TAP close */ -#define D_SHOW_OCC_HASH LOGLEV(2, 23, 0) /* show MD5 hash of option compatibility string */ #define D_PROXY LOGLEV(2, 24, 0) /* show http proxy control packets */ #define D_ARGV LOGLEV(2, 25, 0) /* show struct argv errors */ @@ -85,7 +83,6 @@ #define D_RESTART LOGLEV(3, 33, 0) /* show certain restart messages */ #define D_PUSH LOGLEV(3, 34, 0) /* show push/pull info */ #define D_IFCONFIG_POOL LOGLEV(3, 35, 0) /* show ifconfig pool info */ -#define D_BACKTRACK LOGLEV(3, 36, 0) /* show replay backtracks */ #define D_AUTH LOGLEV(3, 37, 0) /* show user/pass auth info */ #define D_MULTI_LOW LOGLEV(3, 38, 0) /* show point-to-multipoint low-freq debug info */ #define D_PLUGIN LOGLEV(3, 39, 0) /* show plugin calls */ @@ -104,12 +101,20 @@ #define D_PACKET_TRUNC_ERR LOGLEV(4, 55, 0) /* PACKET_TRUNCATION_CHECK */ #define D_PF_DROPPED LOGLEV(4, 56, 0) /* packet filter dropped a packet */ #define D_MULTI_DROPPED LOGLEV(4, 57, 0) /* show point-to-multipoint packet drops */ +#define D_MULTI_MEDIUM LOGLEV(4, 58, 0) /* show medium frequency multi messages */ +#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 */ #define D_LOG_RW LOGLEV(5, 0, 0) /* Print 'R' or 'W' to stdout for read/write */ -#define D_LINK_RW LOGLEV(6, 60, M_DEBUG) /* show TCP/UDP reads/writes (terse) */ -#define D_TUN_RW LOGLEV(6, 60, M_DEBUG) /* show TUN/TAP reads/writes */ -#define D_TAP_WIN32_DEBUG LOGLEV(6, 60, M_DEBUG) /* show TAP-Win32 driver debug info */ +#define D_LINK_RW LOGLEV(6, 69, M_DEBUG) /* show TCP/UDP reads/writes (terse) */ +#define D_TUN_RW LOGLEV(6, 69, M_DEBUG) /* show TUN/TAP reads/writes */ +#define D_TAP_WIN_DEBUG LOGLEV(6, 69, M_DEBUG) /* show TAP-Windows driver debug info */ +#define D_CLIENT_NAT LOGLEV(6, 69, M_DEBUG) /* show client NAT debug info */ #define D_SHOW_KEYS LOGLEV(7, 70, M_DEBUG) /* show data channel encryption keys */ #define D_SHOW_KEY_SOURCE LOGLEV(7, 70, M_DEBUG) /* show data channel key source entropy */ @@ -117,7 +122,6 @@ #define D_FRAG_DEBUG LOGLEV(7, 70, M_DEBUG) /* show fragment debugging info */ #define D_WIN32_IO_LOW LOGLEV(7, 70, M_DEBUG) /* low freq win32 I/O debugging info */ #define D_MTU_DEBUG LOGLEV(7, 70, M_DEBUG) /* show MTU debugging info */ -#define D_PID_DEBUG_LOW LOGLEV(7, 70, M_DEBUG) /* show low-freq packet-id debugging info */ #define D_MULTI_DEBUG LOGLEV(7, 70, M_DEBUG) /* show medium-freq multi debugging info */ #define D_MSS LOGLEV(7, 70, M_DEBUG) /* show MSS adjustments */ #define D_COMP_LOW LOGLEV(7, 70, M_DEBUG) /* show adaptive compression state changes */ @@ -141,6 +145,7 @@ #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_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 */ @@ -158,7 +163,6 @@ #define D_READ_WRITE LOGLEV(9, 70, M_DEBUG) /* show all tun/tcp/udp reads/writes/opens */ #define D_PACKET_CONTENT LOGLEV(9, 70, M_DEBUG) /* show before/after encryption packet content */ #define D_TLS_NO_SEND_KEY LOGLEV(9, 70, M_DEBUG) /* show when no data channel send-key exists */ -#define D_PID_DEBUG LOGLEV(9, 70, M_DEBUG) /* show packet-id debugging info */ #define D_PID_PERSIST_DEBUG LOGLEV(9, 70, M_DEBUG) /* show packet-id persist debugging info */ #define D_LINK_RW_VERBOSE LOGLEV(9, 70, M_DEBUG) /* show link reads/writes with greater verbosity */ #define D_STREAM_DEBUG LOGLEV(9, 70, M_DEBUG) /* show TCP stream debug info */ diff --git a/error.c b/src/openvpn/error.c index 9754464..6848425 100644 --- a/error.c +++ b/src/openvpn/error.c @@ -22,6 +22,12 @@ * 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" #include "error.h" @@ -35,10 +41,13 @@ #include "status.h" #include "integer.h" #include "ps.h" +#include "mstats.h" -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO +#ifdef ENABLE_CRYPTO_OPENSSL #include <openssl/err.h> #endif +#endif #include "memdbg.h" @@ -192,8 +201,15 @@ int x_msg_line_num; /* GLOBAL */ void x_msg (const unsigned int flags, const char *format, ...) { - struct gc_arena gc; va_list arglist; + va_start (arglist, format); + x_msg_va (flags, format, arglist); + va_end (arglist); +} + +void x_msg_va (const unsigned int flags, const char *format, va_list arglist) +{ + struct gc_arena gc; #if SYSLOG_CAPABILITY int level; #endif @@ -212,10 +228,7 @@ void x_msg (const unsigned int flags, const char *format, ...) return; #endif - if (flags & M_ERRNO_SOCK) - e = openvpn_errno_socket (); - else - e = openvpn_errno (); + e = openvpn_errno (); /* * Apply muting filter. @@ -231,19 +244,18 @@ void x_msg (const unsigned int flags, const char *format, ...) m1 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); m2 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); - va_start (arglist, format); vsnprintf (m1, ERR_BUF_SIZE, format, arglist); - va_end (arglist); m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */ - if ((flags & (M_ERRNO|M_ERRNO_SOCK)) && e) + if ((flags & M_ERRNO) && e) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", m1, strerror_ts (e, &gc), e); SWAP; } -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO +#ifdef ENABLE_CRYPTO_OPENSSL if (flags & M_SSL) { int nerrs = 0; @@ -262,6 +274,7 @@ void x_msg (const unsigned int flags, const char *format, ...) } } #endif +#endif if (flags & M_OPTERR) { @@ -340,7 +353,7 @@ void x_msg (const unsigned int flags, const char *format, ...) } if (flags & M_FATAL) - msg (M_INFO, "Exiting"); + msg (M_INFO, "Exiting due to fatal error"); if (flags & M_FATAL) openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */ @@ -460,6 +473,7 @@ redirect_stdout_stderr (const char *file, bool append) #if defined(WIN32) if (!std_redir) { + struct gc_arena gc = gc_new (); HANDLE log_handle; int log_fd; @@ -468,13 +482,15 @@ redirect_stdout_stderr (const char *file, bool append) saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - log_handle = CreateFile (file, - GENERIC_WRITE, - FILE_SHARE_READ, - &saAttr, - append ? OPEN_ALWAYS : CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); + log_handle = CreateFileW (wide_string (file, &gc), + GENERIC_WRITE, + FILE_SHARE_READ, + &saAttr, + append ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + gc_free (&gc); if (log_handle == INVALID_HANDLE_VALUE) { @@ -582,7 +598,7 @@ x_check_status (int status, struct link_socket *sock, struct tuntap *tt) { - const int my_errno = (sock ? openvpn_errno_socket () : (int)openvpn_errno ()); + const int my_errno = openvpn_errno (); const char *extended_msg = NULL; msg (x_cs_verbose_level, "%s %s returned %d", @@ -606,8 +622,8 @@ x_check_status (int status, } } #elif defined(WIN32) - /* get possible driver error from TAP-Win32 driver */ - extended_msg = tap_win32_getinfo (tt, &gc); + /* get possible driver error from TAP-Windows driver */ + extended_msg = tap_win_getinfo (tt, &gc); #endif if (!ignore_sys_error (my_errno)) { @@ -626,7 +642,7 @@ x_check_status (int status, my_errno); if (x_cs_err_delay_ms) - sleep_milliseconds (x_cs_err_delay_ms); + platform_sleep_milliseconds (x_cs_err_delay_ms); } gc_free (&gc); } @@ -651,35 +667,42 @@ const struct virtual_output *x_msg_virtual_output; /* GLOBAL */ void openvpn_exit (const int status) { - void tun_abort(); + if (!forked) + { + void tun_abort(); #ifdef ENABLE_PLUGIN - void plugin_abort (void); + void plugin_abort (void); #endif - tun_abort(); + tun_abort(); #ifdef WIN32 - uninit_win32 (); + uninit_win32 (); #endif - close_syslog (); + close_syslog (); #ifdef ENABLE_PLUGIN - plugin_abort (); + plugin_abort (); #endif #if PORT_SHARE - if (port_share) - port_share_abort (port_share); + if (port_share) + port_share_abort (port_share); +#endif + +#ifdef ENABLE_MEMSTATS + mstats_close(); #endif #ifdef ABORT_ON_ERROR - if (status == OPENVPN_EXIT_STATUS_ERROR) - abort (); + if (status == OPENVPN_EXIT_STATUS_ERROR) + abort (); #endif - if (status == OPENVPN_EXIT_STATUS_GOOD) - perf_output_results (); + if (status == OPENVPN_EXIT_STATUS_GOOD) + perf_output_results (); + } exit (status); } @@ -726,7 +749,7 @@ strerror_win32 (DWORD errnum, struct gc_arena *gc) #if 1 switch (errnum) { /* - * When the TAP-Win32 driver returns STATUS_UNSUCCESSFUL, this code + * When the TAP-Windows driver returns STATUS_UNSUCCESSFUL, this code * gets returned to user space. */ case ERROR_GEN_FAILURE: diff --git a/error.h b/src/openvpn/error.h index 4be3268..27c48b6 100644 --- a/error.h +++ b/src/openvpn/error.h @@ -68,12 +68,10 @@ struct gc_arena; #ifdef WIN32 # define openvpn_errno() GetLastError() -# define openvpn_errno_socket() WSAGetLastError() # define openvpn_strerror(e, gc) strerror_win32(e, gc) const char *strerror_win32 (DWORD errnum, struct gc_arena *gc); #else # define openvpn_errno() errno -# define openvpn_errno_socket() errno # define openvpn_strerror(x, gc) strerror(x) #endif @@ -94,8 +92,11 @@ extern int x_msg_line_num; #define M_DEBUG (1<<7) #define M_ERRNO (1<<8) /* show errno description */ -#define M_ERRNO_SOCK (1<<9) /* show socket errno description */ -#define M_SSL (1<<10) /* show SSL error */ + +#ifdef ENABLE_CRYPTO_OPENSSL +# define M_SSL (1<<10) /* show SSL error */ +#endif + #define M_NOMUTE (1<<11) /* don't do mute processing */ #define M_NOPREFIX (1<<12) /* don't show date/time prefix */ #define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */ @@ -106,7 +107,6 @@ extern int x_msg_line_num; /* flag combinations which are frequently used */ #define M_ERR (M_FATAL | M_ERRNO) -#define M_SOCKERR (M_FATAL | M_ERRNO_SOCK) #define M_SSLERR (M_FATAL | M_SSL) #define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR) #define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX) @@ -174,10 +174,16 @@ bool dont_mute (unsigned int flags); /* check muting filter */ void x_msg (const unsigned int flags, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 2, 3))) +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format (gnu_printf, 2, 3))) +#else + __attribute__ ((format (__printf__, 2, 3))) +#endif #endif ; /* should be called via msg above */ +void x_msg_va (const unsigned int flags, const char *format, va_list arglist); + /* * Function prototypes */ @@ -240,6 +246,9 @@ HANDLE get_orig_stderr (void); /* exit program */ void openvpn_exit (const int status); +/* exit program on out of memory error */ +void out_of_memory (void); + /* * Check the return status of read/write routines. */ diff --git a/event.c b/src/openvpn/event.c index 6a9161b..2a13e1c 100644 --- a/event.c +++ b/src/openvpn/event.c @@ -22,6 +22,12 @@ * 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" #include "buffer.h" @@ -214,9 +220,9 @@ we_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg) { struct we_set *wes = (struct we_set *) es; - dmsg (D_EVENT_WAIT, "WE_CTL n=%d ev=0x%08x rwflags=0x%04x arg=" ptr_format, + dmsg (D_EVENT_WAIT, "WE_CTL n=%d ev=%p rwflags=0x%04x arg=" ptr_format, wes->n_events, - (unsigned int)event, + event, rwflags, (ptr_type)arg); @@ -344,9 +350,9 @@ we_wait (struct event_set *es, const struct timeval *tv, struct event_set_return if (check_debug_level (D_EVENT_WAIT)) { int i; for (i = 0; i < wes->n_events; ++i) - dmsg (D_EVENT_WAIT, "[%d] ev=0x%08x rwflags=0x%04x arg=" ptr_format, + dmsg (D_EVENT_WAIT, "[%d] ev=%p rwflags=0x%04x arg=" ptr_format, i, - (unsigned int)wes->events[i], + wes->events[i], wes->esr[i].rwflags, (ptr_type)wes->esr[i].arg); } @@ -522,10 +528,10 @@ ep_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg) if (errno == ENOENT) { if (epoll_ctl (eps->epfd, EPOLL_CTL_ADD, event, &ev) < 0) - msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_ADD failed"); + msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_ADD failed, sd=%d", (int)event); } else - msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_MOD failed"); + msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_MOD failed, sd=%d", (int)event); } } diff --git a/event.h b/src/openvpn/event.h index bd29fdc..bd29fdc 100644 --- a/event.h +++ b/src/openvpn/event.h diff --git a/fdmisc.c b/src/openvpn/fdmisc.c index 5be3c8b..7fe449c 100644 --- a/fdmisc.c +++ b/src/openvpn/fdmisc.c @@ -22,6 +22,12 @@ * 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" #include "fdmisc.h" @@ -60,7 +66,7 @@ void set_nonblock (int fd) { if (!set_nonblock_action (fd)) - msg (M_SOCKERR, "Set socket to non-blocking mode failed"); + msg (M_ERR, "Set socket to non-blocking mode failed"); } /* Set a file descriptor to not be passed across execs */ diff --git a/fdmisc.h b/src/openvpn/fdmisc.h index 4b6b6d0..4b6b6d0 100644 --- a/fdmisc.h +++ b/src/openvpn/fdmisc.h diff --git a/forward-inline.h b/src/openvpn/forward-inline.h index 64ca941..5853ce2 100644 --- a/forward-inline.h +++ b/src/openvpn/forward-inline.h @@ -35,7 +35,7 @@ static inline void check_tls (struct context *c) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) 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(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) 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) @@ -189,7 +189,7 @@ check_push_request (struct context *c) #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* * Should we persist our anti-replay packet ID state to disk? */ diff --git a/forward.c b/src/openvpn/forward.c index 87d05cc..57c7846 100644 --- a/forward.c +++ b/src/openvpn/forward.c @@ -22,6 +22,12 @@ * 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" #include "forward.h" @@ -39,6 +45,7 @@ #include "forward-inline.h" #include "occ-inline.h" #include "ping-inline.h" +#include "mstats.h" counter_type link_read_bytes_global; /* GLOBAL */ counter_type link_write_bytes_global; /* GLOBAL */ @@ -80,7 +87,7 @@ show_wait_status (struct context *c) * traffic on the control-channel. * */ -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) void check_tls_dowork (struct context *c) { @@ -98,8 +105,7 @@ check_tls_dowork (struct context *c) } else if (tmp_status == TLSMP_KILL) { - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "auth-control-exit"; + register_signal (c, SIGTERM, "auth-control-exit"); } interval_future_trigger (&c->c2.tmp_int, wakeup); @@ -112,21 +118,19 @@ check_tls_dowork (struct context *c) } #endif -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) void check_tls_errors_co (struct context *c) { msg (D_STREAM_ERRORS, "Fatal TLS error (check_tls_errors_co), restarting"); - c->sig->signal_received = c->c2.tls_exit_signal; /* SOFT-SIGUSR1 -- TLS error */ - c->sig->signal_text = "tls-error"; + register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ } void check_tls_errors_nco (struct context *c) { - c->sig->signal_received = c->c2.tls_exit_signal; /* SOFT-SIGUSR1 -- TLS error */ - c->sig->signal_text = "tls-error"; + register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ } #endif @@ -158,7 +162,9 @@ check_incoming_control_channel_dowork (struct context *c) else if (buf_string_match_head_str (&buf, "PUSH_")) incoming_push_message (c, &buf); else if (buf_string_match_head_str (&buf, "RESTART")) - server_pushed_restart (c, &buf); + server_pushed_signal (c, &buf, true, 7); + else if (buf_string_match_head_str (&buf, "HALT")) + server_pushed_signal (c, &buf, false, 4); else msg (D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR (&buf)); } @@ -179,8 +185,8 @@ check_push_request_dowork (struct context *c) { send_push_request (c); - /* if no response to first push_request, retry at 5 second intervals */ - event_timeout_modify_wakeup (&c->c2.push_request_interval, 5); + /* if no response to first push_request, retry at PUSH_REQUEST_INTERVAL second intervals */ + event_timeout_modify_wakeup (&c->c2.push_request_interval, PUSH_REQUEST_INTERVAL); } #endif /* P2MP */ @@ -232,23 +238,29 @@ check_connection_established_dowork (struct context *c) bool send_control_channel_string (struct context *c, const char *str, int msglevel) { -#if defined(USE_CRYPTO) && defined(USE_SSL) - +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->c2.tls_multi) { + struct gc_arena gc = gc_new (); bool stat; /* buffered cleartext write onto TLS control channel */ stat = tls_send_payload (c->c2.tls_multi, (uint8_t*) str, strlen (str) + 1); - /* reschedule tls_multi_process */ + /* + * Reschedule tls_multi_process. + * NOTE: in multi-client mode, usually the below two statements are + * insufficient to reschedule the client instance object unless + * multi_schedule_context_wakeup(m, mi) is also called. + */ interval_action (&c->c2.tmp_int); context_immediate_reschedule (c); /* ZERO-TIMEOUT */ msg (msglevel, "SENT CONTROL [%s]: '%s' (status=%d)", tls_common_name (c->c2.tls_multi, false), - str, + sanitize_control_message (str, &gc), (int) stat); + gc_free (&gc); return stat; } #endif @@ -262,7 +274,8 @@ send_control_channel_string (struct context *c, const char *str, int msglevel) static void check_add_routes_action (struct context *c, const bool errors) { - do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es); + do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list, + c->c1.tuntap, c->plugins, c->c2.es); update_time (); event_timeout_clear (&c->c2.route_wakeup); event_timeout_clear (&c->c2.route_wakeup_expire); @@ -287,8 +300,7 @@ check_add_routes_dowork (struct context *c) { if (!tun_standby (c->c1.tuntap)) { - c->sig->signal_received = SIGHUP; - c->sig->signal_text = "ip-fail"; + register_signal (c, SIGHUP, "ip-fail"); c->persist.restart_sleep_seconds = 10; #ifdef WIN32 show_routes (M_INFO|M_NOPREFIX); @@ -310,8 +322,7 @@ void check_inactivity_timeout_dowork (struct context *c) { msg (M_INFO, "Inactivity timeout (--inactive), exiting"); - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "inactive"; + register_signal (c, SIGTERM, "inactive"); } #if P2MP @@ -323,8 +334,7 @@ check_server_poll_timeout_dowork (struct context *c) if (!tls_initial_packet_received (c->c2.tls_multi)) { msg (M_INFO, "Server poll timeout, restarting"); - c->sig->signal_received = SIGUSR1; - c->sig->signal_text = "server_poll"; + register_signal (c, SIGUSR1, "server_poll"); c->persist.restart_sleep_seconds = -1; } } @@ -349,8 +359,7 @@ schedule_exit (struct context *c, const int n_seconds, const int signal) void check_scheduled_exit_dowork (struct context *c) { - c->sig->signal_received = c->c2.scheduled_exit_signal; - c->sig->signal_text = "delayed-exit"; + register_signal (c, c->c2.scheduled_exit_signal, "delayed-exit"); } #endif @@ -435,7 +444,7 @@ encrypt_sign (struct context *c, bool comp_frag) if (comp_frag) { -#ifdef USE_LZO +#ifdef ENABLE_LZO /* 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); @@ -446,8 +455,8 @@ encrypt_sign (struct context *c, bool comp_frag) #endif } -#ifdef USE_CRYPTO -#ifdef USE_SSL +#ifdef ENABLE_CRYPTO +#ifdef ENABLE_SSL /* * If TLS mode, get the key we will use to encrypt * the packet. @@ -469,8 +478,8 @@ encrypt_sign (struct context *c, bool comp_frag) */ link_socket_get_outgoing_addr (&c->c2.buf, get_link_socket_info (c), &c->c2.to_link_addr); -#ifdef USE_CRYPTO -#ifdef USE_SSL +#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 @@ -495,7 +504,7 @@ encrypt_sign (struct context *c, bool comp_frag) static void process_coarse_timers (struct context *c) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* flush current packet-id to file once per 60 seconds if --replay-persist was specified */ check_packet_id_persist_flush (c); @@ -675,8 +684,7 @@ read_incoming_link (struct context *c) const struct buffer *fbuf = socket_foreign_protocol_head (c->c2.link_socket); const int sd = socket_foreign_protocol_sd (c->c2.link_socket); port_share_redirect (port_share, fbuf, sd); - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "port-share-redirect"; + register_signal (c, SIGTERM, "port-share-redirect"); } else #endif @@ -684,8 +692,7 @@ read_incoming_link (struct context *c) /* received a disconnect from a connection-oriented protocol */ if (c->options.inetd) { - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "connection-reset-inetd"; + register_signal (c, SIGTERM, "connection-reset-inetd"); msg (D_STREAM_ERRORS, "Connection reset, inetd/xinetd exit [%d]", status); } else @@ -699,8 +706,7 @@ read_incoming_link (struct context *c) else #endif { - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- TCP connection reset */ - c->sig->signal_text = "connection-reset"; + register_signal (c, SIGUSR1, "connection-reset"); /* SOFT-SIGUSR1 -- TCP connection reset */ msg (D_STREAM_ERRORS, "Connection reset, restarting [%d]", status); } } @@ -739,6 +745,10 @@ process_incoming_link (struct context *c) { c->c2.link_read_bytes += c->c2.buf.len; link_read_bytes_global += c->c2.buf.len; +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->link_read_bytes = link_read_bytes_global; +#endif c->c2.original_recv_size = c->c2.buf.len; #ifdef ENABLE_MANAGEMENT if (management) @@ -785,8 +795,8 @@ process_incoming_link (struct context *c) 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 USE_CRYPTO -#ifdef USE_SSL +#ifdef ENABLE_CRYPTO +#ifdef ENABLE_SSL if (c->c2.tls_multi) { /* @@ -816,7 +826,7 @@ process_incoming_link (struct context *c) if (c->c2.context_auth != CAS_SUCCEEDED) c->c2.buf.len = 0; #endif -#endif /* USE_SSL */ +#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); @@ -824,20 +834,19 @@ process_incoming_link (struct context *c) if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket)) { /* decryption errors are fatal in TCP mode */ - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- decryption error in TCP mode */ - c->sig->signal_text = "decryption-error"; + 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; } -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ #ifdef ENABLE_FRAGMENT if (c->c2.fragment) fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment); #endif -#ifdef USE_LZO +#ifdef ENABLE_LZO /* 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); @@ -937,8 +946,7 @@ read_incoming_tun (struct context *c) /* Was TUN/TAP interface stopped? */ if (tuntap_stop (c->c2.buf.len)) { - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "tun-stop"; + register_signal (c, SIGTERM, "tun-stop"); msg (M_INFO, "TUN/TAP interface has been stopped, exiting"); perf_pop (); return; @@ -979,7 +987,7 @@ process_incoming_tun (struct context *c) * The --passtos and --mssfix options require * us to examine the IPv4 header. */ - process_ipv4_header (c, PIPV4_PASSTOS|PIPV4_MSSFIX, &c->c2.buf); + process_ipv4_header (c, PIPV4_PASSTOS|PIPV4_MSSFIX|PIPV4_CLIENT_NAT, &c->c2.buf); #ifdef PACKET_TRUNCATION_CHECK /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ @@ -1003,13 +1011,13 @@ process_incoming_tun (struct context *c) void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf) { - if (!c->options.mssfix) + if (!c->options.ce.mssfix) flags &= ~PIPV4_MSSFIX; #if PASSTOS_CAPABILITY if (!c->options.passtos) flags &= ~PIPV4_PASSTOS; #endif - if (!c->options.route_gateway_via_dhcp || !route_list_default_gateway_needed (c->c1.route_list)) + if (!c->options.route_gateway_via_dhcp) flags &= ~PIPV4_EXTRACT_DHCP_ROUTER; if (buf->len > 0) @@ -1037,12 +1045,20 @@ process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf) if (flags & PIPV4_MSSFIX) mss_fixup (&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) { const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf); if (dhcp_router) - route_list_add_default_gateway (c->c1.route_list, c->c2.es, dhcp_router); + route_list_add_vpn_gateway (c->c1.route_list, c->c2.es, dhcp_router); } } } @@ -1078,7 +1094,7 @@ process_outgoing_link (struct context *c) * Let the traffic shaper know how many bytes * we wrote. */ -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER if (c->options.shaper) shaper_wrote_bytes (&c->c2.shaper, BLEN (&c->c2.to_link) + datagram_overhead (c->options.ce.proto)); @@ -1132,6 +1148,10 @@ process_outgoing_link (struct context *c) c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local); c->c2.link_write_bytes += size; link_write_bytes_global += size; +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->link_write_bytes = link_write_bytes_global; +#endif #ifdef ENABLE_MANAGEMENT if (management) { @@ -1199,7 +1219,7 @@ process_outgoing_tun (struct context *c) * The --mssfix option requires * us to examine the IPv4 header. */ - process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_OUTGOING, &c->c2.to_tun); + process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_CLIENT_NAT|PIPV4_OUTGOING, &c->c2.to_tun); if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (&c->c2.frame)) { @@ -1278,7 +1298,7 @@ pre_select (struct context *c) c->c2.timeval.tv_usec = 0; #if defined(WIN32) - if (check_debug_level (D_TAP_WIN32_DEBUG)) + if (check_debug_level (D_TAP_WIN_DEBUG)) { c->c2.timeval.tv_sec = 1; if (tuntap_defined (c->c1.tuntap)) @@ -1363,7 +1383,7 @@ io_wait_dowork (struct context *c, const unsigned int flags) * quota, don't send -- instead compute the delay we must wait * until it will be OK to send the packet. */ -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER int delay = 0; /* set traffic shaping delay in microseconds */ @@ -1378,9 +1398,9 @@ io_wait_dowork (struct context *c, const unsigned int flags) { shaper_soonest_event (&c->c2.timeval, delay); } -#else /* HAVE_GETTIMEOFDAY */ +#else /* ENABLE_FEATURE_SHAPER */ socket |= EVENT_WRITE; -#endif /* HAVE_GETTIMEOFDAY */ +#endif /* ENABLE_FEATURE_SHAPER */ } else { diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h new file mode 100644 index 0000000..0f829bd --- /dev/null +++ b/src/openvpn/forward.h @@ -0,0 +1,242 @@ +/* + * 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 + */ + + +/** + * @file + * Interface functions to the internal and external multiplexers. + */ + + +#ifndef FORWARD_H +#define FORWARD_H + +#include "openvpn.h" +#include "occ.h" +#include "ping.h" + +#define TUN_OUT(c) (BLEN(&(c)->c2.to_tun) > 0) +#define LINK_OUT(c) (BLEN(&(c)->c2.to_link) > 0) +#define ANY_OUT(c) (TUN_OUT(c) || LINK_OUT(c)) + +#ifdef ENABLE_FRAGMENT +#define TO_LINK_FRAG(c) ((c)->c2.fragment && fragment_outgoing_defined ((c)->c2.fragment)) +#else +#define TO_LINK_FRAG(c) (false) +#endif + +#define TO_LINK_DEF(c) (LINK_OUT(c) || TO_LINK_FRAG(c)) + +#define IOW_TO_TUN (1<<0) +#define IOW_TO_LINK (1<<1) +#define IOW_READ_TUN (1<<2) +#define IOW_READ_LINK (1<<3) +#define IOW_SHAPER (1<<4) +#define IOW_CHECK_RESIDUAL (1<<5) +#define IOW_FRAG (1<<6) +#define IOW_MBUF (1<<7) +#define IOW_READ_TUN_FORCE (1<<8) +#define IOW_WAIT_SIGNAL (1<<9) + +#define IOW_READ (IOW_READ_TUN|IOW_READ_LINK) + + +void pre_select (struct context *c); +void process_io (struct context *c); + +const char *wait_status_string (struct context *c, struct gc_arena *gc); +void show_wait_status (struct context *c); + + +/**********************************************************************/ +/** + * Process a data channel packet that will be sent through a VPN tunnel. + * @ingroup data_control + * + * This function controls the processing of a data channel packet which + * will be sent through a VPN tunnel to a remote OpenVPN peer. It's + * general structure is as follows: + * - Check that the client authentication has succeeded; if not, drop the + * packet. + * - If the \a comp_frag argument is true: + * - Call \c lzo_compress() of the \link Data Channel Compression + * module\endlink to (possibly) compress the packet. + * - Call \c fragment_outgoing() of the \link Data Channel Fragmentation + * module\endlink to (possibly) fragment the packet. + * - Activate the \link Data Channel Crypto module\endlink to perform + * security operations on the packet. + * - Call \c tls_pre_encrypt() to choose the appropriate security + * parameters for this packet. + * - Call \c openvpn_encrypt() to encrypt and HMAC signed the packet. + * - Call \c tls_post_encrypt() to prepend the one-byte OpenVPN header + * and do some TLS accounting. + * - Place the resulting packet in \c c->c2.to_link so that it can be sent + * over the external network interface to its remote destination by the + * \link external_multiplexer External Multiplexer\endlink. + * + * @param c - The context structure of the VPN tunnel associated with this + * packet. + * @param comp_frag - Whether to do packet compression and fragmentation. + * This flag is set to true the first time a packet is processed. If + * the packet then gets fragmented, this function will be called again + * once for each remaining fragment with this parameter set to false. + */ +void encrypt_sign (struct context *c, bool comp_frag); + + +/**********************************************************************/ +/** + * Read a packet from the external network interface. + * @ingroup external_multiplexer + * + * The packet read from the external network interface is stored in \c + * c->c2.buf and its source address in \c c->c2.from. If an error + * occurred, the length of \c c->c2.buf will be 0. + * + * OpenVPN running as client or as UDP server only has a single external + * network socket, so this function can be called with the single (client + * mode) or top level (UDP server) context as its argument. OpenVPN + * running as TCP server, on the other hand, has a network socket for each + * active VPN tunnel. In that case this function must be called with the + * context associated with the appropriate VPN tunnel for which data is + * available to be read. + * + * @param c - The context structure which contains the external + * network socket from which to read incoming packets. + */ +void read_incoming_link (struct context *c); + + +/** + * Process a packet read from the external network interface. + * @ingroup external_multiplexer + * + * This function controls 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. + * - Call \c tls_pre_decrypt(), which splits data channel and control + * channel packets: + * - If a data channel packet, the appropriate security parameters are + * loaded. + * - If a control channel packet, this function process is it and + * afterwards sets the packet's buffer length to 0, so that the data + * channel processing steps below will ignore it. + * - 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. + * - Call \c fragment_incoming() of the \link fragmentation Data Channel + * Fragmentation module\endlink to reassemble the packet if it's + * fragmented. + * - Call \c lzo_decompress() of the \link compression Data Channel + * Compression module\endlink to decompress the packet if it's + * compressed. + * - Place the resulting packet in \c c->c2.to_tun so that it can be sent + * over the virtual tun/tap network interface to its local destination + * by the \link internal_multiplexer Internal Multiplexer\endlink. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ +void process_incoming_link (struct context *c); + + +/** + * Write a packet to the external network interface. + * @ingroup external_multiplexer + * + * This function writes the packet stored in \c c->c2.to_link to the + * external network device contained within \c c->c1.link_socket. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ +void process_outgoing_link (struct context *c); + + +/**************************************************************************/ +/** + * Read a packet from the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function reads a packet from the virtual tun/tap network device \c + * c->c1.tuntap and stores it in \c c->c2.buf. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure in which to store the received + * packet. + */ +void read_incoming_tun (struct context *c); + + +/** + * Process a packet read from the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function calls \c encrypt_sign() of the \link data_control Data + * Channel Control module\endlink to process the packet. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ +void process_incoming_tun (struct context *c); + + +/** + * Write a packet to the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function writes the packet stored in \c c->c2.to_tun to the + * virtual tun/tap network device \c c->c1.tuntap. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with + * the packet. + */ +void process_outgoing_tun (struct context *c); + + +/**************************************************************************/ + +bool send_control_channel_string (struct context *c, const char *str, int msglevel); + +#define PIPV4_PASSTOS (1<<0) +#define PIPV4_MSSFIX (1<<1) +#define PIPV4_OUTGOING (1<<2) +#define PIPV4_EXTRACT_DHCP_ROUTER (1<<3) +#define PIPV4_CLIENT_NAT (1<<4) + +void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf); + +#if P2MP +void schedule_exit (struct context *c, const int n_seconds, const int signal); +#endif + +#endif /* FORWARD_H */ diff --git a/fragment.c b/src/openvpn/fragment.c index 5ef3a47..7ad1d61 100644 --- a/fragment.c +++ b/src/openvpn/fragment.c @@ -22,6 +22,12 @@ * 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_FRAGMENT diff --git a/src/openvpn/fragment.h b/src/openvpn/fragment.h new file mode 100644 index 0000000..866573b --- /dev/null +++ b/src/openvpn/fragment.h @@ -0,0 +1,479 @@ +/* + * 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-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 FRAGMENT_H +#define FRAGMENT_H + +/** + * @file + * Data Channel Fragmentation module header file. + */ + + +#ifdef ENABLE_FRAGMENT + +/** + * @addtogroup fragmentation + * @{ + */ + + +#include "common.h" +#include "buffer.h" +#include "interval.h" +#include "mtu.h" +#include "shaper.h" +#include "error.h" + + +#define N_FRAG_BUF 25 + /**< Number of packet buffers for + * reassembling incoming fragmented + * packets. */ + +#define FRAG_TTL_SEC 10 + /**< Time-to-live in seconds for a %fragment. */ + +#define FRAG_WAKEUP_INTERVAL 5 + /**< Interval in seconds between calls to + * wakeup code. */ + +/**************************************************************************/ +/** + * Structure for reassembling one incoming fragmented packet. + */ +struct fragment { + bool defined; /**< Whether reassembly is currently + * taking place in this structure. */ + + int max_frag_size; /**< Maximum size of each %fragment. */ + +# define FRAG_MAP_MASK 0xFFFFFFFF + /**< Mask for reassembly map. */ +# define MAX_FRAGS 32 /**< Maximum number of fragments per packet. */ + unsigned int map; + /**< Reassembly map for recording which + * fragments have been received. + * + * A bit array where each bit + * corresponds to a %fragment. A 1 bit + * in element n means that the %fragment + * n has been received. Needs to have + * at least \c MAX_FRAGS bits. */ + + time_t timestamp; /**< Timestamp for time-to-live purposes. */ + + struct buffer buf; /**< Buffer in which received datagrams + * are reassembled. */ +}; + + +/** + * List of fragment structures for reassembling multiple incoming packets + * concurrently. + */ +struct fragment_list { + int seq_id; /**< Highest fragmentation sequence ID of + * the packets currently being + * reassembled. */ + int index; /**< Index of the packet being reassembled + * with the highest fragmentation + * sequence ID into the \c + * fragment_list.fragments array. */ + +/** Array of reassembly structures, each can contain one whole packet. + * + * The fragmentation sequence IDs of the packets being reassembled in + * this array are linearly increasing. \c + * fragment_list.fragments[fragment_list.index] has an ID of \c + * fragment_list.seq_id. This means that one of these \c fragment_list + * structures can at any one time contain at most packets with the + * fragmentation sequence IDs in the range \c fragment_list.seq_id \c - + * \c N_FRAG_BUF \c + \c 1 to \c fragment_list.seq_id, inclusive. + */ + struct fragment fragments[N_FRAG_BUF]; +}; + + +/** + * Fragmentation and reassembly state for one VPN tunnel instance. + * + * This structure contains all the state necessary for sending and + * receiving fragmented data channel packets associated with one VPN + * tunnel. + * + * The fragmented packet currently being sent to a remote OpenVPN peer is + * stored in \c fragment_master.outgoing. It is copied into that buffer + * by the \c fragment_outgoing() function and the remaining parts to be + * sent can be retrieved by successive calls to \c + * fragment_ready_to_send(). + * + * The received packets currently being reassembled are stored in the \c + * fragment_master.incoming array of \c fragment structures. The \c + * fragment_incoming() function adds newly received parts into this array + * and returns the whole packets once reassembly is complete. + */ +struct fragment_master { + struct event_timeout wakeup; /**< Timeout structure used by the main + * event loop to know when to do + * fragmentation housekeeping. */ + bool received_os_mtu_hint; /**< Whether the operating system has + * explicitly recommended an MTU value. */ +# define N_SEQ_ID 256 + /**< One more than the maximum fragment + * sequence ID, above which the IDs wrap + * to zero. Should be a power of 2. */ + int outgoing_seq_id; /**< Fragment sequence ID of the current + * fragmented packet waiting to be sent. + * + * All parts of a fragmented packet + * share the same sequence ID, so that + * the remote OpenVPN peer can determine + * which parts belong to which original + * packet. */ +# define MAX_FRAG_PKT_SIZE 65536 + /**< (Not used) Maximum packet size before + * fragmenting. */ + int outgoing_frag_size; /**< Size in bytes of each part to be + * sent, except for the last part which + * may be smaller. + * + * This value is computed by the \c + * optimal_fragment_size() function. Its + * value is sent to the remote peer in + * the fragmentation header of the last + * part (i.e. with %fragment type \c + * FRAG_YES_LAST) using the \c + * FRAG_SIZE_MASK and \c FRAG_SIZE_SHIFT + * bits. */ + int outgoing_frag_id; /**< The fragment ID of the next part to + * be sent. Must have a value between 0 + * and \c MAX_FRAGS-1. */ + struct buffer outgoing; /**< Buffer containing the remaining parts + * of the fragmented packet being sent. */ + struct buffer outgoing_return; + /**< Buffer used by \c + * fragment_ready_to_send() to return a + * part to send. */ + + struct fragment_list incoming; + /**< List of structures for reassembling + * incoming packets. */ +}; + + +/**************************************************************************/ +/** @name Fragment header + * @todo Add description of %fragment header format. + *//** @{ *//*************************************/ + +typedef uint32_t fragment_header_type; + /**< Fragmentation information is stored in + * a 32-bit packet header. */ + +#define hton_fragment_header_type(x) htonl(x) + /**< Convert a fragment_header_type from + * host to network order. */ + +#define ntoh_fragment_header_type(x) ntohl(x) + /**< Convert a \c fragment_header_type + * from network to host order. */ + +#define FRAG_TYPE_MASK 0x00000003 + /**< Bit mask for %fragment type info. */ +#define FRAG_TYPE_SHIFT 0 /**< Bit shift for %fragment type info. */ + +#define FRAG_WHOLE 0 /**< Fragment type indicating packet is + * whole. */ +#define FRAG_YES_NOTLAST 1 /**< Fragment type indicating packet is + * part of a fragmented packet, but not + * the last part in the sequence. */ +#define FRAG_YES_LAST 2 /**< Fragment type indicating packet is + * the last part in the sequence of + * parts. */ +#define FRAG_TEST 3 /**< Fragment type not implemented yet. + * In the future might be used as a + * control packet for establishing MTU + * size. */ + +#define FRAG_SEQ_ID_MASK 0x000000ff + /**< Bit mask for %fragment sequence ID. */ +#define FRAG_SEQ_ID_SHIFT 2 /**< Bit shift for %fragment sequence ID. */ + +#define FRAG_ID_MASK 0x0000001f + /**< Bit mask for %fragment ID. */ +#define FRAG_ID_SHIFT 10 + /**< Bit shift for %fragment ID. */ + +/* + * FRAG_SIZE 14 bits + * + * IF FRAG_YES_LAST (FRAG_SIZE): + * The max size of a %fragment. If a %fragment is not the last %fragment in the packet, + * then the %fragment size is guaranteed to be equal to the max %fragment size. Therefore, + * max_frag_size is only sent over the wire if FRAG_LAST is set. Otherwise it is assumed + * to be the actual %fragment size received. + */ +#define FRAG_SIZE_MASK 0x00003fff + /**< Bit mask for %fragment size. */ +#define FRAG_SIZE_SHIFT 15 + /**< Bit shift for %fragment size. */ +#define FRAG_SIZE_ROUND_SHIFT 2 /**< Bit shift for %fragment size rounding. */ +#define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1) + /**< Bit mask for %fragment size rounding. */ + +/* + * FRAG_EXTRA 16 bits + * + * IF FRAG_WHOLE or FRAG_YES_NOTLAST, these 16 bits are available (not currently used) + */ +#define FRAG_EXTRA_MASK 0x0000ffff + /**< Bit mask for extra bits. */ +#define FRAG_EXTRA_SHIFT 15 + /**< Bit shift for extra bits. */ + +/** @} name Fragment header *//********************************************/ + + +/**************************************************************************/ +/** @name Functions for initialization and cleanup *//** @{ *//************/ + +/** + * Allocate and initialize a \c fragment_master structure. + * + * This function also modifies the \a frame packet geometry parameters to + * include space for the fragmentation header. + * + * @param frame - The packet geometry parameters for this VPN + * tunnel, modified by this function to include the + * fragmentation header. + * + * @return A pointer to the new \c fragment_master structure. + */ +struct fragment_master *fragment_init (struct frame *frame); + + +/** + * Allocate internal packet buffers for a \c fragment_master structure. + * + * @param f - The \c fragment_master structure for which to + * allocate the internal buffers. + * @param frame - The packet geometry parameters for this VPN + * tunnel, used to determine how much memory to + * allocate for each packet buffer. + */ +void fragment_frame_init (struct fragment_master *f, const struct frame *frame); + + +/** + * Free a \c fragment_master structure and its internal packet buffers. + * + * @param f - The \c fragment_master structure to free. + */ +void fragment_free (struct fragment_master *f); + +/** @} name Functions for initialization and cleanup *//*******************/ + + +/**************************************************************************/ +/** @name Functions for processing packets received from a remote OpenVPN peer */ +/** @{ */ + +/** + * Process an incoming packet, which may or may not be fragmented. + * + * This function inspects the fragmentation header of the incoming packet + * and processes the packet accordingly. Depending on the %fragment type + * bits (\c FRAG_TYPE_MASK and \c FRAG_TYPE_SHIFT) the packet is processed + * in the following ways: + * - \c FRAG_WHOLE: the packet is not fragmented, and this function does + * not modify its contents, except for removing the fragmentation + * header. + * - \c FRAG_YES_NOTLAST or \c FRAG_YES_LAST: the packet is part of a + * fragmented packet. This function copies the packet into an internal + * reassembly buffer. If the incoming part completes the packet being + * reassembled, the \a buf argument is modified to point to the fully + * reassembled packet. If, on the other hand, reassembly is not yet + * complete, then the the \a buf buffer is set to empty. + * - Any other value: error. + * + * If an error occurs during processing, an error message is logged and + * the length of \a buf is set to zero. + * + * @param f - The \c fragment_master structure for this VPN + * tunnel. + * @param buf - A pointer to the buffer structure containing the + * incoming packet. This pointer will have been + * modified on return either to point to a + * completely reassembled packet, or to have length + * set to zero if reassembly is not yet complete. + * @param frame - The packet geometry parameters for this VPN + * tunnel. + * + * @return Void.\n On return, the \a buf argument will point to a buffer. + * The buffer will have nonzero length if the incoming packet passed + * to this function was whole and unfragmented, or if it was the final + * part of a fragmented packet thereby completing reassembly. On the + * other hand, the buffer will have a length of zero if the incoming + * packet was part of a fragmented packet and reassembly is not yet + * complete. If an error occurs during processing, the buffer length + * is also set to zero. + */ +void fragment_incoming (struct fragment_master *f, struct buffer *buf, + const struct frame* frame); + +/** @} name Functions for processing packets received from a VPN tunnel */ + + +/**************************************************************************/ +/** @name Functions for processing packets to be sent to a remote OpenVPN peer */ +/** @{ */ + +/** + * Process an outgoing packet, which may or may not need to be fragmented. + * + * This function inspects the outgoing packet, determines whether it needs + * to be fragmented, and processes it accordingly. + * + * Depending on the size of the outgoing packet and the packet geometry + * parameters for the VPN tunnel, the packet will or will not be + * fragmented. + * @li Packet size is less than or equal to the maximum packet size for + * this VPN tunnel: fragmentation is not necessary. The \a buf + * argument points to a buffer containing the unmodified outgoing + * packet with a fragmentation header indicating the packet is whole + * (FRAG_WHOLE) prepended. + * @li Packet size is greater than the maximum packet size for this VPN + * tunnel: fragmentation is necessary. The original outgoing packet + * is copied into an internal buffer for fragmentation. The \a buf + * argument is modified to point to the first part of the fragmented + * packet. The remaining parts remain stored in the internal buffer, + * and can be retrieved using the \c fragment_ready_to_send() + * function. + * + * If an error occurs during processing, an error message is logged and + * the length of \a buf is set to zero. + * + * @param f - The \c fragment_master structure for this VPN + * tunnel. + * @param buf - A pointer to the buffer structure containing the + * outgoing packet. This pointer will be modified + * to point to a whole unfragmented packet or to the + * first part of a fragmented packet on return. + * @param frame - The packet geometry parameters for this VPN + * tunnel. + * + * @return Void.\n On return, the \a buf argument will point to a buffer. + * This buffer contains either the whole original outgoing packet if + * fragmentation was not necessary, or the first part of the + * fragmented outgoing packet if fragmentation was necessary. In both + * cases a fragmentation header will have been prepended to inform the + * remote peer how to handle the packet. + */ +void fragment_outgoing (struct fragment_master *f, struct buffer *buf, + const struct frame* frame); + +/** + * Check whether outgoing fragments are ready to be send, and if so make + * one available. + * + * This function checks whether the internal buffer for fragmenting + * outgoing packets contains any unsent parts. If it does not, meaning + * there is nothing waiting to be sent, it returns false. Otherwise there + * are parts ready to be sent, and it returns true. In that case it also + * modifies the \a buf argument to point to a buffer containing the next + * part to be sent. + * + * @param f - The \a fragment_master structure for this VPN + * tunnel. + * @param buf - A pointer to a buffer structure which on return, + * if there are parts waiting to be sent, will point + * to the next part to be sent. + * @param frame - The packet geometry parameters for this VPN + * tunnel. + * + * @return + * @li True, if an outgoing packet has been fragmented and not all parts + * have been sent yet. In this case this function will modify the \a + * buf argument to point to a buffer containing the next part to be + * sent. + * @li False, if there are no outgoing fragmented parts waiting to be + * sent. + */ +bool fragment_ready_to_send (struct fragment_master *f, struct buffer *buf, + const struct frame* frame); + +/** + * Check whether a \c fragment_master structure contains fragments ready + * to be sent. + * + * @param f - The \c fragment_master structure for this VPN + * tunnel. + * + * @return + * @li True, if there are one or more fragments ready to be sent. + * @li False, otherwise. + */ +static inline bool +fragment_outgoing_defined (struct fragment_master *f) +{ + return f->outgoing.len > 0; +} + +/** @} name Functions for processing packets going out through a VPN tunnel */ + + +void fragment_wakeup (struct fragment_master *f, struct frame *frame); + + +/**************************************************************************/ +/** @name Functions for regular housekeeping *//** @{ *//******************/ + +/** + * Perform housekeeping of a \c fragment_master structure. + * + * Housekeeping includes scanning incoming packet reassembly buffers for + * packets which have not yet been reassembled completely but are already + * older than their time-to-live. + * + * @param f - The \c fragment_master structure for this VPN + * tunnel. + * @param frame - The packet geometry parameters for this VPN + * tunnel. + */ +static inline void +fragment_housekeeping (struct fragment_master *f, struct frame *frame, struct timeval *tv) +{ + if (event_timeout_trigger (&f->wakeup, tv, ETT_DEFAULT)) + fragment_wakeup (f, frame); +} + +/** @} name Functions for regular housekeeping *//*************************/ + + +/** @} addtogroup fragmentation *//****************************************/ + + +#endif +#endif diff --git a/gremlin.c b/src/openvpn/gremlin.c index c7c0206..f0aa7f6 100644 --- a/gremlin.c +++ b/src/openvpn/gremlin.c @@ -27,6 +27,12 @@ * network outages when the --gremlin option is used. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #ifdef ENABLE_DEBUG diff --git a/gremlin.h b/src/openvpn/gremlin.h index c0aeab1..c0aeab1 100644 --- a/gremlin.h +++ b/src/openvpn/gremlin.h diff --git a/helper.c b/src/openvpn/helper.c index a9d7fd9..d9eef03 100644 --- a/helper.c +++ b/src/openvpn/helper.c @@ -22,6 +22,12 @@ * 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" #include "forward.h" @@ -142,6 +148,63 @@ helper_client_server (struct options *o) #if P2MP #if P2MP_SERVER + +/* + * Get tun/tap/null device type + */ + const int dev = dev_type_enum (o->dev, o->dev_type); + const int topology = o->topology; + + /* + * + * HELPER DIRECTIVE for IPv6 + * + * server-ipv6 2001:db8::/64 + * + * EXPANDS TO: + * + * tun-ipv6 + * push "tun-ipv6" + * ifconfig-ipv6 2001:db8::1 2001:db8::2 + * if !nopool: + * ifconfig-ipv6-pool 2001:db8::1:0/64 + * + */ + if ( o->server_ipv6_defined ) + { + if ( ! o->server_defined ) + { + msg (M_USAGE, "--server-ipv6 must be used together with --server"); + } + if ( o->server_flags & SF_NOPOOL ) + { + msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" ); + } + if ( o->ifconfig_ipv6_pool_defined ) + { + msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly"); + } + + /* local ifconfig is "base address + 1" and "+2" */ + o->ifconfig_ipv6_local = + print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc ); + o->ifconfig_ipv6_remote = + print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc ); + o->ifconfig_ipv6_netbits = o->server_netbits_ipv6; + + /* pool starts at "base address + 0x1000" - leave enough room */ + ASSERT( o->server_netbits_ipv6 <= 112 ); /* want 16 bits */ + + o->ifconfig_ipv6_pool_defined = true; + o->ifconfig_ipv6_pool_base = + 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 ); + } + /* * * HELPER DIRECTIVE: @@ -171,12 +234,6 @@ helper_client_server (struct options *o) * push "route-gateway 10.8.0.1" */ - /* - * Get tun/tap/null device type - */ - const int dev = dev_type_enum (o->dev, o->dev_type); - const int topology = o->topology; - if (o->server_defined) { int netbits = -2; diff --git a/helper.h b/src/openvpn/helper.h index 444969c..444969c 100644 --- a/helper.h +++ b/src/openvpn/helper.h diff --git a/httpdigest.c b/src/openvpn/httpdigest.c index 90abc6a..78b8344 100644 --- a/httpdigest.c +++ b/src/openvpn/httpdigest.c @@ -22,6 +22,12 @@ * 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 PROXY_DIGEST_AUTH @@ -65,26 +71,28 @@ DigestCalcHA1( OUT HASHHEX SessionKey ) { - MD5_CTX Md5Ctx; HASH HA1; + md_ctx_t md5_ctx; + const md_kt_t *md5_kt = md_kt_get("MD5"); - MD5_Init(&Md5Ctx); - MD5_Update(&Md5Ctx, pszUserName, strlen(pszUserName)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszRealm, strlen(pszRealm)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszPassword, strlen(pszPassword)); - MD5_Final(HA1, &Md5Ctx); + md_ctx_init(&md5_ctx, md5_kt); + md_ctx_update(&md5_ctx, pszUserName, strlen(pszUserName)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszRealm, strlen(pszRealm)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszPassword, strlen(pszPassword)); + md_ctx_final(&md5_ctx, HA1); if (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0) { - MD5_Init(&Md5Ctx); - MD5_Update(&Md5Ctx, HA1, HASHLEN); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); - MD5_Final(HA1, &Md5Ctx); + md_ctx_init(&md5_ctx, md5_kt); + md_ctx_update(&md5_ctx, HA1, HASHLEN); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszNonce, strlen(pszNonce)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszCNonce, strlen(pszCNonce)); + md_ctx_final(&md5_ctx, HA1); }; + md_ctx_cleanup(&md5_ctx); CvtHex(HA1, SessionKey); } @@ -102,41 +110,44 @@ DigestCalcResponse( OUT HASHHEX Response /* request-digest or response-digest */ ) { - MD5_CTX Md5Ctx; HASH HA2; HASH RespHash; HASHHEX HA2Hex; - // calculate H(A2) - MD5_Init(&Md5Ctx); - MD5_Update(&Md5Ctx, pszMethod, strlen(pszMethod)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri)); + md_ctx_t md5_ctx; + const md_kt_t *md5_kt = md_kt_get("MD5"); + + /* calculate H(A2) */ + md_ctx_init(&md5_ctx, md5_kt); + md_ctx_update(&md5_ctx, pszMethod, strlen(pszMethod)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszDigestUri, strlen(pszDigestUri)); if (strcasecmp(pszQop, "auth-int") == 0) { - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, HEntity, HASHHEXLEN); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, HEntity, HASHHEXLEN); }; - MD5_Final(HA2, &Md5Ctx); + md_ctx_final(&md5_ctx, HA2); CvtHex(HA2, HA2Hex); - // calculate response - MD5_Init(&Md5Ctx); - MD5_Update(&Md5Ctx, HA1, HASHHEXLEN); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce)); - MD5_Update(&Md5Ctx, ":", 1); + /* calculate response */ + md_ctx_init(&md5_ctx, md5_kt); + md_ctx_update(&md5_ctx, HA1, HASHHEXLEN); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszNonce, strlen(pszNonce)); + md_ctx_update(&md5_ctx, ":", 1); if (*pszQop) { - MD5_Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); - MD5_Update(&Md5Ctx, ":", 1); - MD5_Update(&Md5Ctx, pszQop, strlen(pszQop)); - MD5_Update(&Md5Ctx, ":", 1); + md_ctx_update(&md5_ctx, pszNonceCount, strlen(pszNonceCount)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszCNonce, strlen(pszCNonce)); + md_ctx_update(&md5_ctx, ":", 1); + md_ctx_update(&md5_ctx, pszQop, strlen(pszQop)); + md_ctx_update(&md5_ctx, ":", 1); }; - MD5_Update(&Md5Ctx, HA2Hex, HASHHEXLEN); - MD5_Final(RespHash, &Md5Ctx); + md_ctx_update(&md5_ctx, HA2Hex, HASHHEXLEN); + md_ctx_final(&md5_ctx, RespHash); + md_ctx_cleanup(&md5_ctx); CvtHex(RespHash, Response); } diff --git a/httpdigest.h b/src/openvpn/httpdigest.h index 8423841..8423841 100644 --- a/httpdigest.h +++ b/src/openvpn/httpdigest.h diff --git a/init.c b/src/openvpn/init.c index d47a4ef..25d8225 100644 --- a/init.c +++ b/src/openvpn/init.c @@ -22,6 +22,12 @@ * 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" #include "win32.h" @@ -36,6 +42,7 @@ #include "ps.h" #include "lladdr.h" #include "ping.h" +#include "mstats.h" #include "memdbg.h" @@ -96,115 +103,187 @@ update_options_ce_post (struct options *options) */ if (options->pull && options->ping_rec_timeout_action == PING_UNDEF - && options->ce.proto == PROTO_UDPv4) + && proto_is_dgram(options->ce.proto)) { options->ping_rec_timeout = PRE_PULL_INITIAL_PING_RESTART; options->ping_rec_timeout_action = PING_RESTART; } #endif -#ifdef USE_CRYPTO - /* - * Don't use replay window for TCP mode (i.e. require that packets be strictly in sequence). - */ - if (link_socket_proto_connection_oriented (options->ce.proto)) - options->replay_window = options->replay_time = 0; -#endif } -#if HTTP_PROXY_FALLBACK - +#ifdef ENABLE_MANAGEMENT static bool -ce_http_proxy_fallback_defined(const struct context *c) +management_callback_proxy_cmd (void *arg, const char **p) { - const struct connection_list *l = c->options.connection_list; - if (l && l->current == 0) - { - int i; - for (i = 0; i < l->len; ++i) - { - const struct connection_entry *ce = l->array[i]; - if (ce->flags & CE_HTTP_PROXY_FALLBACK) - return true; - } + struct context *c = arg; + struct connection_entry *ce = &c->options.ce; + struct gc_arena *gc = &c->c2.gc; + bool ret = false; + + update_time(); + if (streq (p[1], "NONE")) + 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) + { + 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->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; + ret = true; +#endif + } } - return false; + else + msg (M_WARN, "Bad proxy command"); + + ce->flags &= ~CE_MAN_QUERY_PROXY; + + return ret; } -static void -ce_http_proxy_fallback_start(struct context *c, const char *remote_ip_hint) +static bool +ce_management_query_proxy (struct context *c) { const struct connection_list *l = c->options.connection_list; - if (l) + struct connection_entry *ce = &c->options.ce; + struct gc_arena gc; + bool ret = true; + + update_time(); + if (management) { - int i; - for (i = 0; i < l->len; ++i) - { - struct connection_entry *ce = l->array[i]; - if (ce->flags & CE_HTTP_PROXY_FALLBACK) - { - ce->http_proxy_options = NULL; - ce->ce_http_proxy_fallback_timestamp = 0; - if (!remote_ip_hint) - remote_ip_hint = ce->remote; - } - } + gc = gc_new (); + struct buffer out = alloc_buf_gc (256, &gc); + buf_printf (&out, ">PROXY:%u,%s,%s", (l ? l->current : 0) + 1, + (proto_is_udp (ce->proto) ? "UDP" : "TCP"), np (ce->remote)); + management_notify_generic (management, BSTR (&out)); + ce->flags |= CE_MAN_QUERY_PROXY; + while (ce->flags & CE_MAN_QUERY_PROXY) + { + management_event_loop_n_seconds (management, 1); + if (IS_SIG (c)) + { + ret = false; + break; + } + } + gc_free (&gc); } - if (management) - management_http_proxy_fallback_notify(management, "NEED_LATER", remote_ip_hint); + return ret; } + static bool -ce_http_proxy_fallback (struct context *c, volatile const struct connection_entry *ce) +management_callback_remote_cmd (void *arg, const char **p) { - const int proxy_info_expire = 120; /* seconds before proxy info expires */ - - update_time(); - if (management) + struct context *c = (struct context *) arg; + struct connection_entry *ce = &c->options.ce; + int ret = false; + if (p[1] && ((ce->flags>>CE_MAN_QUERY_REMOTE_SHIFT)&CE_MAN_QUERY_REMOTE_MASK) == CE_MAN_QUERY_REMOTE_QUERY) { - if (!ce->ce_http_proxy_fallback_timestamp) + int flags = 0; + if (!strcmp(p[1], "ACCEPT")) { - management_http_proxy_fallback_notify(management, "NEED_NOW", NULL); - while (!ce->ce_http_proxy_fallback_timestamp) + flags = CE_MAN_QUERY_REMOTE_ACCEPT; + ret = true; + } + else if (!strcmp(p[1], "SKIP")) + { + flags = CE_MAN_QUERY_REMOTE_SKIP; + ret = true; + } + 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)) { - management_event_loop_n_seconds (management, 1); - if (IS_SIG (c)) - return false; + struct remote_host_store *rhs = c->options.rh_store; + if (!rhs) + { + ALLOC_OBJ_CLEAR_GC (rhs, struct remote_host_store, &c->options.gc); + c->options.rh_store = rhs; + } + strncpynt(rhs->host, p[2], RH_HOST_LEN); + ce->remote = rhs->host; + ce->remote_port = port; + flags = CE_MAN_QUERY_REMOTE_MOD; + ret = true; } } - return (now < ce->ce_http_proxy_fallback_timestamp + proxy_info_expire && ce->http_proxy_options); + if (ret) + { + ce->flags &= ~(CE_MAN_QUERY_REMOTE_MASK<<CE_MAN_QUERY_REMOTE_SHIFT); + ce->flags |= ((flags&CE_MAN_QUERY_REMOTE_MASK)<<CE_MAN_QUERY_REMOTE_SHIFT); + } } - return false; + return ret; } static bool -management_callback_http_proxy_fallback_cmd (void *arg, const char *server, const char *port, const char *flags) +ce_management_query_remote (struct context *c, const char *remote_ip_hint) { - struct context *c = (struct context *) arg; - const struct connection_list *l = c->options.connection_list; - int ret = false; - struct http_proxy_options *ho = parse_http_proxy_fallback (c, server, port, flags, M_WARN); - + struct gc_arena gc = gc_new (); + volatile struct connection_entry *ce = &c->options.ce; + int ret = true; update_time(); - if (l) + if (management) { - int i; - for (i = 0; i < l->len; ++i) + 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)); + 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); + while (((ce->flags>>CE_MAN_QUERY_REMOTE_SHIFT) & CE_MAN_QUERY_REMOTE_MASK) == CE_MAN_QUERY_REMOTE_QUERY) { - struct connection_entry *ce = l->array[i]; - if (ce->flags & CE_HTTP_PROXY_FALLBACK) + management_event_loop_n_seconds (management, 1); + if (IS_SIG (c)) { - ce->http_proxy_options = ho; - ce->ce_http_proxy_fallback_timestamp = now; - ret = true; + ret = false; + break; } } } - + { + 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); return ret; } - -#endif +#endif /* ENABLE_MANAGEMENT */ /* * Initialize and possibly randomize connection list. @@ -212,7 +291,6 @@ management_callback_http_proxy_fallback_cmd (void *arg, const char *server, cons static void init_connection_list (struct context *c) { -#ifdef ENABLE_CONNECTION struct connection_list *l = c->options.connection_list; if (l) { @@ -233,32 +311,7 @@ init_connection_list (struct context *c) } } } -#endif -} - -#if 0 /* fixme -- disable for production */ -static void -show_connection_list (const struct connection_list *l) -{ - int i; - dmsg (M_INFO, "CONNECTION_LIST len=%d current=%d", - l->len, l->current); - for (i = 0; i < l->len; ++i) - { - dmsg (M_INFO, "[%d] %s:%d proto=%s http_proxy=%d", - i, - l->array[i]->remote, - l->array[i]->remote_port, - proto2ascii(l->array[i]->proto, true), - BOOL_CAST(l->array[i]->http_proxy_options)); - } -} -#else -static inline void -show_connection_list (const struct connection_list *l) -{ } -#endif /* * Increment to next connection entry @@ -266,7 +319,6 @@ show_connection_list (const struct connection_list *l) static void next_connection_entry (struct context *c) { -#ifdef ENABLE_CONNECTION struct connection_list *l = c->options.connection_list; if (l) { @@ -295,7 +347,6 @@ next_connection_entry (struct context *c) if (l->current == 0) newcycle = true; - show_connection_list(l); } ce = l->array[l->current]; @@ -303,35 +354,33 @@ next_connection_entry (struct context *c) if (c->options.remote_ip_hint && !l->n_cycles) remote_ip_hint = c->options.remote_ip_hint; -#if HTTP_PROXY_FALLBACK - if (newcycle && ce_http_proxy_fallback_defined(c)) - ce_http_proxy_fallback_start(c, remote_ip_hint); + if (ce->flags & CE_DISABLED) + ce_defined = false; - if (ce->flags & CE_HTTP_PROXY_FALLBACK) + c->options.ce = *ce; +#ifdef ENABLE_MANAGEMENT + if (ce_defined && management && management_query_remote_enabled(management)) { - ce_defined = ce_http_proxy_fallback(c, ce); + /* allow management interface to override connection entry details */ + ce_defined = ce_management_query_remote(c, remote_ip_hint); if (IS_SIG (c)) break; } + else #endif - - if (ce->flags & CE_DISABLED) - ce_defined = false; - - c->options.ce = *ce; - if (remote_ip_hint) c->options.ce.remote = remote_ip_hint; -#if 0 /* fixme -- disable for production, this code simulates a network where proxy fallback is the only method to reach the OpenVPN server */ - if (!(c->options.ce.flags & CE_HTTP_PROXY_FALLBACK)) - { - c->options.ce.remote = "10.10.0.1"; /* use an unreachable address here */ - } +#ifdef ENABLE_MANAGEMENT + 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); } -#endif update_options_ce_post (&c->options); } @@ -341,7 +390,7 @@ next_connection_entry (struct context *c) static void init_query_passwords (struct context *c) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) /* Certificate password input */ if (c->options.key_pass_file) pem_password_setup (c->options.key_pass_file); @@ -350,7 +399,13 @@ init_query_passwords (struct context *c) #if P2MP /* Auth user/pass input */ if (c->options.auth_user_pass_file) - auth_user_pass_setup (c->options.auth_user_pass_file); + { +#ifdef ENABLE_CLIENT_CR + auth_user_pass_setup (c->options.auth_user_pass_file, &c->options.sc_info); +#else + auth_user_pass_setup (c->options.auth_user_pass_file, NULL); +#endif + } #endif } @@ -399,11 +454,10 @@ init_proxy_dowork (struct context *c) uninit_proxy_dowork (c); #ifdef ENABLE_HTTP_PROXY - if (c->options.ce.http_proxy_options || c->options.auto_proxy_info) + if (c->options.ce.http_proxy_options) { /* Possible HTTP proxy user/pass input */ - c->c1.http_proxy = http_proxy_new (c->options.ce.http_proxy_options, - c->options.auto_proxy_info); + c->c1.http_proxy = http_proxy_new (c->options.ce.http_proxy_options); if (c->c1.http_proxy) { did_http = true; @@ -413,13 +467,12 @@ init_proxy_dowork (struct context *c) #endif #ifdef ENABLE_SOCKS - if (!did_http && (c->options.ce.socks_proxy_server || c->options.auto_proxy_info)) + 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.auto_proxy_info); + c->options.ce.socks_proxy_retry); if (c->c1.socks_proxy) { c->c1.socks_proxy_owned = true; @@ -521,7 +574,9 @@ init_port_share (struct context *c) if (!port_share && (c->options.port_share_host && c->options.port_share_port)) { port_share = port_share_open (c->options.port_share_host, - c->options.port_share_port); + c->options.port_share_port, + MAX_RW_SIZE_LINK (&c->c2.frame), + c->options.port_share_journal_dir); if (port_share == NULL) msg (M_FATAL, "Fatal error: Port sharing failed"); } @@ -534,8 +589,8 @@ init_static (void) { /* configure_path (); */ -#if defined(USE_CRYPTO) && defined(DMALLOC) - openssl_dmalloc_init (); +#if defined(ENABLE_CRYPTO) && defined(DMALLOC) + crypto_init_dmalloc(); #endif init_random_seed (); /* init random() function, only used as @@ -557,7 +612,7 @@ init_static (void) update_time (); -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO init_ssl_lib (); /* init PRNG used for IV generation */ @@ -601,6 +656,15 @@ init_static (void) return false; #endif +#ifdef TEST_GET_DEFAULT_GATEWAY + { + struct route_gateway_info rgi; + get_default_gateway(&rgi); + print_default_gateway(M_INFO, &rgi); + return false; + } +#endif + #ifdef GEN_PATH_TEST { struct gc_arena gc = gc_new (); @@ -641,14 +705,14 @@ init_static (void) uint8_t rndbuf[8]; int i; prng_init ("sha1", 16); - //prng_init (NULL, 0); + /*prng_init (NULL, 0);*/ const int factor = 1; for (i = 0; i < factor * 8; ++i) { #if 1 prng_bytes (rndbuf, sizeof (rndbuf)); #else - ASSERT(RAND_bytes (rndbuf, sizeof (rndbuf))); + ASSERT(rand_bytes (rndbuf, sizeof (rndbuf))); #endif printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc)); } @@ -712,13 +776,29 @@ init_static (void) } #endif +#ifdef MSTATS_TEST + { + int i; + mstats_open("/dev/shm/mstats.dat"); + for (i = 0; i < 30; ++i) + { + mmap_stats->n_clients += 1; + mmap_stats->link_write_bytes += 8; + mmap_stats->link_read_bytes += 16; + sleep(1); + } + mstats_close(); + return false; + } +#endif + return true; } void uninit_static (void) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO free_ssl_lib (); #endif @@ -730,7 +810,7 @@ uninit_static (void) close_port_share (); #endif -#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) show_tls_performance_stats (); #endif } @@ -759,8 +839,10 @@ init_verb_mute (struct context *c, unsigned int flags) void init_options_dev (struct options *options) { - if (!options->dev) - options->dev = openvpn_basename (options->dev_node); + if (!options->dev && options->dev_node) { + char *dev_node = strdup(options->dev_node); /* POSIX basename() implementaions may modify its arguments */ + options->dev = basename (dev_node); + } } bool @@ -769,9 +851,9 @@ print_openssl_info (const struct options *options) /* * OpenSSL info print mode? */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (options->show_ciphers || options->show_digests || options->show_engines -#ifdef USE_SSL +#ifdef ENABLE_SSL || options->show_tls_ciphers #endif ) @@ -782,7 +864,7 @@ print_openssl_info (const struct options *options) show_available_digests (); if (options->show_engines) show_available_engines (); -#ifdef USE_SSL +#ifdef ENABLE_SSL if (options->show_tls_ciphers) show_available_tls_ciphers (); #endif @@ -798,7 +880,7 @@ print_openssl_info (const struct options *options) bool do_genkey (const struct options * options) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (options->genkey) { int nbits_written; @@ -807,7 +889,7 @@ do_genkey (const struct options * options) "shared secret output file (--secret)"); if (options->mlock) /* should we disable paging? */ - do_mlockall (true); + platform_mlockall (true); nbits_written = write_key_file (2, options->shared_secret_file); @@ -826,16 +908,16 @@ do_genkey (const struct options * options) bool do_persist_tuntap (const struct options *options) { -#ifdef TUNSETPERSIST +#ifdef ENABLE_FEATURE_TUN_PERSIST if (options->persist_config) { /* sanity check on options for --mktun or --rmtun */ notnull (options->dev, "TUN/TAP device (--dev)"); if (options->ce.remote || options->ifconfig_local || options->ifconfig_remote_netmask -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO || options->shared_secret_file -#ifdef USE_SSL +#ifdef ENABLE_SSL || options->tls_server || options->tls_client #endif #endif @@ -843,7 +925,7 @@ do_persist_tuntap (const struct options *options) msg (M_FATAL|M_OPTERR, "options --mktun or --rmtun should only be used together with --dev"); tuncfg (options->dev, options->dev_type, options->dev_node, - options->tun_ipv6, options->persist_mode, + options->persist_mode, options->username, options->groupname, &options->tuntap_options); if (options->persist_mode && options->lladdr) set_lladdr(options->dev, options->lladdr, NULL); @@ -865,7 +947,7 @@ possibly_become_daemon (const struct options *options, const bool first_time) { ASSERT (!options->inetd); if (daemon (options->cd_dir != NULL, options->log) < 0) - msg (M_ERR, "daemon() failed"); + msg (M_ERR, "daemon() failed or unsupported"); restore_signal_state (); if (options->log) set_std_files_to_null (true); @@ -894,7 +976,7 @@ do_uid_gid_chroot (struct context *c, bool no_delay) if (c->options.chroot_dir) { if (no_delay) - do_chroot (c->options.chroot_dir); + platform_chroot (c->options.chroot_dir); else msg (M_INFO, "NOTE: chroot %s", why_not); } @@ -902,8 +984,8 @@ do_uid_gid_chroot (struct context *c, bool no_delay) /* set user and/or group that we want to setuid/setgid to */ if (no_delay) { - set_group (&c0->group_state); - set_user (&c0->user_state); + platform_group_set (&c0->platform_state_group); + platform_user_set (&c0->platform_state_user); c0->uid_gid_set = true; } else if (c0->uid_gid_specified) @@ -911,7 +993,12 @@ do_uid_gid_chroot (struct context *c, bool no_delay) msg (M_INFO, "NOTE: UID/GID downgrade %s", why_not); } -#ifdef HAVE_SETCON +#ifdef ENABLE_MEMSTATS + if (c->options.memstats_fn) + mstats_open(c->options.memstats_fn); +#endif + +#ifdef ENABLE_SELINUX /* Apply a SELinux context in order to restrict what OpenVPN can do * to _only_ what it is supposed to do after initialization is complete * (basically just network I/O operations). Doing it after chroot @@ -941,7 +1028,7 @@ const char * format_common_name (struct context *c, struct gc_arena *gc) { struct buffer out = alloc_buf_gc (256, gc); -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->c2.tls_multi) { buf_printf (&out, "[%s] ", tls_common_name (c->c2.tls_multi, false)); @@ -1028,12 +1115,12 @@ do_init_timers (struct context *c, bool deferred) #endif /* initialize packet_id persistence timer */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (c->options.packet_id_file) event_timeout_init (&c->c2.packet_id_persist_interval, 60, now); #endif -#if defined(USE_CRYPTO) && defined(USE_SSL) +#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); @@ -1047,7 +1134,7 @@ do_init_timers (struct context *c, bool deferred) static void do_init_traffic_shaper (struct context *c) { -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER /* initialize traffic shaper (i.e. transmit bandwidth limiter) */ if (c->options.shaper) { @@ -1066,6 +1153,8 @@ do_alloc_route_list (struct context *c) { if (c->options.routes && !c->c1.route_list) c->c1.route_list = new_route_list (c->options.max_routes, &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); } @@ -1108,6 +1197,42 @@ 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, + 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 */ +#if 0 /* not yet done for IPv6 - TODO!*/ + if ( options->route_ipv6_default_gateway ) /* override? */ + gw = options->route_ipv6_default_gateway; +#endif + + if (options->route_default_metric) + metric = options->route_default_metric; + + if (!init_route_ipv6_list (route_ipv6_list, + options->routes_ipv6, + gw, + metric, + es)) + { + if (fatal) + openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */ + } + else + { + /* copy routes to environment */ + setenv_routes_ipv6 (es, route_ipv6_list); + } +} + + /* * Called after all initialization has been completed. */ @@ -1150,7 +1275,12 @@ initialization_sequence_completed (struct context *c, const unsigned int flags) const char *detail = "SUCCESS"; if (c->c1.tuntap) tun_local = c->c1.tuntap->local; - tun_remote = htonl (c->c1.link_socket_addr.actual.dest.sa.sin_addr.s_addr); + /* 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"; management_set_state (management, @@ -1162,7 +1292,6 @@ initialization_sequence_completed (struct context *c, const unsigned int flags) management_post_tunnel_open (management, tun_local); } #endif - } /* @@ -1172,12 +1301,20 @@ initialization_sequence_completed (struct context *c, const unsigned int flags) void do_route (const struct options *options, struct route_list *route_list, + struct route_ipv6_list *route_ipv6_list, const struct tuntap *tt, const struct plugin_list *plugins, struct env_set *es) { - if (!options->route_noexec && route_list) - add_routes (route_list, tt, ROUTE_OPTION_FLAGS (options), es); + if (!options->route_noexec && ( route_list || route_ipv6_list ) ) + { + add_routes (route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS (options), es); + setenv_int (es, "redirect_gateway", route_did_redirect_default_gateway(route_list)); + } +#ifdef ENABLE_MANAGEMENT + if (management) + management_up_down (management, "UP", es); +#endif if (plugin_defined (plugins, OPENVPN_PLUGIN_ROUTE_UP)) { @@ -1234,11 +1371,17 @@ do_init_tun (struct context *c) c->options.topology, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, + 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->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); @@ -1270,6 +1413,8 @@ do_open_tun (struct context *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); /* do ifconfig */ if (!c->options.ifconfig_noexec @@ -1286,7 +1431,7 @@ do_open_tun (struct context *c) /* open the tun device */ open_tun (c->options.dev, c->options.dev_type, c->options.dev_node, - c->options.tun_ipv6, c->c1.tuntap); + c->c1.tuntap); /* set the hardware address */ if (c->options.lladdr) @@ -1304,6 +1449,7 @@ do_open_tun (struct context *c) c->plugins, OPENVPN_PLUGIN_UP, c->c1.tuntap->actual_name, + dev_type_string (c->options.dev, c->options.dev_type), TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (c->c1.tuntap->local, IA_EMPTY_IF_UNDEF, &gc), @@ -1315,7 +1461,8 @@ do_open_tun (struct context *c) /* possibly add routes */ if (!c->options.route_delay_defined) - do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es); + do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list, + c->c1.tuntap, c->plugins, c->c2.es); /* * Did tun/tap driver give us an MTU? @@ -1339,6 +1486,7 @@ do_open_tun (struct context *c) c->plugins, OPENVPN_PLUGIN_UP, c->c1.tuntap->actual_name, + dev_type_string (c->options.dev, c->options.dev_type), TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (c->c1.tuntap->local, IA_EMPTY_IF_UNDEF, &gc), @@ -1385,12 +1533,33 @@ do_close_tun (struct context *c, bool force) #ifdef ENABLE_MANAGEMENT /* tell management layer we are about to close the TUN/TAP device */ if (management) - management_pre_tunnel_close (management); + { + management_pre_tunnel_close (management); + management_up_down (management, "DOWN", c->c2.es); + } #endif /* delete any routes we added */ - if (c->c1.route_list) - delete_routes (c->c1.route_list, c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es); + 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, + NULL, + TUN_MTU_SIZE (&c->c2.frame), + EXPANDED_SIZE (&c->c2.frame), + print_in_addr_t (local, IA_EMPTY_IF_UNDEF, &gc), + print_in_addr_t (remote_netmask, IA_EMPTY_IF_UNDEF, &gc), + "init", + signal_description (c->sig->signal_received, + c->sig->signal_text), + "route-pre-down", + c->c2.es); + + delete_routes (c->c1.route_list, c->c1.route_ipv6_list, + c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es); + } /* actually close tun/tap device based on --down-pre flag */ if (!c->options.down_pre) @@ -1402,6 +1571,7 @@ do_close_tun (struct context *c, bool force) c->plugins, OPENVPN_PLUGIN_DOWN, tuntap_actual, + NULL, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (local, IA_EMPTY_IF_UNDEF, &gc), @@ -1424,6 +1594,7 @@ do_close_tun (struct context *c, bool force) c->plugins, OPENVPN_PLUGIN_DOWN, tuntap_actual, + NULL, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (local, IA_EMPTY_IF_UNDEF, &gc), @@ -1527,7 +1698,6 @@ pull_permission_mask (const struct context *c) unsigned int flags = OPT_P_UP | OPT_P_ROUTE_EXTRAS - | OPT_P_IPWIN32 | OPT_P_SOCKBUF | OPT_P_SOCKFLAGS | OPT_P_SETENV @@ -1541,7 +1711,7 @@ pull_permission_mask (const struct context *c) | OPT_P_PULL_MODE; if (!c->options.route_nopull) - flags |= OPT_P_ROUTE; + flags |= (OPT_P_ROUTE | OPT_P_IPWIN32); return flags; } @@ -1566,17 +1736,17 @@ do_deferred_options (struct context *c, const unsigned int found) #ifdef ENABLE_OCC if (found & OPT_P_EXPLICIT_NOTIFY) { - if (c->options.ce.proto != PROTO_UDPv4 && c->options.explicit_exit_notification) + if (!proto_is_udp(c->options.ce.proto) && c->options.ce.explicit_exit_notification) { msg (D_PUSH, "OPTIONS IMPORT: --explicit-exit-notify can only be used with --proto udp"); - c->options.explicit_exit_notification = 0; + c->options.ce.explicit_exit_notification = 0; } else msg (D_PUSH, "OPTIONS IMPORT: explicit notify parm(s) modified"); } #endif -#ifdef USE_LZO +#ifdef ENABLE_LZO if (found & OPT_P_COMP) { if (lzo_defined (&c->c2.lzo_compwork)) @@ -1661,13 +1831,16 @@ socket_restart_pause (struct context *c) 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: sec = 1; break; case PROTO_TCPv4_CLIENT: + case PROTO_TCPv6_CLIENT: sec = c->options.ce.connect_retry_seconds; break; } @@ -1681,9 +1854,11 @@ socket_restart_pause (struct context *c) 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 if (c->persist.restart_sleep_seconds > 0 && c->persist.restart_sleep_seconds > sec) sec = c->persist.restart_sleep_seconds; @@ -1737,10 +1912,10 @@ frame_finalize_options (struct context *c, const struct options *o) } frame_finalize (&c->c2.frame, - o->link_mtu_defined, - o->link_mtu, - o->tun_mtu_defined, - o->tun_mtu); + o->ce.link_mtu_defined, + o->ce.link_mtu, + o->ce.tun_mtu_defined, + o->ce.tun_mtu); } /* @@ -1749,26 +1924,26 @@ frame_finalize_options (struct context *c, const struct options *o) static void key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO free_key_ctx_bi (&ks->static_key); -#ifdef USE_SSL - if (ks->ssl_ctx && free_ssl_ctx) +#ifdef ENABLE_SSL + if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx) { - SSL_CTX_free (ks->ssl_ctx); + tls_ctx_free (&ks->ssl_ctx); free_key_ctx_bi (&ks->tls_auth_key); } -#endif /* USE_SSL */ -#endif /* USE_CRYPTO */ +#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ CLEAR (*ks); } -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO static void init_crypto_pre (struct context *c, const unsigned int flags) { if (c->options.engine) - init_crypto_lib_engine (c->options.engine); + crypto_init_lib_engine (c->options.engine); if (flags & CF_LOAD_PERSISTED_PACKET_ID) { @@ -1784,6 +1959,12 @@ init_crypto_pre (struct context *c, const unsigned int flags) 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(); +#endif + } /* @@ -1800,8 +1981,11 @@ do_init_crypto_static (struct context *c, const unsigned int flags) /* Initialize packet ID tracking */ if (options->replay) { - packet_id_init (&c->c2.packet_id, options->replay_window, - options->replay_time); + packet_id_init (&c->c2.packet_id, + link_socket_proto_connection_oriented (options->ce.proto), + 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; @@ -1825,13 +2009,11 @@ do_init_crypto_static (struct context *c, const unsigned int flags) unsigned int rkf_flags = RKF_MUST_SUCCEED; const char *rkf_file = options->shared_secret_file; -#if ENABLE_INLINE_FILES if (options->shared_secret_file_inline) { rkf_file = options->shared_secret_file_inline; rkf_flags |= RKF_INLINE; } -#endif read_key_file (&key2, rkf_file, rkf_flags); } @@ -1844,9 +2026,9 @@ do_init_crypto_static (struct context *c, const unsigned int flags) 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, DO_ENCRYPT, "Static Encrypt"); + &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, DO_DECRYPT, "Static Decrypt"); + &c->c1.ks.key_type, OPENVPN_OP_DECRYPT, "Static Decrypt"); /* Erase the temporary copy of key */ CLEAR (key2); @@ -1870,7 +2052,7 @@ do_init_crypto_static (struct context *c, const unsigned int flags) options->use_iv); } -#ifdef USE_SSL +#ifdef ENABLE_SSL /* * Initialize the persistent component of OpenVPN's TLS mode, @@ -1881,14 +2063,14 @@ do_init_crypto_tls_c1 (struct context *c) { const struct options *options = &c->options; - if (!c->c1.ks.ssl_ctx) + if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx)) { /* * Initialize the OpenSSL library's global * SSL context. */ - c->c1.ks.ssl_ctx = init_ssl (options); - if (!c->c1.ks.ssl_ctx) + init_ssl (options, &(c->c1.ks.ssl_ctx)); + if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx)) { #if P2MP switch (auth_retry_get ()) @@ -1897,7 +2079,7 @@ do_init_crypto_tls_c1 (struct context *c) msg (M_FATAL, "Error: private key password verification failed"); break; case AR_INTERACT: - ssl_purge_auth (); + ssl_purge_auth (false); case AR_NOINTERACT: c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Password failure error */ break; @@ -1925,13 +2107,11 @@ do_init_crypto_tls_c1 (struct context *c) unsigned int flags = 0; const char *file = options->tls_auth_file; -#if ENABLE_INLINE_FILES if (options->tls_auth_file_inline) { flags |= GHK_INLINE; file = options->tls_auth_file_inline; } -#endif get_tls_handshake_key (&c->c1.ks.key_type, &c->c1.ks.tls_auth_key, file, @@ -1949,7 +2129,7 @@ do_init_crypto_tls_c1 (struct context *c) } else { - msg (M_INFO, "Re-using SSL/TLS context"); + msg (D_INIT_MEDIUM, "Re-using SSL/TLS context"); } } @@ -2002,6 +2182,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) to.replay = options->replay; to.replay_window = options->replay_window; to.replay_time = options->replay_time; + to.tcp_mode = link_socket_proto_connection_oriented (options->ce.proto); to.transition_window = options->transition_window; to.handshake_window = options->handshake_window; to.packet_timeout = options->tls_timeout; @@ -2026,9 +2207,16 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) to.verify_export_cert = options->tls_export_cert; to.verify_x509name = options->tls_remote; to.crl_file = options->crl_file; + 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)); to.remote_cert_eku = options->remote_cert_eku; + to.verify_hash = options->verify_hash; +#ifdef ENABLE_X509ALTUSERNAME + to.x509_username_field = (char *) options->x509_username_field; +#else + to.x509_username_field = X509_USERNAME_FIELD_DEFAULT; +#endif to.es = c->c2.es; #ifdef ENABLE_DEBUG @@ -2045,11 +2233,20 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) to.auth_user_pass_verify_script = options->auth_user_pass_verify_script; to.auth_user_pass_verify_script_via_file = options->auth_user_pass_verify_script_via_file; to.tmp_dir = options->tmp_dir; - to.ssl_flags = options->ssl_flags; if (options->ccd_exclusive) to.client_config_dir_exclusive = options->client_config_dir; #endif +#ifdef ENABLE_X509_TRACK + to.x509_track = options->x509_track; +#endif + +#if P2MP +#ifdef ENABLE_CLIENT_CR + to.sci = &options->sc_info; +#endif +#endif + /* TLS handshake authentication (--tls-auth) */ if (options->tls_auth_file) { @@ -2094,10 +2291,10 @@ do_init_finalize_tls_frame (struct context *c) } } -#endif /* USE_SSL */ -#endif /* USE_CRYPTO */ +#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* * No encryption or authentication. */ @@ -2113,26 +2310,26 @@ do_init_crypto_none (const struct context *c) static void do_init_crypto (struct context *c, const unsigned int flags) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (c->options.shared_secret_file) do_init_crypto_static (c, flags); -#ifdef USE_SSL +#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 /* USE_CRYPTO */ +#else /* ENABLE_CRYPTO */ msg (M_WARN, "******* WARNING *******: " PACKAGE_NAME " built without OpenSSL -- encryption and authentication features disabled -- all data will be tunnelled as cleartext"); -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ } static void do_init_frame (struct context *c) { -#ifdef USE_LZO +#ifdef ENABLE_LZO /* * Initialize LZO compression library. */ @@ -2155,7 +2352,7 @@ do_init_frame (struct context *c) lzo_adjust_frame_parameters (&c->c2.frame_fragment_omit); /* omit LZO frame delta from final frame_fragment */ #endif } -#endif /* USE_LZO */ +#endif /* ENABLE_LZO */ #ifdef ENABLE_SOCKS /* @@ -2168,8 +2365,8 @@ do_init_frame (struct context *c) /* * Adjust frame size based on the --tun-mtu-extra parameter. */ - if (c->options.tun_mtu_extra_defined) - tun_adjust_frame_parameters (&c->c2.frame, c->options.tun_mtu_extra); + if (c->options.ce.tun_mtu_extra_defined) + tun_adjust_frame_parameters (&c->c2.frame, c->options.ce.tun_mtu_extra); /* * Adjust frame size based on link socket parameters. @@ -2198,13 +2395,13 @@ do_init_frame (struct context *c) /* * MTU advisories */ - if (c->options.fragment && c->options.mtu_test) + if (c->options.ce.fragment && c->options.mtu_test) msg (M_WARN, "WARNING: using --fragment and --mtu-test together may produce an inaccurate MTU test result"); #endif #ifdef ENABLE_FRAGMENT - if ((c->options.mssfix || c->options.fragment) + if ((c->options.ce.mssfix || c->options.ce.fragment) && TUN_MTU_SIZE (&c->c2.frame_fragment) != ETHERNET_MTU) msg (M_WARN, "WARNING: normally if you use --mssfix and/or --fragment, you should also set --tun-mtu %d (currently it is %d)", @@ -2217,17 +2414,11 @@ do_option_warnings (struct context *c) { const struct options *o = &c->options; -#if 1 /* JYFIXME -- port warning */ - if (!o->ce.port_option_used && (o->ce.local_port == OPENVPN_PORT && o->ce.remote_port == OPENVPN_PORT)) - msg (M_WARN, "IMPORTANT: OpenVPN's default port number is now %d, based on an official port number assignment by IANA. OpenVPN 2.0-beta16 and earlier used 5000 as the default port.", - OPENVPN_PORT); -#endif - if (o->ping_send_timeout && !o->ping_rec_timeout) msg (M_WARN, "WARNING: --ping should normally be used with --ping-restart or --ping-exit"); if (o->username || o->groupname || o->chroot_dir -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX || o->selinux_context #endif ) @@ -2265,19 +2456,19 @@ do_option_warnings (struct context *c) #endif #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (!o->replay) msg (M_WARN, "WARNING: You have disabled Replay Protection (--no-replay) which may make " PACKAGE_NAME " less secure"); if (!o->use_iv) msg (M_WARN, "WARNING: You have disabled Crypto IVs (--no-iv) which may make " PACKAGE_NAME " less secure"); -#ifdef USE_SSL +#ifdef ENABLE_SSL if (o->tls_server) warn_on_use_of_common_subnets (); if (o->tls_client && !o->tls_verify && !o->tls_remote - && !(o->ns_cert_type & NS_SSL_SERVER) + && !(o->ns_cert_type & NS_CERT_CHECK_SERVER) && !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."); if (o->tls_remote) @@ -2296,15 +2487,12 @@ do_option_warnings (struct context *c) msg (M_WARN, "WARNING: the current --script-security setting may allow passwords to be passed to scripts via environmental variables"); else msg (M_WARN, "NOTE: " PACKAGE_NAME " 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables"); - - if (script_method == SM_SYSTEM) - msg (M_WARN, "NOTE: --script-security method='system' is deprecated due to the fact that passed parameters will be subject to shell expansion"); } static void do_init_frame_tls (struct context *c) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) do_init_finalize_tls_frame (c); #endif } @@ -2321,12 +2509,12 @@ init_context_buffers (const struct frame *frame) b->aux_buf = alloc_buf (BUF_SIZE (frame)); -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO b->encrypt_buf = alloc_buf (BUF_SIZE (frame)); b->decrypt_buf = alloc_buf (BUF_SIZE (frame)); #endif -#ifdef USE_LZO +#ifdef ENABLE_LZO b->lzo_compress_buf = alloc_buf (BUF_SIZE (frame)); b->lzo_decompress_buf = alloc_buf (BUF_SIZE (frame)); #endif @@ -2343,12 +2531,12 @@ free_context_buffers (struct context_buffers *b) free_buf (&b->read_tun_buf); free_buf (&b->aux_buf); -#ifdef USE_LZO +#ifdef ENABLE_LZO free_buf (&b->lzo_compress_buf); free_buf (&b->lzo_decompress_buf); #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO free_buf (&b->encrypt_buf); free_buf (&b->decrypt_buf); #endif @@ -2376,9 +2564,9 @@ do_init_buffers (struct context *c) static void do_init_fragment (struct context *c) { - ASSERT (c->options.fragment); + ASSERT (c->options.ce.fragment); frame_set_mtu_dynamic (&c->c2.frame_fragment, - c->options.fragment, SET_MTU_UPPER_BOUND); + c->options.ce.fragment, SET_MTU_UPPER_BOUND); fragment_frame_init (c->c2.fragment, &c->c2.frame_fragment); } #endif @@ -2389,10 +2577,10 @@ do_init_fragment (struct context *c) static void do_init_mssfix (struct context *c) { - if (c->options.mssfix) + if (c->options.ce.mssfix) { frame_set_mtu_dynamic (&c->c2.frame, - c->options.mssfix, SET_MTU_UPPER_BOUND); + c->options.ce.mssfix, SET_MTU_UPPER_BOUND); } } @@ -2448,9 +2636,10 @@ do_init_socket_1 (struct context *c, const int mode) c->options.ce.connect_retry_seconds, c->options.ce.connect_timeout, c->options.ce.connect_retry_max, - c->options.mtu_discover_type, + c->options.ce.mtu_discover_type, c->options.rcvbuf, c->options.sndbuf, + c->options.mark, sockflags); } @@ -2496,7 +2685,7 @@ do_compute_occ_strings (struct context *c) msg (D_SHOW_OCC, "Expected Remote Options String: '%s'", c->c2.options_string_remote); -#ifdef USE_CRYPTO +#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, @@ -2507,7 +2696,7 @@ do_compute_occ_strings (struct context *c) strlen (c->c2.options_string_remote), 9, &gc)); #endif -#if defined(USE_CRYPTO) && defined(USE_SSL) +#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, @@ -2535,8 +2724,8 @@ do_init_first_time (struct context *c) /* get user and/or group that we want to setuid/setgid to */ c0->uid_gid_specified = - get_group (c->options.groupname, &c0->group_state) | - get_user (c->options.username, &c0->user_state); + platform_group_get (c->options.groupname, &c0->platform_state_group) | + platform_user_get (c->options.username, &c0->platform_state_user); /* get --writepid file descriptor */ get_pid_file (c->options.writepid, &c0->pid_state); @@ -2546,13 +2735,13 @@ do_init_first_time (struct context *c) /* should we disable paging? */ if (c->options.mlock && c->did_we_daemonize) - do_mlockall (true); /* call again in case we daemonized */ + platform_mlockall (true); /* call again in case we daemonized */ /* save process ID in a file */ write_pid (&c0->pid_state); /* should we change scheduling priority? */ - set_nice (c->options.nice); + platform_nice (c->options.nice); } } @@ -2593,7 +2782,7 @@ do_close_free_buf (struct context *c) static void do_close_tls (struct context *c) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->c2.tls_multi) { tls_multi_free (c->c2.tls_multi, true); @@ -2649,7 +2838,7 @@ do_close_link_socket (struct context *c) static void do_close_packet_id (struct context *c) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO packet_id_free (&c->c2.packet_id); packet_id_persist_save (&c->c1.pid_persist); if (!(c->sig->signal_received == SIGUSR1)) @@ -2775,7 +2964,7 @@ do_close_ifconfig_pool_persist (struct context *c) static void do_inherit_env (struct context *c, const struct env_set *src) { - c->c2.es = env_set_create (NULL); + c->c2.es = env_set_create (&c->c2.gc); c->c2.es_owned = true; env_set_inherit (c->c2.es, src); } @@ -2807,11 +2996,11 @@ do_setup_fast_io (struct context *c) #ifdef WIN32 msg (M_INFO, "NOTE: --fast-io is disabled since we are running on Windows"); #else - if (c->options.ce.proto != PROTO_UDPv4) + if (!proto_is_udp(c->options.ce.proto)) msg (M_INFO, "NOTE: --fast-io is disabled since we are not using UDP"); else { -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER if (c->options.shaper) msg (M_INFO, "NOTE: --fast-io is disabled since we are using --shaper"); else @@ -2827,7 +3016,7 @@ do_setup_fast_io (struct context *c) static void do_signal_on_tls_errors (struct context *c) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->options.tls_exit) c->c2.tls_exit_signal = SIGTERM; else @@ -2939,9 +3128,8 @@ init_management_callback_p2p (struct context *c) cb.arg = c; cb.status = management_callback_status_p2p; cb.show_net = management_show_net_callback; -#if HTTP_PROXY_FALLBACK - cb.http_proxy_fallback_cmd = management_callback_http_proxy_fallback_cmd; -#endif + cb.proxy_cmd = management_callback_proxy_cmd; + cb.remote_cmd = management_callback_remote_cmd; management_set_callback (management, &cb); } #endif @@ -3083,7 +3271,8 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int /* 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) + if (c->options.ce.proto == PROTO_TCPv4_SERVER + || c->options.ce.proto == PROTO_TCPv6_SERVER) { if (c->mode == CM_TOP) link_socket_mode = LS_MODE_TCP_LISTEN; @@ -3093,7 +3282,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int /* should we disable paging? */ if (c->first_time && options->mlock) - do_mlockall (true); + platform_mlockall (true); #if P2MP /* get passwords if undefined */ @@ -3158,7 +3347,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int #ifdef ENABLE_FRAGMENT /* initialize internal fragmentation object */ - if (options->fragment && (c->mode == CM_P2P || child)) + if (options->ce.fragment && (c->mode == CM_P2P || child)) c->c2.fragment = fragment_init (&c->c2.frame); #endif @@ -3176,7 +3365,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int goto sig; } -#ifdef USE_LZO +#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); @@ -3194,7 +3383,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int #ifdef ENABLE_FRAGMENT /* initialize internal fragmentation capability with known frame size */ - if (options->fragment && (c->mode == CM_P2P || child)) + if (options->ce.fragment && (c->mode == CM_P2P || child)) do_init_fragment (c); #endif @@ -3293,7 +3482,7 @@ close_instance (struct context *c) /* if xinetd/inetd mode, don't allow restart */ do_close_check_if_restart_permitted (c); -#ifdef USE_LZO +#ifdef ENABLE_LZO if (lzo_defined (&c->c2.lzo_compwork)) lzo_compress_uninit (&c->c2.lzo_compwork); #endif @@ -3358,17 +3547,8 @@ inherit_context_child (struct context *dest, { CLEAR (*dest); - switch (src->options.ce.proto) - { - case PROTO_UDPv4: - dest->mode = CM_CHILD_UDP; - break; - case PROTO_TCPv4_SERVER: - dest->mode = CM_CHILD_TCP; - break; - default: - ASSERT (0); - } + /* proto_is_dgram will ASSERT(0) if proto is invalid */ + dest->mode = proto_is_dgram(src->options.ce.proto)? CM_CHILD_UDP : CM_CHILD_TCP; dest->gc = gc_new (); @@ -3377,9 +3557,9 @@ inherit_context_child (struct context *dest, /* c1 init */ packet_id_persist_init (&dest->c1.pid_persist); -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO dest->c1.ks.key_type = src->c1.ks.key_type; -#ifdef USE_SSL +#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; @@ -3456,7 +3636,7 @@ inherit_context_top (struct context *dest, /* detach plugins */ dest->plugins_owned = false; -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) dest->c2.tls_multi = NULL; #endif @@ -3474,7 +3654,7 @@ inherit_context_top (struct context *dest, dest->c2.es_owned = false; dest->c2.event_set = NULL; - if (src->options.ce.proto == PROTO_UDPv4) + if (proto_is_dgram(src->options.ce.proto)) do_event_set_init (dest, false); } @@ -3501,7 +3681,7 @@ close_context (struct context *c, int sig, unsigned int flags) context_gc_free (c); } -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* * Do a loopback test @@ -3534,7 +3714,7 @@ test_crypto_thread (void *arg) bool do_test_crypto (const struct options *o) { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (o->test_crypto) { struct context c; diff --git a/init.h b/src/openvpn/init.h index cf5ca8a..5a1d1dc 100644 --- a/init.h +++ b/src/openvpn/init.h @@ -63,6 +63,7 @@ void init_instance (struct context *c, const struct env_set *env, const unsigned void do_route (const struct options *options, struct route_list *route_list, + struct route_ipv6_list *route_ipv6_list, const struct tuntap *tt, const struct plugin_list *plugins, struct env_set *es); diff --git a/integer.h b/src/openvpn/integer.h index f0fc196..f0fc196 100644 --- a/integer.h +++ b/src/openvpn/integer.h diff --git a/interval.c b/src/openvpn/interval.c index 44d59d0..64494f1 100644 --- a/interval.c +++ b/src/openvpn/interval.c @@ -22,6 +22,12 @@ * 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" #include "interval.h" diff --git a/interval.h b/src/openvpn/interval.h index 4814ec9..4814ec9 100644 --- a/interval.h +++ b/src/openvpn/interval.h diff --git a/list.c b/src/openvpn/list.c index fb93d0a..ea6bd74 100644 --- a/list.c +++ b/src/openvpn/list.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER diff --git a/list.h b/src/openvpn/list.h index adde36b..adde36b 100644 --- a/list.h +++ b/src/openvpn/list.h diff --git a/lladdr.c b/src/openvpn/lladdr.c index 7aefdba..57f447b 100644 --- a/lladdr.c +++ b/src/openvpn/lladdr.c @@ -2,6 +2,12 @@ * Support routine for configuring link layer address */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #include "error.h" #include "misc.h" @@ -16,7 +22,7 @@ int set_lladdr(const char *ifname, const char *lladdr, return -1; #if defined(TARGET_LINUX) -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE argv_printf (&argv, "%s link set addr %s dev %s", iproute_path, lladdr, ifname); diff --git a/lladdr.h b/src/openvpn/lladdr.h index d6c4256..d6c4256 100644 --- a/lladdr.h +++ b/src/openvpn/lladdr.h diff --git a/lzo.c b/src/openvpn/lzo.c index 6ea0d03..195b819 100644 --- a/lzo.c +++ b/src/openvpn/lzo.c @@ -22,9 +22,19 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/** + * @file Data Channel Compression module function definitions. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#ifdef USE_LZO +#ifdef ENABLE_LZO #include "lzo.h" #include "error.h" @@ -32,6 +42,14 @@ #include "memdbg.h" +#ifndef ENABLE_LZO_STUB +/** + * Perform adaptive compression housekeeping. + * + * @param ac the adaptive compression state structure. + * + * @return + */ static bool lzo_adaptive_compress_test (struct lzo_adaptive_compress *ac) { @@ -79,6 +97,8 @@ 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. */ @@ -94,14 +114,18 @@ lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags) { CLEAR (*lzowork); - lzowork->wmem_size = LZO_WORKSPACE; lzowork->flags = flags; +#ifndef ENABLE_LZO_STUB + lzowork->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 (M_INFO, "LZO compression initialized"); + msg (D_INIT_MEDIUM, "LZO compression initialized"); +#else + msg (D_INIT_MEDIUM, "LZO stub compression initialized"); +#endif lzowork->defined = true; } @@ -111,8 +135,10 @@ lzo_compress_uninit (struct lzo_compress_workspace *lzowork) if (lzowork) { ASSERT (lzowork->defined); +#ifndef ENABLE_LZO_STUB lzo_free (lzowork->wmem); lzowork->wmem = NULL; +#endif lzowork->defined = false; } } @@ -120,6 +146,7 @@ lzo_compress_uninit (struct lzo_compress_workspace *lzowork) static inline bool lzo_compression_enabled (struct lzo_compress_workspace *lzowork) { +#ifndef ENABLE_LZO_STUB if ((lzowork->flags & (LZO_SELECTED|LZO_ON)) == (LZO_SELECTED|LZO_ON)) { if (lzowork->flags & LZO_ADAPTIVE) @@ -127,27 +154,27 @@ lzo_compression_enabled (struct lzo_compress_workspace *lzowork) else return true; } +#endif return false; } -/* Magic numbers to tell our peer if we compressed or not */ -#define YES_COMPRESS 0x66 -#define NO_COMPRESS 0xFA - void lzo_compress (struct buffer *buf, struct buffer work, struct lzo_compress_workspace *lzowork, 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. @@ -193,6 +220,7 @@ lzo_compress (struct buffer *buf, struct buffer work, *buf = work; } else +#endif { uint8_t *header = buf_prepend (buf, 1); *header = NO_COMPRESS; @@ -204,9 +232,11 @@ lzo_decompress (struct buffer *buf, struct buffer work, struct lzo_compress_workspace *lzowork, const struct frame* frame) { +#ifndef ENABLE_LZO_STUB lzo_uint zlen = EXPANDED_SIZE (frame); - uint8_t c; /* flag indicating whether or not our peer compressed */ int err; +#endif + uint8_t c; /* flag indicating whether or not our peer compressed */ ASSERT (lzowork->defined); @@ -220,6 +250,7 @@ lzo_decompress (struct buffer *buf, struct buffer work, if (c == YES_COMPRESS) /* packet was compressed */ { +#ifndef ENABLE_LZO_STUB ASSERT (buf_safe (&work, zlen)); err = LZO_DECOMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, lzowork->wmem); @@ -238,6 +269,11 @@ lzo_decompress (struct buffer *buf, struct buffer work, lzowork->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 */ { @@ -257,19 +293,18 @@ lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags) lzowork->flags = flags; } -/* - * Print statistics - */ 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 } #else static void dummy(void) {} -#endif /* USE_LZO */ +#endif /* ENABLE_LZO */ diff --git a/src/openvpn/lzo.h b/src/openvpn/lzo.h new file mode 100644 index 0000000..472204d --- /dev/null +++ b/src/openvpn/lzo.h @@ -0,0 +1,347 @@ +/* + * 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-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_LZO_H +#define OPENVPN_LZO_H + + +/** + * @file + * Data Channel Compression module header file. + */ + + +#ifdef ENABLE_LZO + +/** + * @addtogroup compression + * @{ + */ + +#ifndef ENABLE_LZO_STUB +#if defined(HAVE_LZO_LZOUTIL_H) +#include "lzo/lzoutil.h" +#elif defined(HAVE_LZOUTIL_H) +#include "lzoutil.h" +#endif +#if defined(HAVE_LZO_LZO1X_H) +#include "lzo/lzo1x.h" +#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 *//****/ + +/**************************************************************************/ +/** @name LZO library interface defines *//** @{ *//***********************/ +#ifndef ENABLE_LZO_STUB +#define LZO_COMPRESS lzo1x_1_15_compress + /**< LZO library compression function. + * + * Use \c lzo1x_1_15_compress because it + * is described as faster than the + * standard routine, although it does + * need a bit more memory. */ +#define LZO_WORKSPACE LZO1X_1_15_MEM_COMPRESS + /**< The size in bytes of the memory + * %buffer required by the LZO library + * compression algorithm. */ +#define LZO_DECOMPRESS lzo1x_decompress_safe + /**< LZO library decompression function. + * + * Use safe decompress because it + * includes checks for possible %buffer + * overflows. If speed is essential and + * you will always be using a MAC to + * 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 + * evaluated. */ +#define AC_SAVE_PCT 5 /**< Minimum size reduction percentage + * below which compression will be + * 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. + */ +struct lzo_adaptive_compress { + bool compress_state; + time_t next; + int n_total; + int n_comp; +}; + +#endif /* ENABLE_LZO_STUB */ + + +/** + * State for the compression and decompression routines. + * + * This structure contains compression module state, such as whether + * compression is enabled and the status of the adaptive compression + * routines. It also contains an allocated working buffer. + * + * One of these compression workspace structures is maintained for each + * VPN tunnel. + */ +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 diff --git a/manage.c b/src/openvpn/manage.c index 820621e..d0bb416 100644 --- a/manage.c +++ b/src/openvpn/manage.c @@ -22,6 +22,12 @@ * 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_MANAGEMENT @@ -86,6 +92,8 @@ man_help () msg (M_CLIENT, " where action is reply string."); msg (M_CLIENT, "net : (Windows only) Show network info and routing table."); msg (M_CLIENT, "password type p : Enter password p for a queried OpenVPN password."); + msg (M_CLIENT, "remote type [host port] : Override remote directive, type=ACCEPT|MOD|SKIP."); + msg (M_CLIENT, "proxy type [host port flags] : Enter dynamic proxy server info."); msg (M_CLIENT, "pid : Show process ID of the current OpenVPN process."); #ifdef ENABLE_PKCS11 msg (M_CLIENT, "pkcs11-id-count : Get number of available PKCS#11 identities."); @@ -96,12 +104,16 @@ man_help () msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID"); msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason"); msg (M_CLIENT, " text R and optional client reason text CR"); - msg (M_CLIENT, "client-kill CID : Kill client instance CID"); + msg (M_CLIENT, "client-kill CID [M] : Kill client instance CID with message M (def=RESTART)"); msg (M_CLIENT, "env-filter [level] : Set env-var filter level"); #ifdef MANAGEMENT_PF msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)"); #endif #endif +#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"); +#endif msg (M_CLIENT, "signal s : Send signal s to daemon,"); msg (M_CLIENT, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2."); msg (M_CLIENT, "state [on|off] [N|all] : Like log, but show state history."); @@ -110,10 +122,6 @@ man_help () msg (M_CLIENT, "username type u : Enter username u for a queried OpenVPN username."); msg (M_CLIENT, "verb [n] : Set log verbosity level to n, or show if n is absent."); msg (M_CLIENT, "version : Show current version number."); -#if HTTP_PROXY_FALLBACK - msg (M_CLIENT, "http-proxy-fallback <server> <port> [flags] : Enter dynamic HTTP proxy fallback info."); - msg (M_CLIENT, "http-proxy-fallback-disable : Disable HTTP proxy fallback."); -#endif msg (M_CLIENT, "END"); } @@ -276,7 +284,10 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s { struct management *man = (struct management *) arg; static int recursive_level = 0; /* GLOBAL */ - bool did_push = false; + +# define AF_DID_PUSH (1<<0) +# define AF_DID_RESET (1<<1) + unsigned int action_flags = 0; if (!recursive_level) /* don't allow recursion */ { @@ -310,7 +321,7 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s if (out) { man_output_list_push_str (man, out); - did_push = true; + action_flags |= AF_DID_PUSH; } if (flags & M_FATAL) { @@ -318,8 +329,7 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s if (out) { man_output_list_push_str (man, out); - did_push = true; - man_reset_client_socket (man, true); + action_flags |= (AF_DID_PUSH|AF_DID_RESET); } } } @@ -328,8 +338,10 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s gc_free (&gc); } - if (did_push) + if (action_flags & AF_DID_PUSH) man_output_list_push_finalize (man); + if (action_flags & AF_DID_RESET) + man_reset_client_socket (man, true); } /* @@ -602,25 +614,19 @@ man_up_finalize (struct management *man) { switch (man->connection.up_query_mode) { - case UP_QUERY_DISABLED: - man->connection.up_query.defined = false; - break; case UP_QUERY_USER_PASS: - if (strlen (man->connection.up_query.username) && strlen (man->connection.up_query.password)) - man->connection.up_query.defined = true; - break; + if (!strlen (man->connection.up_query.username)) + break; + /* fall through */ case UP_QUERY_PASS: - if (strlen (man->connection.up_query.password)) - man->connection.up_query.defined = true; - break; case UP_QUERY_NEED_OK: - if (strlen (man->connection.up_query.password)) - man->connection.up_query.defined = true; - break; case UP_QUERY_NEED_STR: if (strlen (man->connection.up_query.password)) man->connection.up_query.defined = true; break; + case UP_QUERY_DISABLED: + man->connection.up_query.defined = false; + break; default: ASSERT (0); } @@ -661,16 +667,17 @@ man_query_user_pass (struct management *man, static void man_query_username (struct management *man, const char *type, const char *string) { - const bool needed = (man->connection.up_query_mode == UP_QUERY_USER_PASS && man->connection.up_query_type); + const bool needed = ((man->connection.up_query_mode == UP_QUERY_USER_PASS + ) && man->connection.up_query_type); man_query_user_pass (man, type, string, needed, "username", man->connection.up_query.username, USER_PASS_LEN); } static void man_query_password (struct management *man, const char *type, const char *string) { - const bool needed = ((man->connection.up_query_mode == UP_QUERY_USER_PASS - || man->connection.up_query_mode == UP_QUERY_PASS) - && man->connection.up_query_type); + const bool needed = ((man->connection.up_query_mode == UP_QUERY_PASS + || man->connection.up_query_mode == UP_QUERY_USER_PASS + ) && man->connection.up_query_type); if (!string[0]) /* allow blank passwords to be passed through using the blank_up tag */ string = blank_up; man_query_user_pass (man, type, string, needed, "password", man->connection.up_query.password, USER_PASS_LEN); @@ -693,8 +700,8 @@ man_query_need_str (struct management *man, const char *type, const char *action static void man_forget_passwords (struct management *man) { -#if defined(USE_CRYPTO) && defined(USE_SSL) - ssl_purge_auth (); +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) + ssl_purge_auth (false); msg (M_CLIENT, "SUCCESS: Passwords were forgotten"); #endif } @@ -768,49 +775,30 @@ man_hold (struct management *man, const char *cmd) msg (M_CLIENT, "SUCCESS: hold=%d", BOOL_CAST(man->settings.flags & MF_HOLD)); } -#ifdef MANAGEMENT_DEF_AUTH - -static bool -parse_cid (const char *str, unsigned long *cid) -{ - if (sscanf (str, "%lu", cid) == 1) - return true; - else - { - msg (M_CLIENT, "ERROR: cannot parse CID"); - return false; - } -} +#ifdef MANAGEMENT_IN_EXTRA -static bool -parse_kid (const char *str, unsigned int *kid) -{ - if (sscanf (str, "%u", kid) == 1) - return true; - else - { - msg (M_CLIENT, "ERROR: cannot parse KID"); - return false; - } -} +#define IER_RESET 0 +#define IER_NEW 1 static void -in_extra_reset (struct man_connection *mc, const bool new) +in_extra_reset (struct man_connection *mc, const int mode) { if (mc) { - if (!new) + if (mode != IER_NEW) { mc->in_extra_cmd = IEC_UNDEF; +#ifdef MANAGEMENT_DEF_AUTH mc->in_extra_cid = 0; mc->in_extra_kid = 0; +#endif } if (mc->in_extra) { buffer_list_free (mc->in_extra); mc->in_extra = NULL; } - if (new) + if (mode == IER_NEW) mc->in_extra = buffer_list_new (0); } } @@ -820,6 +808,7 @@ in_extra_dispatch (struct management *man) { switch (man->connection.in_extra_cmd) { +#ifdef MANAGEMENT_DEF_AUTH case IEC_CLIENT_AUTH: if (man->persist.callback.client_auth) { @@ -846,6 +835,7 @@ in_extra_dispatch (struct management *man) msg (M_CLIENT, "ERROR: The client-auth command is not supported by the current daemon mode"); } break; +#endif #ifdef MANAGEMENT_PF case IEC_CLIENT_PF: if (man->persist.callback.client_pf) @@ -870,8 +860,44 @@ in_extra_dispatch (struct management *man) } break; #endif +#ifdef MANAGMENT_EXTERNAL_KEY + case IEC_RSA_SIGN: + man->connection.ext_key_state = EKS_READY; + buffer_list_free (man->connection.ext_key_input); + man->connection.ext_key_input = man->connection.in_extra; + man->connection.in_extra = NULL; + return; +#endif + } + in_extra_reset (&man->connection, IER_RESET); +} + +#endif /* MANAGEMENT_IN_EXTRA */ + +#ifdef MANAGEMENT_DEF_AUTH + +static bool +parse_cid (const char *str, unsigned long *cid) +{ + if (sscanf (str, "%lu", cid) == 1) + return true; + else + { + msg (M_CLIENT, "ERROR: cannot parse CID"); + return false; + } +} + +static bool +parse_kid (const char *str, unsigned int *kid) +{ + if (sscanf (str, "%u", kid) == 1) + return true; + else + { + msg (M_CLIENT, "ERROR: cannot parse KID"); + return false; } - in_extra_reset (&man->connection, false); } static void @@ -884,7 +910,7 @@ man_client_auth (struct management *man, const char *cid_str, const char *kid_st && parse_kid (kid_str, &mc->in_extra_kid)) { mc->in_extra_cmd = IEC_CLIENT_AUTH; - in_extra_reset (mc, true); + in_extra_reset (mc, IER_NEW); if (!extra) in_extra_dispatch (man); } @@ -924,14 +950,14 @@ man_client_deny (struct management *man, const char *cid_str, const char *kid_st } static void -man_client_kill (struct management *man, const char *cid_str) +man_client_kill (struct management *man, const char *cid_str, const char *kill_msg) { unsigned long cid = 0; if (parse_cid (cid_str, &cid)) { if (man->persist.callback.kill_by_cid) { - const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid); + const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid, kill_msg); if (status) { msg (M_CLIENT, "SUCCESS: client-kill command succeeded"); @@ -980,11 +1006,29 @@ man_client_pf (struct management *man, const char *cid_str) if (parse_cid (cid_str, &mc->in_extra_cid)) { mc->in_extra_cmd = IEC_CLIENT_PF; - in_extra_reset (mc, true); + in_extra_reset (mc, IER_NEW); } } -#endif +#endif /* MANAGEMENT_PF */ +#endif /* MANAGEMENT_DEF_AUTH */ + +#ifdef MANAGMENT_EXTERNAL_KEY + +static void +man_rsa_sig (struct management *man) +{ + struct man_connection *mc = &man->connection; + if (mc->ext_key_state == EKS_SOLICIT) + { + mc->ext_key_state = EKS_INPUT; + mc->in_extra_cmd = IEC_RSA_SIGN; + in_extra_reset (mc, IER_NEW); + } + else + msg (M_CLIENT, "ERROR: The rsa-sig command is not currently available"); +} + #endif static void @@ -1024,31 +1068,42 @@ man_need (struct management *man, const char **p, const int n, unsigned int flag return true; } -#if HTTP_PROXY_FALLBACK +static void +man_proxy (struct management *man, const char **p) +{ + if (man->persist.callback.proxy_cmd) + { + const bool status = (*man->persist.callback.proxy_cmd)(man->persist.callback.arg, p); + if (status) + msg (M_CLIENT, "SUCCESS: proxy command succeeded"); + else + msg (M_CLIENT, "ERROR: proxy command failed"); + } + else + msg (M_CLIENT, "ERROR: The proxy command is not supported by the current daemon mode"); +} static void -man_http_proxy_fallback (struct management *man, const char *server, const char *port, const char *flags) +man_remote (struct management *man, const char **p) { - if (man->persist.callback.http_proxy_fallback_cmd) + if (man->persist.callback.remote_cmd) { - const bool status = (*man->persist.callback.http_proxy_fallback_cmd)(man->persist.callback.arg, server, port, flags); + const bool status = (*man->persist.callback.remote_cmd)(man->persist.callback.arg, p); if (status) { - msg (M_CLIENT, "SUCCESS: proxy-fallback command succeeded"); + msg (M_CLIENT, "SUCCESS: remote command succeeded"); } else { - msg (M_CLIENT, "ERROR: proxy-fallback command failed"); + msg (M_CLIENT, "ERROR: remote command failed"); } } else { - msg (M_CLIENT, "ERROR: The proxy-fallback command is not supported by the current daemon mode"); + msg (M_CLIENT, "ERROR: The remote command is not supported by the current daemon mode"); } } -#endif - static void man_dispatch_command (struct management *man, struct status_output *so, const char **p, const int nparms) { @@ -1072,7 +1127,7 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch } else if (streq (p[0], "pid")) { - msg (M_CLIENT, "SUCCESS: pid=%d", openvpn_getpid ()); + msg (M_CLIENT, "SUCCESS: pid=%d", platform_getpid ()); } #ifdef MANAGEMENT_DEF_AUTH else if (streq (p[0], "nclients")) @@ -1224,8 +1279,8 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch #ifdef MANAGEMENT_DEF_AUTH else if (streq (p[0], "client-kill")) { - if (man_need (man, p, 1, 0)) - man_client_kill (man, p[1]); + if (man_need (man, p, 1, MN_AT_LEAST)) + man_client_kill (man, p[1], p[2]); } else if (streq (p[0], "client-deny")) { @@ -1250,6 +1305,12 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch } #endif #endif +#ifdef MANAGMENT_EXTERNAL_KEY + else if (streq (p[0], "rsa-sig")) + { + man_rsa_sig (man); + } +#endif #ifdef ENABLE_PKCS11 else if (streq (p[0], "pkcs11-id-count")) { @@ -1261,17 +1322,16 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch man_pkcs11_id_get (man, atoi(p[1])); } #endif -#if HTTP_PROXY_FALLBACK - else if (streq (p[0], "http-proxy-fallback")) + else if (streq (p[0], "proxy")) { - if (man_need (man, p, 2, MN_AT_LEAST)) - man_http_proxy_fallback (man, p[1], p[2], p[3]); + if (man_need (man, p, 1, MN_AT_LEAST)) + man_proxy (man, p); } - else if (streq (p[0], "http-proxy-fallback-disable")) + else if (streq (p[0], "remote")) { - man_http_proxy_fallback (man, NULL, NULL, NULL); + if (man_need (man, p, 1, MN_AT_LEAST)) + man_remote (man, p); } -#endif #if 1 else if (streq (p[0], "test")) { @@ -1342,7 +1402,7 @@ man_record_peer_info (struct management *man) { const in_addr_t a = ntohl (addr.sin_addr.s_addr); const int p = ntohs (addr.sin_port); - FILE *fp = fopen (man->settings.write_peer_info_file, "w"); + FILE *fp = platform_fopen (man->settings.write_peer_info_file, "w"); if (fp) { fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p); @@ -1507,7 +1567,7 @@ man_listen (struct management *man) else #endif { - man->connection.sd_top = create_socket_tcp (); + man->connection.sd_top = create_socket_tcp (AF_INET); socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT"); } @@ -1515,7 +1575,7 @@ man_listen (struct management *man) * Listen for connection */ if (listen (man->connection.sd_top, 1)) - msg (M_SOCKERR, "MANAGEMENT: listen() failed"); + msg (M_ERR, "MANAGEMENT: listen() failed"); /* * Set misc socket properties @@ -1573,7 +1633,7 @@ man_connect (struct management *man) else #endif { - man->connection.sd_cli = create_socket_tcp (); + man->connection.sd_cli = create_socket_tcp (AF_INET); status = openvpn_connect (man->connection.sd_cli, &man->settings.local, 5, @@ -1626,16 +1686,16 @@ man_reset_client_socket (struct management *man, const bool exiting) man->connection.state = MS_INITIAL; command_line_reset (man->connection.in); buffer_list_reset (man->connection.out); -#ifdef MANAGEMENT_DEF_AUTH - in_extra_reset (&man->connection, false); +#ifdef MANAGEMENT_IN_EXTRA + in_extra_reset (&man->connection, IER_RESET); #endif msg (D_MANAGEMENT, "MANAGEMENT: Client disconnected"); } if (!exiting) { -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (man->settings.flags & MF_FORGET_DISCONNECT) - ssl_purge_auth (); + ssl_purge_auth (false); #endif if (man->settings.flags & MF_SIGNAL) { int mysig = man_mod_signal (man, SIGUSR1); @@ -1666,8 +1726,8 @@ man_process_command (struct management *man, const char *line) CLEAR (parms); so = status_open (NULL, 0, -1, &man->persist.vout, 0); -#ifdef MANAGEMENT_DEF_AUTH - in_extra_reset (&man->connection, false); +#ifdef MANAGEMENT_IN_EXTRA + in_extra_reset (&man->connection, IER_RESET); #endif if (man_password_needed (man)) @@ -1703,7 +1763,7 @@ man_process_command (struct management *man, const char *line) static bool man_io_error (struct management *man, const char *prefix) { - const int err = openvpn_errno_socket (); + const int err = openvpn_errno (); if (!ignore_sys_error (err)) { @@ -1751,18 +1811,13 @@ man_read (struct management *man) const unsigned char *line; while ((line = command_line_get (man->connection.in))) { -#ifdef MANAGEMENT_DEF_AUTH +#ifdef MANAGEMENT_IN_EXTRA if (man->connection.in_extra) { if (!strcmp ((char *)line, "END")) - { - in_extra_dispatch (man); - in_extra_reset (&man->connection, false); - } + in_extra_dispatch (man); else - { - buffer_list_push (man->connection.in_extra, line); - } + buffer_list_push (man->connection.in_extra, line); } else #endif @@ -1931,17 +1986,17 @@ man_settings_init (struct man_settings *ms, */ if (client_user) { - struct user_state s; - get_user (client_user, &s); - ms->client_uid = user_state_uid (&s); + struct platform_state_user s; + platform_user_get (client_user, &s); + ms->client_uid = platform_state_user_uid (&s); msg (D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid); ASSERT (ms->client_uid >= 0); } if (client_group) { - struct group_state s; - get_group (client_group, &s); - ms->client_gid = group_state_gid (&s); + struct platform_state_group s; + platform_group_get (client_group, &s); + ms->client_gid = platform_state_group_gid (&s); msg (D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid); ASSERT (ms->client_gid >= 0); } @@ -1957,9 +2012,9 @@ man_settings_init (struct man_settings *ms, /* * Initialize socket address */ - ms->local.sa.sin_family = AF_INET; - ms->local.sa.sin_addr.s_addr = 0; - ms->local.sa.sin_port = htons (port); + 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 @@ -1971,7 +2026,7 @@ man_settings_init (struct man_settings *ms, } else { - ms->local.sa.sin_addr.s_addr = getaddr + ms->local.addr.in4.sin_addr.s_addr = getaddr (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL); } } @@ -2063,8 +2118,11 @@ man_connection_close (struct management *man) command_line_free (mc->in); if (mc->out) buffer_list_free (mc->out); -#ifdef MANAGEMENT_DEF_AUTH - in_extra_reset (&man->connection, false); +#ifdef MANAGEMENT_IN_EXTRA + in_extra_reset (&man->connection, IER_RESET); +#endif +#ifdef MANAGMENT_EXTERNAL_KEY + buffer_list_free (mc->ext_key_input); #endif man_connection_clear (mc); } @@ -2145,6 +2203,7 @@ management_open (struct management *man, void management_close (struct management *man) { + man_output_list_push_finalize (man); /* flush output queue */ man_connection_close (man); man_settings_close (&man->settings); man_persist_close (&man->persist); @@ -2207,8 +2266,6 @@ management_set_state (struct management *man, } } -#ifdef MANAGEMENT_DEF_AUTH - static bool env_filter_match (const char *env_str, const int env_filter_level) { @@ -2216,7 +2273,7 @@ env_filter_match (const char *env_str, const int env_filter_level) "username=", "password=", "X509_0_CN=", - "tls_serial_0=", + "tls_serial_", "untrusted_ip=", "ifconfig_local=", "ifconfig_netmask=", @@ -2229,24 +2286,28 @@ env_filter_match (const char *env_str, const int env_filter_level) "bytes_sent=", "bytes_received=" }; - if (env_filter_level >= 1) + + if (env_filter_level == 0) + return true; + else if (env_filter_level <= 1 && !strncmp(env_str, "X509_", 5)) + return true; + else if (env_filter_level <= 2) { size_t i; for (i = 0; i < SIZE(env_names); ++i) { const char *en = env_names[i]; const size_t len = strlen(en); - if (strncmp(env_str, en, len) == 0) + if (!strncmp(env_str, en, len)) return true; } return false; } - else - return true; + return false; } static void -man_output_env (const struct env_set *es, const bool tail, const int env_filter_level) +man_output_env (const struct env_set *es, const bool tail, const int env_filter_level, const char *prefix) { if (es) { @@ -2254,15 +2315,15 @@ man_output_env (const struct env_set *es, const bool tail, const int env_filter_ for (e = es->list; e != NULL; e = e->next) { if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level))) - msg (M_CLIENT, ">CLIENT:ENV,%s", e->string); + msg (M_CLIENT, ">%s:ENV,%s", prefix, e->string); } } if (tail) - msg (M_CLIENT, ">CLIENT:ENV,END"); + msg (M_CLIENT, ">%s:ENV,END", prefix); } static void -man_output_extra_env (struct management *man) +man_output_extra_env (struct management *man, const char *prefix) { struct gc_arena gc = gc_new (); struct env_set *es = env_set_create (&gc); @@ -2271,10 +2332,34 @@ man_output_extra_env (struct management *man) const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg); setenv_int (es, "n_clients", nclients); } - man_output_env (es, false, man->connection.env_filter_level); + man_output_env (es, false, man->connection.env_filter_level, prefix); gc_free (&gc); } +void +management_up_down(struct management *man, const char *updown, const struct env_set *es) +{ + if (man->settings.flags & MF_UP_DOWN) + { + msg (M_CLIENT, ">UPDOWN:%s", updown); + man_output_env (es, true, 0, "UPDOWN"); + } +} + +void +management_notify(struct management *man, const char *severity, const char *type, const char *text) +{ + msg (M_CLIENT, ">NOTIFY:%s,%s,%s", severity, type, text); +} + +void +management_notify_generic (struct management *man, const char *str) +{ + msg (M_CLIENT, "%s", str); +} + +#ifdef MANAGEMENT_DEF_AUTH + static bool validate_peer_info_line(const char *line) { @@ -2339,9 +2424,9 @@ management_notify_client_needing_auth (struct management *management, if (mdac->flags & DAF_CONNECTION_ESTABLISHED) mode = "REAUTH"; msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id); - man_output_extra_env (management); + man_output_extra_env (management, "CLIENT"); man_output_peer_info_env(management, mdac); - man_output_env (es, true, management->connection.env_filter_level); + man_output_env (es, true, management->connection.env_filter_level, "CLIENT"); mdac->flags |= DAF_INITIAL_AUTH; } } @@ -2353,8 +2438,8 @@ management_connection_established (struct management *management, { mdac->flags |= DAF_CONNECTION_ESTABLISHED; msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid); - man_output_extra_env (management); - man_output_env (es, true, management->connection.env_filter_level); + man_output_extra_env (management, "CLIENT"); + man_output_env (es, true, management->connection.env_filter_level, "CLIENT"); } void @@ -2365,7 +2450,7 @@ management_notify_client_close (struct management *management, if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED)) { msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid); - man_output_env (es, true, management->connection.env_filter_level); + man_output_env (es, true, management->connection.env_filter_level, "CLIENT"); mdac->flags |= DAF_CONNECTION_CLOSED; } } @@ -2387,7 +2472,7 @@ management_learn_addr (struct management *management, gc_free (&gc); } -#endif +#endif /* MANAGEMENT_DEF_AUTH */ void management_echo (struct management *man, const char *string, const bool pull) @@ -2427,7 +2512,7 @@ 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.sa.sin_addr.s_addr = htonl (tun_local_ip); + man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip); man_connection_init (man); } @@ -2449,6 +2534,12 @@ management_auth_failure (struct management *man, const char *type, const char *r msg (M_CLIENT, ">PASSWORD:Verification Failed: '%s'", type); } +void +management_auth_token (struct management *man, const char *token) +{ + msg (M_CLIENT, ">PASSWORD:Auth-Token:%s", token); +} + static inline bool man_persist_state (unsigned int *persistent, const int n) { @@ -2693,6 +2784,7 @@ man_standalone_event_loop (struct management *man, volatile int *signal_received #define MWCC_PASSWORD_WAIT (1<<0) #define MWCC_HOLD_WAIT (1<<1) +#define MWCC_OTHER_WAIT (1<<2) /* * Block until client connects @@ -2710,6 +2802,8 @@ man_wait_for_client_connection (struct management *man, msg (D_MANAGEMENT, "Need password(s) from management interface, waiting..."); if (flags & MWCC_HOLD_WAIT) msg (D_MANAGEMENT, "Need hold release from management interface, waiting..."); + if (flags & MWCC_OTHER_WAIT) + msg (D_MANAGEMENT, "Need information from management interface, waiting..."); do { man_standalone_event_loop (man, signal_received, expire); if (signal_received && *signal_received) @@ -2768,7 +2862,8 @@ bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, - const unsigned int flags) + const unsigned int flags, + const char *static_challenge) { struct gc_arena gc = gc_new (); bool ret = false; @@ -2781,7 +2876,9 @@ management_query_user_pass (struct management *man, const char *alert_type = NULL; const char *prefix = NULL; unsigned int up_query_mode = 0; - +#ifdef ENABLE_CLIENT_CR + const char *sc = NULL; +#endif ret = true; man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */ man->persist.special_state_msg = NULL; @@ -2811,6 +2908,10 @@ management_query_user_pass (struct management *man, up_query_mode = UP_QUERY_USER_PASS; prefix = "PASSWORD"; alert_type = "username/password"; +#ifdef ENABLE_CLIENT_CR + if (static_challenge) + sc = static_challenge; +#endif } buf_printf (&alert_msg, ">%s:Need '%s' %s", prefix, @@ -2820,6 +2921,13 @@ management_query_user_pass (struct management *man, if (flags & (GET_USER_PASS_NEED_OK | GET_USER_PASS_NEED_STR)) buf_printf (&alert_msg, " MSG:%s", up->username); +#ifdef ENABLE_CLIENT_CR + if (sc) + buf_printf (&alert_msg, " SC:%d,%s", + BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), + sc); +#endif + man_wait_for_client_connection (man, &signal_received, 0, MWCC_PASSWORD_WAIT); if (signal_received) ret = false; @@ -2833,7 +2941,7 @@ management_query_user_pass (struct management *man, man->connection.up_query_mode = up_query_mode; man->connection.up_query_type = type; - /* run command processing event loop until we get our username/password */ + /* run command processing event loop until we get our username/password/response */ do { man_standalone_event_loop (man, &signal_received, 0); @@ -2873,6 +2981,82 @@ management_query_user_pass (struct management *man, return ret; } +#ifdef MANAGMENT_EXTERNAL_KEY + +char * /* returns allocated base64 signature */ +management_query_rsa_sig (struct management *man, + const char *b64_data) +{ + struct gc_arena gc = gc_new (); + char *ret = NULL; + 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; + + if (man_standalone_ok (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; + + alert_msg = alloc_buf_gc (strlen(b64_data)+64, &gc); + buf_printf (&alert_msg, ">RSA_SIGN:%s", b64_data); + + man_wait_for_client_connection (man, &signal_received, 0, MWCC_OTHER_WAIT); + + if (signal_received) + goto done; + + man->persist.special_state_msg = BSTR (&alert_msg); + msg (M_CLIENT, "%s", man->persist.special_state_msg); + + /* run command processing event loop until we get our signature */ + do + { + man_standalone_event_loop (man, &signal_received, 0); + if (!signal_received) + man_check_for_signals (&signal_received); + if (signal_received) + goto done; + } while (mc->ext_key_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'; + } + } + } + + 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"); + + /* 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; + + gc_free (&gc); + return ret; +} + +#endif + /* * Return true if management_hold() would block */ @@ -2972,7 +3156,7 @@ command_line_add (struct command_line *cl, const unsigned char *buf, const int l int i; for (i = 0; i < len; ++i) { - if (buf[i] && (isprint(buf[i]) || buf[i] == '\n')) + if (buf[i] && char_class(buf[i], (CC_PRINT|CC_NEWLINE))) { if (!buf_write_u8 (&cl->buf, buf[i])) buf_clear (&cl->buf); @@ -3142,19 +3326,6 @@ log_history_ref (const struct log_history *h, const int index) return NULL; } -#if HTTP_PROXY_FALLBACK - -void -management_http_proxy_fallback_notify (struct management *man, const char *type, const char *remote_ip_hint) -{ - if (remote_ip_hint) - msg (M_CLIENT, ">PROXY:%s,%s", type, remote_ip_hint); - else - msg (M_CLIENT, ">PROXY:%s", type); -} - -#endif /* HTTP_PROXY_FALLBACK */ - #else static void dummy(void) {} #endif /* ENABLE_MANAGEMENT */ diff --git a/manage.h b/src/openvpn/manage.h index 6a9ccd8..28da69f 100644 --- a/manage.h +++ b/src/openvpn/manage.h @@ -156,7 +156,7 @@ struct management_callback void (*delete_event) (void *arg, event_t event); int (*n_clients) (void *arg); #ifdef MANAGEMENT_DEF_AUTH - bool (*kill_by_cid) (void *arg, const unsigned long cid); + bool (*kill_by_cid) (void *arg, const unsigned long cid, const char *kill_msg); bool (*client_auth) (void *arg, const unsigned long cid, const unsigned int mda_key_id, @@ -171,9 +171,8 @@ struct management_callback const unsigned long cid, struct buffer_list *pf_config); /* ownership transferred */ #endif -#if HTTP_PROXY_FALLBACK - bool (*http_proxy_fallback_cmd) (void *arg, const char *server, const char *port, const char *flags); -#endif + bool (*proxy_cmd) (void *arg, const char **p); + bool (*remote_cmd) (void *arg, const char **p); }; /* @@ -264,17 +263,28 @@ struct man_connection { struct command_line *in; struct buffer_list *out; -#ifdef MANAGEMENT_DEF_AUTH +#ifdef MANAGEMENT_IN_EXTRA # define IEC_UNDEF 0 # define IEC_CLIENT_AUTH 1 # define IEC_CLIENT_PF 2 +# define IEC_RSA_SIGN 3 int in_extra_cmd; + struct buffer_list *in_extra; +#ifdef MANAGEMENT_DEF_AUTH unsigned long in_extra_cid; unsigned int in_extra_kid; - struct buffer_list *in_extra; - int env_filter_level; +#endif +#ifdef MANAGMENT_EXTERNAL_KEY +# define EKS_UNDEF 0 +# define EKS_SOLICIT 1 +# define EKS_INPUT 2 +# define EKS_READY 3 + int ext_key_state; + struct buffer_list *ext_key_input; +#endif #endif struct event_set *es; + int env_filter_level; bool state_realtime; bool log_realtime; @@ -285,6 +295,10 @@ struct man_connection { const char *up_query_type; int up_query_mode; struct user_pass up_query; + +#ifdef MANAGMENT_EXTERNAL_KEY + struct buffer_list *rsa_sig; +#endif }; struct management @@ -314,6 +328,12 @@ struct management *management_init (void); # define MF_CLIENT_PF (1<<7) #endif # define MF_UNIX_SOCK (1<<8) +#ifdef MANAGMENT_EXTERNAL_KEY +# define MF_EXTERNAL_KEY (1<<9) +#endif +#define MF_UP_DOWN (1<<10) +#define MF_QUERY_REMOTE (1<<11) +#define MF_QUERY_PROXY (1<<12) bool management_open (struct management *man, const char *addr, @@ -346,7 +366,11 @@ void management_set_callback (struct management *man, void management_clear_callback (struct management *man); -bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, const unsigned int flags); +bool management_query_user_pass (struct management *man, + struct user_pass *up, + const char *type, + const unsigned int flags, + const char *static_challenge); bool management_should_daemonize (struct management *man); bool management_would_hold (struct management *man); @@ -354,6 +378,12 @@ bool management_hold (struct management *man); void management_event_loop_n_seconds (struct management *man, int sec); +void management_up_down(struct management *man, const char *updown, const struct env_set *es); + +void management_notify(struct management *man, const char *severity, const char *type, const char *text); + +void management_notify_generic (struct management *man, const char *str); + #ifdef MANAGEMENT_DEF_AUTH void management_notify_client_needing_auth (struct management *management, const unsigned int auth_id, @@ -374,6 +404,12 @@ void management_learn_addr (struct management *management, const bool primary); #endif +#ifdef MANAGMENT_EXTERNAL_KEY + +char *management_query_rsa_sig (struct management *man, const char *b64_data); + +#endif + static inline bool management_connected (const struct management *man) { @@ -386,6 +422,18 @@ management_query_user_pass_enabled (const struct management *man) return BOOL_CAST(man->settings.flags & MF_QUERY_PASSWORDS); } +static inline bool +management_query_remote_enabled (const struct management *man) +{ + return BOOL_CAST(man->settings.flags & MF_QUERY_REMOTE); +} + +static inline bool +management_query_proxy_enabled (const struct management *man) +{ + return BOOL_CAST(man->settings.flags & MF_QUERY_PROXY); +} + #ifdef MANAGEMENT_PF static inline bool management_enable_pf (const struct management *man) @@ -443,6 +491,11 @@ void management_echo (struct management *man, const char *string, const bool pul void management_auth_failure (struct management *man, const char *type, const char *reason); /* + * Echo an authentication token to management interface + */ +void management_auth_token (struct management *man, const char *token); + +/* * These functions drive the bytecount in/out counters. */ @@ -506,11 +559,5 @@ management_bytes_server (struct management *man, #endif /* MANAGEMENT_DEF_AUTH */ -#if HTTP_PROXY_FALLBACK - -void management_http_proxy_fallback_notify (struct management *man, const char *type, const char *remote_ip_hint); - -#endif /* HTTP_PROXY_FALLBACK */ - #endif #endif diff --git a/mbuf.c b/src/openvpn/mbuf.c index 0f36d3c..82f2388 100644 --- a/mbuf.c +++ b/src/openvpn/mbuf.c @@ -22,6 +22,12 @@ * 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 P2MP diff --git a/mbuf.h b/src/openvpn/mbuf.h index a0de679..a0de679 100644 --- a/mbuf.h +++ b/src/openvpn/mbuf.h diff --git a/memdbg.h b/src/openvpn/memdbg.h index 1f6bb67..1f6bb67 100644 --- a/memdbg.h +++ b/src/openvpn/memdbg.h diff --git a/misc.c b/src/openvpn/misc.c index 4067d85..fcc8552 100644 --- a/misc.c +++ b/src/openvpn/misc.c @@ -22,6 +22,12 @@ * 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" #include "buffer.h" @@ -35,136 +41,18 @@ #include "manage.h" #include "crypto.h" #include "route.h" +#include "console.h" #include "win32.h" #include "memdbg.h" -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE const char *iproute_path = IPROUTE_PATH; /* GLOBAL */ #endif /* contains an SSEC_x value defined in misc.h */ int script_security = SSEC_BUILT_IN; /* GLOBAL */ -/* contains SM_x value defined in misc.h */ -int script_method = SM_EXECVE; /* GLOBAL */ - -/* Redefine the top level directory of the filesystem - to restrict access to files for security */ -void -do_chroot (const char *path) -{ - if (path) - { -#ifdef HAVE_CHROOT - const char *top = "/"; - if (chroot (path)) - msg (M_ERR, "chroot to '%s' failed", path); - if (openvpn_chdir (top)) - msg (M_ERR, "cd to '%s' failed", top); - msg (M_INFO, "chroot to '%s' and cd to '%s' succeeded", path, top); -#else - msg (M_FATAL, "Sorry but I can't chroot to '%s' because this operating system doesn't appear to support the chroot() system call", path); -#endif - } -} - -/* Get/Set UID of process */ - -bool -get_user (const char *username, struct user_state *state) -{ - bool ret = false; - CLEAR (*state); - if (username) - { -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) - state->pw = getpwnam (username); - if (!state->pw) - msg (M_ERR, "failed to find UID for user %s", username); - state->username = username; - ret = true; -#else - msg (M_FATAL, "cannot get UID for user %s -- platform lacks getpwname() or setuid() system calls", username); -#endif - } - return ret; -} - -void -set_user (const struct user_state *state) -{ -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) - if (state->username && state->pw) - { - if (setuid (state->pw->pw_uid)) - msg (M_ERR, "setuid('%s') failed", state->username); - msg (M_INFO, "UID set to %s", state->username); - } -#endif -} - -/* Get/Set GID of process */ - -bool -get_group (const char *groupname, struct group_state *state) -{ - bool ret = false; - CLEAR (*state); - if (groupname) - { -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) - state->gr = getgrnam (groupname); - if (!state->gr) - msg (M_ERR, "failed to find GID for group %s", groupname); - state->groupname = groupname; - ret = true; -#else - msg (M_FATAL, "cannot get GID for group %s -- platform lacks getgrnam() or setgid() system calls", groupname); -#endif - } - return ret; -} - -void -set_group (const struct group_state *state) -{ -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) - if (state->groupname && state->gr) - { - if (setgid (state->gr->gr_gid)) - msg (M_ERR, "setgid('%s') failed", state->groupname); - msg (M_INFO, "GID set to %s", state->groupname); -#ifdef HAVE_SETGROUPS - { - gid_t gr_list[1]; - gr_list[0] = state->gr->gr_gid; - if (setgroups (1, gr_list)) - msg (M_ERR, "setgroups('%s') failed", state->groupname); - } -#endif - } -#endif -} - -/* Change process priority */ -void -set_nice (int niceval) -{ - if (niceval) - { -#ifdef HAVE_NICE - errno = 0; - if (nice (niceval) < 0 && errno != 0) - msg (M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, strerror(errno)); - else - msg (M_INFO, "nice %d succeeded", niceval); -#else - msg (M_WARN, "WARNING: nice %d failed (function not implemented)", niceval); -#endif - } -} - /* * Pass tunnel endpoint and MTU parms to a user-supplied script. * Used to execute the up/down script/plugins. @@ -174,6 +62,7 @@ run_up_down (const char *command, const struct plugin_list *plugins, int plugin_type, const char *arg, + const char *dev_type, int tun_mtu, int link_mtu, const char *ifconfig_local, @@ -191,6 +80,8 @@ run_up_down (const char *command, setenv_int (es, "tun_mtu", tun_mtu); setenv_int (es, "link_mtu", link_mtu); setenv_str (es, "dev", arg); + if (dev_type) + setenv_str (es, "dev_type", dev_type); if (!ifconfig_local) ifconfig_local = ""; @@ -243,7 +134,7 @@ get_pid_file (const char* filename, struct pid_state *state) CLEAR (*state); if (filename) { - state->fp = fopen (filename, "w"); + state->fp = platform_fopen (filename, "w"); if (!state->fp) msg (M_ERR, "Open error on pid file %s", filename); state->filename = filename; @@ -256,74 +147,13 @@ write_pid (const struct pid_state *state) { if (state->filename && state->fp) { - unsigned int pid = openvpn_getpid (); + unsigned int pid = platform_getpid (); fprintf(state->fp, "%u\n", pid); if (fclose (state->fp)) msg (M_ERR, "Close error on pid file %s", state->filename); } } -/* Get current PID */ -unsigned int -openvpn_getpid () -{ -#ifdef WIN32 - return (unsigned int) GetCurrentProcessId (); -#else -#ifdef HAVE_GETPID - return (unsigned int) getpid (); -#else - return 0; -#endif -#endif -} - -/* Disable paging */ -void -do_mlockall(bool print_msg) -{ -#ifdef HAVE_MLOCKALL - if (mlockall (MCL_CURRENT | MCL_FUTURE)) - msg (M_WARN | M_ERRNO, "WARNING: mlockall call failed"); - else if (print_msg) - msg (M_INFO, "mlockall call succeeded"); -#else - msg (M_WARN, "WARNING: mlockall call failed (function not implemented)"); -#endif -} - -#ifndef HAVE_DAEMON - -int -daemon(int nochdir, int noclose) -{ -#if defined(HAVE_FORK) && defined(HAVE_SETSID) - switch (fork()) - { - case -1: - return (-1); - case 0: - break; - default: - openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ - } - - if (setsid() == -1) - return (-1); - - if (!nochdir) - openvpn_chdir ("/"); - - if (!noclose) - set_std_files_to_null (false); -#else - msg (M_FATAL, "Sorry but I can't become a daemon because this operating system doesn't appear to support either the daemon() or fork() system calls"); -#endif - return (0); -} - -#endif - /* * Set standard file descriptors to /dev/null */ @@ -347,19 +177,6 @@ set_std_files_to_null (bool stdin_only) } /* - * Wrapper for chdir library function - */ -int -openvpn_chdir (const char* dir) -{ -#ifdef HAVE_CHDIR - return chdir (dir); -#else - return -1; -#endif -} - -/* * dup inetd/xinetd socket descriptor and save */ @@ -385,9 +202,7 @@ warn_if_group_others_accessible (const char* filename) { #ifndef WIN32 #ifdef HAVE_STAT -#if ENABLE_INLINE_FILES if (strcmp (filename, INLINE_FILE_TAG)) -#endif { struct stat st; if (stat (filename, &st)) @@ -405,32 +220,6 @@ warn_if_group_others_accessible (const char* filename) } /* - * convert system() return into a success/failure value - */ -bool -system_ok (int stat) -{ -#ifdef WIN32 - return stat == 0; -#else - return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0; -#endif -} - -/* - * did system() call execute the given command? - */ -bool -system_executed (int stat) -{ -#ifdef WIN32 - return stat != -1; -#else - return stat != -1 && WEXITSTATUS (stat) != 127; -#endif -} - -/* * Print an error message based on the status code returned by system(). */ const char * @@ -470,7 +259,7 @@ openvpn_execve_check (const struct argv *a, const struct env_set *es, const unsi const int stat = openvpn_execve (a, es, flags); int ret = false; - if (system_ok (stat)) + if (platform_system_ok (stat)) ret = true; else { @@ -508,39 +297,28 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i if (a && a->argv[0]) { -#if defined(ENABLE_EXECVE) +#if defined(ENABLE_FEATURE_EXECVE) if (openvpn_execve_allowed (flags)) { - if (script_method == SM_EXECVE) - { - const char *cmd = a->argv[0]; - char *const *argv = a->argv; - char *const *envp = (char *const *)make_env_array (es, true, &gc); - pid_t pid; - - pid = fork (); - if (pid == (pid_t)0) /* child side */ - { - execve (cmd, argv, envp); - exit (127); - } - else if (pid < (pid_t)0) /* fork failed */ - ; - else /* parent side */ - { - if (waitpid (pid, &ret, 0) != pid) - ret = -1; - } - } - else if (script_method == SM_SYSTEM) - { - ret = openvpn_system (argv_system_str (a), es, flags); - } - else - { - ASSERT (0); - } - } + const char *cmd = a->argv[0]; + char *const *argv = a->argv; + char *const *envp = (char *const *)make_env_array (es, true, &gc); + pid_t pid; + + pid = fork (); + if (pid == (pid_t)0) /* child side */ + { + execve (cmd, argv, envp); + exit (127); + } + else if (pid < (pid_t)0) /* fork failed */ + msg (M_ERR, "openvpn_execve: unable to fork"); + else /* parent side */ + { + if (waitpid (pid, &ret, 0) != pid) + ret = -1; + } + } else if (!warn_shown && (script_security < SSEC_SCRIPTS)) { msg (M_WARN, SCRIPT_SECURITY_WARNING); @@ -552,7 +330,7 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i } else { - msg (M_WARN, "openvpn_execve: called with empty argv"); + msg (M_FATAL, "openvpn_execve: called with empty argv"); } gc_free (&gc); @@ -561,51 +339,72 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i #endif /* - * Wrapper around the system() call. + * Run execve() inside a fork(), duping stdout. Designed to replicate the semantics of popen() but + * in a safer way that doesn't require the invocation of a shell or the risks + * assocated with formatting and parsing a command line. */ int -openvpn_system (const char *command, const struct env_set *es, unsigned int flags) +openvpn_popen (const struct argv *a, const struct env_set *es) { -#ifdef HAVE_SYSTEM - int ret; - - perf_push (PERF_SCRIPT); - - /* - * add env_set to environment. - */ - if (flags & S_SCRIPT) - env_set_add_to_environment (es); - - - /* debugging */ - dmsg (D_SCRIPT, "SYSTEM[%u] '%s'", flags, command); - if (flags & S_SCRIPT) - env_set_print (D_SCRIPT, es); - - /* - * execute the command - */ - ret = system (command); - - /* debugging */ - dmsg (D_SCRIPT, "SYSTEM return=%u", ret); - - /* - * remove env_set from environment - */ - if (flags & S_SCRIPT) - env_set_remove_from_environment (es); - - perf_pop (); - return ret; + struct gc_arena gc = gc_new (); + int ret = -1; + static bool warn_shown = false; + if (a && a->argv[0]) + { +#if defined(ENABLE_FEATURE_EXECVE) + if (script_security >= SSEC_BUILT_IN) + { + const char *cmd = a->argv[0]; + char *const *argv = a->argv; + char *const *envp = (char *const *)make_env_array (es, true, &gc); + pid_t pid; + int pipe_stdout[2]; + + if (pipe (pipe_stdout) == 0) { + pid = fork (); + if (pid == (pid_t)0) /* child side */ + { + close (pipe_stdout[0]); + 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 */ + { + ret=pipe_stdout[0]; + close (pipe_stdout[1]); + } + } + else { + msg (M_WARN, "openvpn_popen: unable to create stdout pipe"); + ret = -1; + } + } + else if (!warn_shown && (script_security < SSEC_SCRIPTS)) + { + msg (M_WARN, SCRIPT_SECURITY_WARNING); + warn_shown = true; + } #else - msg (M_FATAL, "Sorry but I can't execute the shell command '%s' because this operating system doesn't appear to support the system() call", command); - return -1; /* NOTREACHED */ + msg (M_WARN, "openvpn_popen: execve function not available"); #endif + } + else + { + msg (M_FATAL, "openvpn_popen: called with empty argv"); + } + + gc_free (&gc); + return ret; } + + /* * Initialize random number seed. random() is only used * when "weak" random numbers are acceptable. @@ -616,7 +415,6 @@ openvpn_system (const char *command, const struct env_set *es, unsigned int flag void init_random_seed(void) { -#ifdef HAVE_GETTIMEOFDAY struct timeval tv; if (!gettimeofday (&tv, NULL)) @@ -624,10 +422,6 @@ init_random_seed(void) const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; srandom (seed); } -#else /* HAVE_GETTIMEOFDAY */ - const time_t current = time (NULL); - srandom ((unsigned int)current); -#endif /* HAVE_GETTIMEOFDAY */ } /* thread-safe strerror */ @@ -913,7 +707,7 @@ env_set_remove_from_environment (const struct env_set *es) static struct env_item *global_env = NULL; /* GLOBAL */ -static void +void manage_env (char *str) { remove_env_item (str, true, &global_env); @@ -1001,34 +795,20 @@ setenv_str_ex (struct env_set *es, { const char *str = construct_name_value (name_tmp, val_tmp, &gc); env_set_add (es, str); - /*msg (M_INFO, "SETENV_ES '%s'", str);*/ +#if DEBUG_VERBOSE_SETENV + msg (M_INFO, "SETENV_ES '%s'", str); +#endif } else env_set_del (es, name_tmp); } else { -#if defined(WIN32) + char *str = construct_name_value (name_tmp, val_tmp, NULL); + if (platform_putenv(str)) { - /*msg (M_INFO, "SetEnvironmentVariable '%s' '%s'", name_tmp, val_tmp ? val_tmp : "NULL");*/ - if (!SetEnvironmentVariable (name_tmp, val_tmp)) - msg (M_WARN | M_ERRNO, "SetEnvironmentVariable failed, name='%s', value='%s'", - name_tmp, - val_tmp ? val_tmp : "NULL"); + msg (M_WARN | M_ERRNO, "putenv('%s') failed", str); } -#elif defined(HAVE_PUTENV) - { - char *str = construct_name_value (name_tmp, val_tmp, NULL); - int status; - - status = putenv (str); - /*msg (M_INFO, "PUTENV '%s'", str);*/ - if (!status) - manage_env (str); - if (status) - msg (M_WARN | M_ERRNO, "putenv('%s') failed", str); - } -#endif } gc_free (&gc); @@ -1092,35 +872,6 @@ count_netmask_bits(const char *dotted_quad) return ((int)result); } -/* - * Go to sleep for n milliseconds. - */ -void -sleep_milliseconds (unsigned int n) -{ -#ifdef WIN32 - Sleep (n); -#else - struct timeval tv; - tv.tv_sec = n / 1000; - tv.tv_usec = (n % 1000) * 1000; - select (0, NULL, NULL, NULL, &tv); -#endif -} - -/* - * Go to sleep indefinitely. - */ -void -sleep_until_signal (void) -{ -#ifdef WIN32 - ASSERT (0); -#else - select (0, NULL, NULL, NULL, NULL); -#endif -} - /* return true if filename can be opened for read */ bool test_file (const char *filename) @@ -1128,7 +879,7 @@ test_file (const char *filename) bool ret = false; if (filename) { - FILE *fp = fopen (filename, "r"); + FILE *fp = platform_fopen (filename, "r"); if (fp) { fclose (fp); @@ -1143,7 +894,7 @@ test_file (const char *filename) return ret; } -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* create a temporary filename in directory */ const char * @@ -1176,7 +927,7 @@ create_temp_file (const char *directory, const char *prefix, struct gc_arena *gc /* Atomically create the file. Errors out if the file already exists. */ - fd = open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); + fd = platform_open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (fd != -1) { close (fd); @@ -1245,7 +996,13 @@ hostname_randomize(const char *hostname, struct gc_arena *gc) const char * gen_path (const char *directory, const char *filename, struct gc_arena *gc) { - const char *safe_filename = string_mod_const (filename, CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT, 0, '_', gc); +#if 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 + const int CC_PATH_RESERVED = CC_SLASH; +#endif + const char *safe_filename = string_mod_const (filename, CC_PRINT, CC_PATH_RESERVED, '_', gc); if (safe_filename && strcmp (safe_filename, ".") @@ -1272,19 +1029,6 @@ gen_path (const char *directory, const char *filename, struct gc_arena *gc) return NULL; } -/* delete a file, return true if succeeded */ -bool -delete_file (const char *filename) -{ -#if defined(WIN32) - return (DeleteFile (filename) != 0); -#elif defined(HAVE_UNLINK) - return (unlink (filename) == 0); -#else - return false; -#endif -} - bool absolute_pathname (const char *pathname) { @@ -1301,75 +1045,6 @@ absolute_pathname (const char *pathname) return false; } -#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 - -/* - * Get input from console - */ -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) - 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"); -#endif - return ret; -} - /* * Get and store a username/password */ @@ -1398,10 +1073,16 @@ get_user_pass_cr (struct user_pass *up, && ((auth_file && streq (auth_file, "management")) || (from_stdin && (flags & GET_USER_PASS_MANAGEMENT))) && management_query_user_pass_enabled (management)) { + const char *sc = NULL; + if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) management_auth_failure (management, prefix, "previous auth credentials failed"); - if (!management_query_user_pass (management, up, prefix, flags)) +#ifdef ENABLE_CLIENT_CR + if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE)) + sc = auth_challenge; +#endif + if (!management_query_user_pass (management, up, prefix, flags, sc)) { if ((flags & GET_USER_PASS_NOFATAL) != 0) return false; @@ -1433,7 +1114,7 @@ get_user_pass_cr (struct user_pass *up, else if (from_stdin) { #ifdef ENABLE_CLIENT_CR - if (auth_challenge) + if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE)) { struct auth_challenge_info *ac = get_auth_challenge (auth_challenge, &gc); if (ac) @@ -1442,7 +1123,7 @@ get_user_pass_cr (struct user_pass *up, struct buffer packed_resp; buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN); - msg (M_INFO, "CHALLENGE: %s", ac->challenge_text); + msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text); if (!get_console_input ("Response:", BOOL_CAST(ac->flags&CR_ECHO), response, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not read challenge response from stdin"); strncpynt (up->username, ac->user, USER_PASS_LEN); @@ -1472,6 +1153,28 @@ get_user_pass_cr (struct user_pass *up, if (!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)) + { + char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc); + struct buffer packed_resp; + char *pw64=NULL, *resp64=NULL; + + msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge); + if (!get_console_input ("Response:", 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 (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"); + buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN); + buf_printf (&packed_resp, "SCRV1:%s:%s", pw64, resp64); + string_clear(pw64); + free(pw64); + string_clear(resp64); + free(resp64); + } +#endif } } else @@ -1492,7 +1195,7 @@ get_user_pass_cr (struct user_pass *up, warn_if_group_others_accessible (auth_file); - fp = fopen (auth_file, "r"); + fp = platform_fopen (auth_file, "r"); if (!fp) msg (M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file); @@ -1539,42 +1242,8 @@ get_user_pass_cr (struct user_pass *up, #ifdef ENABLE_CLIENT_CR /* - * Parse a challenge message returned along with AUTH_FAILED. - * The message is formatted as such: - * - * CRV1:<flags>:<state_id>:<username_base64>:<challenge_text> - * - * flags: a series of optional, comma-separated flags: - * E : echo the response when the user types it - * R : a response is required - * - * state_id: an opaque string that should be returned to the server - * along with the response. - * - * username_base64 : the username formatted as base64 - * - * challenge_text : the challenge text to be shown to the user - * - * Example challenge: - * - * CRV1:R,E:Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l:Y3Ix:Please enter token PIN - * - * After showing the challenge_text and getting a response from the user - * (if R flag is specified), the client should submit the following - * auth creds back to the OpenVPN server: - * - * Username: [username decoded from username_base64] - * Password: CRV1::<state_id>::<response_text> - * - * Where state_id is taken from the challenge request and response_text - * is what the user entered in response to the challenge_text. - * If the R flag is not present, response_text may be the empty - * string. - * - * Example response (suppose the user enters "8675309" for the token PIN): - * - * Username: cr1 ("Y3Ix" base64 decoded) - * Password: CRV1::Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l::8675309 + * See management/management-notes.txt for more info on the + * the dynamic challenge/response protocol implemented here. */ struct auth_challenge_info * get_auth_challenge (const char *auth_challenge, struct gc_arena *gc) @@ -1618,7 +1287,7 @@ get_auth_challenge (const char *auth_challenge, struct gc_arena *gc) if (!buf_parse(&b, ':', work, len)) return NULL; ac->user = (char *) gc_malloc (strlen(work)+1, true, gc); - base64_decode(work, (void*)ac->user); + openvpn_base64_decode(work, (void*)ac->user, -1); /* parse challenge text */ ac->challenge_text = string_alloc(BSTR(&b), gc); @@ -1633,49 +1302,30 @@ get_auth_challenge (const char *auth_challenge, struct gc_arena *gc) #if AUTO_USERID -static const char * -get_platform_prefix (void) -{ -#if defined(TARGET_LINUX) - return "L"; -#elif defined(TARGET_SOLARIS) - return "S"; -#elif defined(TARGET_OPENBSD) - return "O"; -#elif defined(TARGET_DARWIN) - return "M"; -#elif defined(TARGET_NETBSD) - return "N"; -#elif defined(TARGET_FREEBSD) - return "F"; -#elif defined(WIN32) - return "W"; -#else - return "X"; -#endif -} - void get_user_pass_auto_userid (struct user_pass *up, const char *tag) { struct gc_arena gc = gc_new (); - MD5_CTX ctx; struct buffer buf; uint8_t macaddr[6]; static uint8_t digest [MD5_DIGEST_LENGTH]; static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST"; + const md_kt_t *md5_kt = md_kt_get("MD5"); + md_ctx_t ctx; + CLEAR (*up); buf_set_write (&buf, (uint8_t*)up->username, USER_PASS_LEN); - buf_printf (&buf, "%s", get_platform_prefix ()); + buf_printf (&buf, "%s", TARGET_PREFIX); if (get_default_gateway_mac_addr (macaddr)) { dmsg (D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex (macaddr, sizeof (macaddr), 0, 1, ":", &gc)); - MD5_Init (&ctx); - MD5_Update (&ctx, hashprefix, sizeof (hashprefix) - 1); - MD5_Update (&ctx, macaddr, sizeof (macaddr)); - MD5_Final (digest, &ctx); - buf_printf (&buf, "%s", format_hex_ex (digest, sizeof (digest), 0, 256, " ", &gc)); + md_ctx_init(&ctx, md5_kt); + md_ctx_update(&ctx, hashprefix, sizeof (hashprefix) - 1); + md_ctx_update(&ctx, macaddr, sizeof (macaddr)); + md_ctx_final(&ctx, digest); + md_ctx_cleanup(&ctx) + buf_printf(&buf, "%s", format_hex_ex (digest, sizeof (digest), 0, 256, " ", &gc)); } else { @@ -1708,6 +1358,16 @@ purge_user_pass (struct user_pass *up, const bool force) } } +void +set_auth_token (struct user_pass *up, const char *token) +{ + if (token && strlen(token) && up && up->defined && !up->nocache) + { + CLEAR (up->password); + strncpynt (up->password, token, USER_PASS_LEN); + } +} + /* * Process string received by untrusted peer before * printing to console or log file. @@ -1808,7 +1468,6 @@ make_arg_array (const char *first, const char *parms, struct gc_arena *gc) return (const char **)ret; } -#if ENABLE_INLINE_FILES static const char ** make_inline_array (const char *str, struct gc_arena *gc) { @@ -1837,7 +1496,6 @@ make_inline_array (const char *str, struct gc_arena *gc) ret[i] = NULL; return (const char **)ret; } -#endif static const char ** make_arg_copy (char **p, struct gc_arena *gc) @@ -1860,11 +1518,9 @@ const char ** make_extended_arg_array (char **p, struct gc_arena *gc) { const int argc = string_array_len ((const char **)p); -#if ENABLE_INLINE_FILES if (!strcmp (p[0], INLINE_FILE_TAG) && argc == 2) return make_inline_array (p[1], gc); else -#endif if (argc == 0) return make_arg_array (NULL, NULL, gc); else if (argc == 1) @@ -2010,13 +1666,15 @@ argv_extract_cmd_name (const char *path) { if (path) { - const char *bn = openvpn_basename (path); + char *path_cp = strdup(path); /* POSIX basename() implementaions may modify its arguments */ + const char *bn = basename (path_cp); if (bn) { char *ret = string_alloc (bn, NULL); char *dot = strrchr (ret, '.'); if (dot) *dot = '\0'; + free(path_cp); if (ret[0] != '\0') return ret; } @@ -2290,17 +1948,17 @@ argv_test (void) 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"); + /*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"); + /*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"); + /*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); @@ -2358,21 +2016,74 @@ argv_test (void) } #endif +/* + * Remove security-sensitive strings from control message + * so that they will not be output to log file. + */ const char * -openvpn_basename (const char *path) +sanitize_control_message(const char *src, struct gc_arena *gc) { - const char *ret; - const int dirsep = OS_SPECIFIC_DIRSEP; + char *ret = gc_malloc (strlen(src)+1, false, gc); + char *dest = ret; + bool redact = false; + int skip = 0; - if (path) + for (;;) { - ret = strrchr (path, dirsep); - if (ret && *ret) - ++ret; + const char c = *src; + if (c == '\0') + break; + if (c == 'S' && !strncmp(src, "SESS_ID_", 8)) + { + skip = 7; + redact = true; + } + else if (c == 'e' && !strncmp(src, "echo ", 5)) + { + skip = 4; + redact = true; + } + + if (c == ',') /* end of redacted item? */ + { + skip = 0; + redact = false; + } + + if (redact) + { + if (skip > 0) + { + --skip; + *dest++ = c; + } + } else - ret = path; - if (*ret) - return ret; + *dest++ = c; + + ++src; } - return NULL; + *dest = '\0'; + return ret; +} + +/** + * Will set or query for a global compat flag. To modify the compat flags + * the COMPAT_FLAG_SET must be bitwise ORed together with the flag to set. + * If no "operator" flag is given it defaults to COMPAT_FLAG_QUERY, + * which returns the flag state. + * + * @param flag Flag to be set/queried for bitwise ORed with the operator flag + * @return Returns 0 if the flag is not set, otherwise the 'flag' value is returned + */ +bool +compat_flag (unsigned int flag) +{ + static unsigned int compat_flags = 0; + + if (flag & COMPAT_FLAG_SET) + compat_flags |= (flag >> 1); + + return (compat_flags & (flag >> 1)); + } diff --git a/misc.h b/src/openvpn/misc.h index 3f22ca0..183898e 100644 --- a/misc.h +++ b/src/openvpn/misc.h @@ -29,6 +29,7 @@ #include "common.h" #include "integer.h" #include "buffer.h" +#include "platform.h" /* socket descriptor passed by inetd/xinetd server to us */ #define INETD_SOCKET_DESCRIPTOR 0 @@ -58,41 +59,11 @@ struct env_set { struct env_item *list; }; -/* Get/Set UID of process */ - -struct user_state { -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) - const char *username; - struct passwd *pw; -#else - int dummy; -#endif -}; - -bool get_user (const char *username, struct user_state *state); -void set_user (const struct user_state *state); - -/* Get/Set GID of process */ - -struct group_state { -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) - const char *groupname; - struct group *gr; -#else - int dummy; -#endif -}; - -bool get_group (const char *groupname, struct group_state *state); -void set_group (const struct group_state *state); - -void set_nice (int niceval); -void do_chroot (const char *path); - void run_up_down (const char *command, const struct plugin_list *plugins, int plugin_type, const char *arg, + const char *dev_type, int tun_mtu, int link_mtu, const char *ifconfig_local, @@ -110,13 +81,6 @@ struct pid_state { void get_pid_file (const char* filename, struct pid_state *state); void write_pid (const struct pid_state *state); -unsigned int openvpn_getpid (void); - -void do_mlockall (bool print_msg); /* Disable paging */ - -#ifndef HAVE_DAEMON -int daemon (int nochdir, int noclose); -#endif /* check file protections */ void warn_if_group_others_accessible(const char* filename); @@ -125,16 +89,13 @@ void warn_if_group_others_accessible(const char* filename); #define S_SCRIPT (1<<0) #define S_FATAL (1<<1) -/* interpret the status code returned by system()/execve() */ -bool system_ok(int); -bool system_executed (int stat); const char *system_error_message (int, struct gc_arena *gc); /* wrapper around the execve() call */ +int openvpn_popen (const struct argv *a, const struct env_set *es); int openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags); bool openvpn_execve_check (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message); bool openvpn_execve_allowed (const unsigned int flags); -int openvpn_system (const char *command, const struct env_set *es, unsigned int flags); static inline bool openvpn_run_script (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook) @@ -143,7 +104,8 @@ openvpn_run_script (const struct argv *a, const struct env_set *es, const unsign openvpn_snprintf(msg, sizeof(msg), "WARNING: Failed running command (%s)", hook); return openvpn_execve_check(a, es, flags | S_SCRIPT, msg); -}; +} + #ifdef HAVE_STRERROR /* a thread-safe version of strerror */ @@ -153,14 +115,11 @@ const char* strerror_ts (int errnum, struct gc_arena *gc); /* Set standard file descriptors to /dev/null */ void set_std_files_to_null (bool stdin_only); -/* Wrapper for chdir library function */ -int openvpn_chdir (const char* dir); - /* dup inetd/xinetd socket descriptor and save */ extern int inetd_socket_descriptor; void save_inetd_socket_descriptor (void); -/* init random() function, only used as source for weak random numbers, when !USE_CRYPTO */ +/* init random() function, only used as source for weak random numbers, when !ENABLE_CRYPTO */ void init_random_seed(void); /* set/delete environmental variable */ @@ -211,14 +170,8 @@ const char **make_extended_arg_array (char **p, struct gc_arena *gc); int count_netmask_bits(const char *); unsigned int count_bits(unsigned int ); -/* go to sleep for n milliseconds */ -void sleep_milliseconds (unsigned int n); - -/* go to sleep indefinitely */ -void sleep_until_signal (void); - /* an analogue to the random() function, but use OpenSSL functions if available */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO long int get_random(void); #else #define get_random random @@ -233,13 +186,10 @@ const char *create_temp_file (const char *directory, const char *prefix, struct /* put a directory and filename together */ const char *gen_path (const char *directory, const char *filename, struct gc_arena *gc); -/* delete a file, return true if succeeded */ -bool delete_file (const char *filename); - /* return true if pathname is absolute */ bool absolute_pathname (const char *pathname); -/* prepend a random prefix to hostname (need USE_CRYPTO) */ +/* prepend a random prefix to hostname (need ENABLE_CRYPTO) */ const char *hostname_randomize(const char *hostname, struct gc_arena *gc); /* @@ -277,12 +227,21 @@ struct auth_challenge_info { struct auth_challenge_info *get_auth_challenge (const char *auth_challenge, struct gc_arena *gc); +/* + * Challenge response info on client as pushed by server. + */ +struct static_challenge_info { +# define SC_ECHO (1<<0) /* echo response when typed by user */ + unsigned int flags; + + const char *challenge_text; +}; + #else struct auth_challenge_info {}; +struct static_challenge_info {}; #endif -bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity); - /* * Flags for get_user_pass and management_query_user_pass */ @@ -294,6 +253,10 @@ bool get_console_input (const char *prompt, const bool echo, char *input, const #define GET_USER_PASS_NEED_STR (1<<5) #define GET_USER_PASS_PREVIOUS_CREDS_FAILED (1<<6) +#define GET_USER_PASS_DYNAMIC_CHALLENGE (1<<7) /* CRV1 protocol -- dynamic challenge */ +#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 */ + bool get_user_pass_cr (struct user_pass *up, const char *auth_file, const char *prefix, @@ -315,6 +278,8 @@ void fail_user_pass (const char *prefix, void purge_user_pass (struct user_pass *up, const bool force); +void set_auth_token (struct user_pass *up, const char *token); + /* * Process string received by untrusted peer before * printing to console or log file. @@ -336,6 +301,8 @@ void openvpn_sleep (const int n); void configure_path (void); +const char *sanitize_control_message(const char *str, struct gc_arena *gc); + #if AUTO_USERID void get_user_pass_auto_userid (struct user_pass *up, const char *tag); #endif @@ -343,7 +310,7 @@ void get_user_pass_auto_userid (struct user_pass *up, const char *tag); /* * /sbin/ip path, may be overridden */ -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE extern const char *iproute_path; #endif @@ -354,16 +321,9 @@ extern const char *iproute_path; #define SSEC_PW_ENV 3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */ extern int script_security; /* GLOBAL */ -#define SM_EXECVE 0 /* call external programs with execve() or CreateProcess() */ -#define SM_SYSTEM 1 /* call external programs with system() */ -extern int script_method; /* GLOBAL */ - /* return the next largest power of 2 */ size_t adjust_power_of_2 (size_t u); -/* return the basename of path */ -const char *openvpn_basename (const char *path); - /* * A printf-like function (that only recognizes a subset of standard printf * format operators) that prints arguments to an argv list instead @@ -385,38 +345,28 @@ void argv_printf_arglist (struct argv *a, const char *format, const unsigned int void argv_printf (struct argv *a, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 2, 3))) +#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__ - __attribute__ ((format (printf, 2, 3))) +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format (gnu_printf, 2, 3))) +#else + __attribute__ ((format (__printf__, 2, 3))) #endif - ; - -/* - * Extract UID or GID - */ - -static inline int -user_state_uid (const struct user_state *s) -{ -#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) - if (s->pw) - return s->pw->pw_uid; #endif - return -1; -} + ; -static inline int -group_state_gid (const struct group_state *s) -{ -#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) - if (s->gr) - return s->gr->gr_gid; -#endif - return -1; -} +#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); #endif diff --git a/mroute.c b/src/openvpn/mroute.c index 3debd80..850e336 100644 --- a/mroute.c +++ b/src/openvpn/mroute.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER @@ -46,7 +52,7 @@ mroute_addr_init (struct mroute_addr *addr) static inline bool is_mac_mcast_addr (const uint8_t *mac) { - return (bool) mac[0] & 1; + return (bool) (mac[0] & 1); } static inline bool @@ -88,12 +94,33 @@ mroute_get_in_addr_t (struct mroute_addr *ma, const in_addr_t src, unsigned int } } +static inline void +mroute_get_in6_addr (struct mroute_addr *ma, const struct in6_addr src, unsigned int mask) +{ + if (ma) + { + ma->type = MR_ADDR_IPV6 | mask; + ma->netbits = 0; + ma->len = 16; + *(struct in6_addr *)ma->addr = src; + } +} + static inline bool mroute_is_mcast (const in_addr_t addr) { return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK)); } +/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies + * the address as being a multicast address" + */ +static inline bool +mroute_is_mcast_ipv6 (const struct in6_addr addr) +{ + return (addr.s6_addr[0] == 0xff); +} + #ifdef ENABLE_PF static unsigned int @@ -155,10 +182,29 @@ mroute_extract_addr_ipv4 (struct mroute_addr *src, } break; case 6: - { - msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet"); - break; - } + if (BLEN (buf) >= (int) sizeof (struct openvpn_ipv6hdr)) + { + const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR (buf); +#if 0 /* very basic debug */ + struct gc_arena gc = gc_new (); + msg( M_INFO, "IPv6 packet! src=%s, dst=%s", + print_in6_addr( ipv6->saddr, 0, &gc ), + print_in6_addr( ipv6->daddr, 0, &gc )); + gc_free (&gc); +#endif + + mroute_get_in6_addr (src, ipv6->saddr, 0); + mroute_get_in6_addr (dest, ipv6->daddr, 0); + + if (mroute_is_mcast_ipv6 (ipv6->daddr)) + ret |= MROUTE_EXTRACT_MCAST; + + ret |= MROUTE_EXTRACT_SUCCEEDED; + } + break; + default: + msg (M_WARN, "IP packet with unknown IP version=%d seen", + OPENVPN_IPH_GET_VER (*BPTR(buf))); } } return ret; @@ -226,25 +272,45 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port) { - if (osaddr->sa.sin_family == AF_INET) + switch (osaddr->addr.sa.sa_family) + { + case AF_INET: { if (use_port) { addr->type = MR_ADDR_IPV4 | MR_WITH_PORT; addr->netbits = 0; addr->len = 6; - memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4); - memcpy (addr->addr + 4, &osaddr->sa.sin_port, 2); + memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4); + memcpy (addr->addr + 4, &osaddr->addr.in4.sin_port, 2); } else { addr->type = MR_ADDR_IPV4; addr->netbits = 0; addr->len = 4; - memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4); + memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4); } return true; } + case AF_INET6: + if (use_port) + { + 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); + } + else + { + addr->type = MR_ADDR_IPV6; + addr->netbits = 0; + addr->len = 16; + memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16); + } + return true; + } return false; } @@ -252,14 +318,36 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr, * Zero off the host bits in an address, leaving * only the network bits, using the netbits member of * struct mroute_addr as the controlling parameter. + * + * TODO: this is called for route-lookup for every yet-unhashed + * destination address, so for lots of active net-iroutes, this + * might benefit from some "zeroize 32 bit at a time" improvements */ void mroute_addr_mask_host_bits (struct mroute_addr *ma) { in_addr_t addr = ntohl(*(in_addr_t*)ma->addr); - ASSERT ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4); - addr &= netbits_to_netmask (ma->netbits); - *(in_addr_t*)ma->addr = htonl (addr); + if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4) + { + addr &= netbits_to_netmask (ma->netbits); + *(in_addr_t*)ma->addr = htonl (addr); + } + else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6) + { + int byte = ma->len-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; } + else + { ma->addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear); bits_to_clear = 0; } + } + ASSERT( bits_to_clear == 0 ); + } + else + ASSERT(0); } /* @@ -337,17 +425,24 @@ mroute_addr_print_ex (const struct mroute_addr *ma, } break; case MR_ADDR_IPV6: - buf_printf (&out, "IPV6"); - break; - default: - buf_printf (&out, "UNKNOWN"); - break; - } - return BSTR (&out); - } - else - return "[NULL]"; -} + { + buf_printf (&out, "%s", + print_in6_addr( *(struct in6_addr*)&maddr.addr, 0, gc)); + if (maddr.type & MR_WITH_NETBITS) + { + buf_printf (&out, "/%d", maddr.netbits); + } + } + break; + default: + buf_printf (&out, "UNKNOWN"); + break; + } + return BSTR (&out); + } + else + return "[NULL]"; + } /* * mroute_helper's main job is keeping track of @@ -418,6 +513,40 @@ mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir) } } +/* 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) +{ + if (ir6->netbits >= 0) + { + ASSERT (ir6->netbits < MR_HELPER_NET_LEN); + ++mh->cache_generation; + ++mh->net_len_refcount[ir6->netbits]; + if (mh->net_len_refcount[ir6->netbits] == 1) + mroute_helper_regenerate (mh); + } +} + +void +mroute_helper_del_iroute6 (struct mroute_helper *mh, + const struct iroute_ipv6 *ir6) +{ + if (ir6->netbits >= 0) + { + ASSERT (ir6->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]) + mroute_helper_regenerate (mh); + } +} + void mroute_helper_free (struct mroute_helper *mh) { diff --git a/mroute.h b/src/openvpn/mroute.h index 7265001..b72b5ff 100644 --- a/mroute.h +++ b/src/openvpn/mroute.h @@ -85,7 +85,7 @@ struct mroute_addr { /* * Number of bits in an address. Should be raised for IPv6. */ -#define MR_HELPER_NET_LEN 32 +#define MR_HELPER_NET_LEN 129 /* * Used to help maintain CIDR routing table. @@ -127,6 +127,8 @@ 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); /* * Given a raw packet in buf, return the src and dest diff --git a/mss.c b/src/openvpn/mss.c index 660b62c..8981bad 100644 --- a/mss.c +++ b/src/openvpn/mss.c @@ -22,6 +22,12 @@ * 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" #include "error.h" #include "mss.h" diff --git a/mss.h b/src/openvpn/mss.h index 0b290c3..0b290c3 100644 --- a/mss.h +++ b/src/openvpn/mss.h diff --git a/src/openvpn/mstats.c b/src/openvpn/mstats.c new file mode 100644 index 0000000..3be493c --- /dev/null +++ b/src/openvpn/mstats.c @@ -0,0 +1,122 @@ +/* + * 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-2011 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 + */ + +/* + * Maintain usage stats in a memory-mapped file + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#if defined(ENABLE_MEMSTATS) + +#include <sys/mman.h> + +#include "error.h" +#include "misc.h" +#include "mstats.h" + +#include "memdbg.h" + +volatile struct mmap_stats *mmap_stats = NULL; /* GLOBAL */ +static char mmap_fn[128]; + +void +mstats_open(const char *fn) +{ + void *data; + ssize_t stat; + int fd; + struct mmap_stats ms; + + if (mmap_stats) /* already called? */ + return; + + /* verify that filename is not too long */ + if (strlen(fn) >= sizeof(mmap_fn)) + msg (M_FATAL, "mstats_open: filename too long"); + + /* create file that will be memory mapped */ + fd = open (fn, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) + { + msg (M_ERR, "mstats_open: cannot open: %s", fn); + return; + } + + /* set the file to the correct size to contain a + struct mmap_stats, and zero it */ + CLEAR(ms); + ms.state = MSTATS_ACTIVE; + stat = write(fd, &ms, sizeof(ms)); + if (stat != sizeof(ms)) + { + msg (M_ERR, "mstats_open: write error: %s", fn); + close(fd); + return; + } + + /* mmap the file */ + data = mmap(NULL, sizeof(struct mmap_stats), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) + { + msg (M_ERR, "mstats_open: write error: %s", fn); + close(fd); + return; + } + + /* close the fd (mmap now controls the file) */ + if (close(fd)) + { + msg (M_ERR, "mstats_open: close error: %s", fn); + } + + /* save filename so we can delete it later */ + strcpy(mmap_fn, fn); + + /* save a global pointer to memory-mapped region */ + mmap_stats = (struct mmap_stats *)data; + + msg (M_INFO, "memstats data will be written to %s", fn); +} + +void +mstats_close(void) +{ + if (mmap_stats) + { + mmap_stats->state = MSTATS_EXPIRED; + if (munmap((void *)mmap_stats, sizeof(struct mmap_stats))) + msg (M_WARN | M_ERRNO, "mstats_close: munmap error"); + platform_unlink(mmap_fn); + mmap_stats = NULL; + } +} + +#endif diff --git a/mudp.h b/src/openvpn/mstats.h index dc9cfde..dab05fe 100644 --- a/mudp.h +++ b/src/openvpn/mstats.h @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2011 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 @@ -23,20 +23,29 @@ */ /* - * UDP specific code for --mode server + * Maintain usage stats in a memory-mapped file */ -#ifndef MUDP_H -#define MUDP_H +#if !defined(OPENVPN_MEMSTATS_H) && defined(ENABLE_MEMSTATS) +#define OPENVPN_MEMSTATS_H -#if P2MP_SERVER +#include "basic.h" -struct context; -struct multi_context; +/* this struct is mapped to the file */ +struct mmap_stats { + counter_type link_read_bytes; /* counter_type can be assumed to be a uint64_t */ + counter_type link_write_bytes; + int n_clients; -void tunnel_server_udp (struct context *top); +# define MSTATS_UNDEF 0 +# define MSTATS_ACTIVE 1 +# define MSTATS_EXPIRED 2 + int state; +}; -struct multi_instance *multi_get_create_instance_udp (struct multi_context *m); +extern volatile struct mmap_stats *mmap_stats; /* GLOBAL */ + +void mstats_open(const char *fn); +void mstats_close(void); -#endif #endif diff --git a/mtcp.c b/src/openvpn/mtcp.c index 314aa44..dc15f09 100644 --- a/mtcp.c +++ b/src/openvpn/mtcp.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER @@ -150,6 +156,9 @@ multi_tcp_instance_specific_init (struct multi_context *m, struct multi_instance ASSERT (mi->context.c2.link_socket); ASSERT (mi->context.c2.link_socket->info.lsa); ASSERT (mi->context.c2.link_socket->mode == LS_MODE_TCP_ACCEPT_FROM); + ASSERT (mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET + || mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6 + ); if (!mroute_extract_openvpn_sockaddr (&mi->real, &mi->context.c2.link_socket->info.lsa->actual.dest, true)) { msg (D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined"); diff --git a/mtcp.h b/src/openvpn/mtcp.h index 3585af4..b677b48 100644 --- a/mtcp.h +++ b/src/openvpn/mtcp.h @@ -60,8 +60,17 @@ void multi_tcp_instance_specific_free (struct multi_instance *mi); void multi_tcp_link_out_deferred (struct multi_context *m, struct multi_instance *mi); + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in TCP server mode. + * @ingroup eventloop + * + * @param top - Top-level context structure. + */ void tunnel_server_tcp (struct context *top); + void multi_tcp_delete_event (struct multi_tcp *mtcp, event_t event); #endif diff --git a/mtu.c b/src/openvpn/mtu.c index 494f939..13f3f6c 100644 --- a/mtu.c +++ b/src/openvpn/mtu.c @@ -22,6 +22,12 @@ * 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" #include "common.h" diff --git a/mtu.h b/src/openvpn/mtu.h index d9fa020..29ec21f 100644 --- a/mtu.h +++ b/src/openvpn/mtu.h @@ -86,39 +86,43 @@ */ #define PAYLOAD_ALIGN 4 -struct frame { - /* - * Maximum datagram size to be sent over the tunnel TCP/UDP channel. - */ - int link_mtu; - int link_mtu_dynamic; - - /* - * How many extra bytes might each subsystem (crypto, TLS, or, compression) - * add to frame in worst case? - * - * mtu + extra_frame = MTU of TCP/UDP transport - */ - int extra_frame; - - /* - * Worst case size added to internal buffer due to functions - * such as compression which can potentially expand the size of uncompressible - * data. - */ - int extra_buffer; - - /* - * Max number of bytes in excess of tun mtu size that we might read - * or write from TUN/TAP device. - */ - int extra_tun; - /* - * Max number of bytes in excess of link mtu size that we might read - * or write from UDP/TCP link. - */ - int extra_link; +/**************************************************************************/ +/** + * Packet geometry parameters. + */ +struct frame { + int link_mtu; /**< Maximum packet size to be sent over + * the external network interface. */ + + int link_mtu_dynamic; /**< Dynamic MTU value for the external + * network interface. */ + + int extra_frame; /**< Maximum number of bytes that all + * processing steps together could add. + * @code + * frame.link_mtu = "socket MTU" - extra_frame; + * @endcode + */ + + int extra_buffer; /**< Maximum number of bytes that + * processing steps could expand the + * internal work buffer. + * + * This is used by the \link compression + * Data Channel Compression + * module\endlink to give enough working + * space for worst-case expansion of + * incompressible content. */ + + int extra_tun; /**< Maximum number of bytes in excess of + * the tun/tap MTU that might be read + * from or written to the virtual + * tun/tap network interface. */ + + int extra_link; /**< Maximum number of bytes in excess of + * external network interface's MTU that + * might be read from or written to it. */ /* * Alignment control diff --git a/mudp.c b/src/openvpn/mudp.c index a478b29..3468dab 100644 --- a/mudp.c +++ b/src/openvpn/mudp.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER @@ -199,9 +205,17 @@ p2mp_iow_flags (const struct multi_context *m) return flags; } -/* - * Top level event loop for single-threaded operation. - * UDP mode. + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in UDP server mode. + * @ingroup eventloop + * + * This function implements OpenVPN's main event loop for UDP server mode. + * At this time, OpenVPN does not yet support multithreading. This + * function's name is therefore slightly misleading. + * + * @param top - Top-level context structure. */ static void tunnel_server_udp_single_threaded (struct context *top) diff --git a/src/openvpn/mudp.h b/src/openvpn/mudp.h new file mode 100644 index 0000000..97f961b --- /dev/null +++ b/src/openvpn/mudp.h @@ -0,0 +1,71 @@ +/* + * 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 + */ + +/* + * UDP specific code for --mode server + */ + +#ifndef MUDP_H +#define MUDP_H + +#if P2MP_SERVER + +struct context; +struct multi_context; + + +/**************************************************************************/ +/** + * Main event loop wrapper function for OpenVPN in UDP server mode. + * @ingroup eventloop + * + * This function simply calls \c tunnel_server_udp_single_threaded(). + * + * @param top - Top-level context structure. + */ +void tunnel_server_udp (struct context *top); + + +/**************************************************************************/ +/** + * Get, and if necessary create, the multi_instance associated with a + * packet's source address. + * @ingroup external_multiplexer + * + * This function extracts the source address of a recently read packet + * from \c m->top.c2.from and uses that source address as a hash key for + * the hash table \c m->hash. If an entry exists, this function returns + * it. If no entry exists, this function handles its creation, and if + * successful, returns the newly created instance. + * + * @param m - The single multi_context structure. + * + * @return A pointer to a multi_instance if one already existed for the + * 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); + +#endif +#endif diff --git a/multi.c b/src/openvpn/multi.c index 22c0a3f..9876b80 100644 --- a/multi.c +++ b/src/openvpn/multi.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER @@ -31,6 +37,7 @@ #include "misc.h" #include "otime.h" #include "gremlin.h" +#include "mstats.h" #include "memdbg.h" @@ -60,6 +67,15 @@ set_cc_config (struct multi_instance *mi, struct buffer_list *cc_config) } #endif +static inline void +update_mstat_n_clients(const int n_clients) +{ +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->n_clients = n_clients; +#endif +} + static bool learn_address_script (const struct multi_context *m, const struct multi_instance *mi, @@ -316,25 +332,18 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa */ if (t->options.ifconfig_pool_defined) { - if (dev == DEV_TYPE_TAP) - { - m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV, - t->options.ifconfig_pool_start, - t->options.ifconfig_pool_end, - t->options.duplicate_cn); - } - else if (dev == DEV_TYPE_TUN) - { - m->ifconfig_pool = ifconfig_pool_init ( - (t->options.topology == TOP_NET30) ? IFCONFIG_POOL_30NET : IFCONFIG_POOL_INDIV, - t->options.ifconfig_pool_start, - t->options.ifconfig_pool_end, - t->options.duplicate_cn); - } - else - { - ASSERT (0); - } + int pool_type = IFCONFIG_POOL_INDIV; + + if ( dev == DEV_TYPE_TUN && t->options.topology == TOP_NET30 ) + pool_type = IFCONFIG_POOL_30NET; + + m->ifconfig_pool = ifconfig_pool_init (pool_type, + t->options.ifconfig_pool_start, + t->options.ifconfig_pool_end, + t->options.duplicate_cn, + t->options.ifconfig_ipv6_pool_defined, + t->options.ifconfig_ipv6_pool_base, + t->options.ifconfig_ipv6_pool_netbits ); /* reload pool data from file */ if (t->c1.ifconfig_pool_persist) @@ -375,6 +384,14 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa * tun/tap interface and network stack? */ m->enable_c2c = t->options.enable_c2c; + + /* initialize stale routes check timer */ + if (t->options.stale_routes_check_interval > 0) + { + msg (M_INFO, "Initializing stale route check timer to run every %i seconds and to removing routes with activity timeout older than %i seconds", + 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); + } } const char * @@ -429,10 +446,14 @@ multi_del_iroutes (struct multi_context *m, struct multi_instance *mi) { const struct iroute *ir; + const struct iroute_ipv6 *ir6; 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); + + for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next ) + mroute_helper_del_iroute6 (m->route_helper, ir6); } } @@ -505,6 +526,7 @@ multi_close_instance (struct multi_context *m, /* adjust current client connection count */ m->n_clients += mi->n_clients_delta; + update_mstat_n_clients(m->n_clients); mi->n_clients_delta = 0; /* prevent dangling pointers */ @@ -629,7 +651,7 @@ multi_create_instance (struct multi_context *m, const struct mroute_addr *real) perf_push (PERF_MULTI_CREATE_INSTANCE); - msg (D_MULTI_LOW, "MULTI: multi_create_instance called"); + msg (D_MULTI_MEDIUM, "MULTI: multi_create_instance called"); ALLOC_OBJ_CLEAR (mi, struct multi_instance); @@ -785,8 +807,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)", - sep, sep, sep, sep, sep, sep, sep, sep); + 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); hash_iterator_init (m->hash, &hi); while ((he = hash_iterator_next (&hi))) { @@ -795,14 +817,15 @@ 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", + status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u%c%s", 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, 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, (unsigned int)mi->created, + sep, tls_username (mi->context.c2.tls_multi, false)); } gc_free (&gc); } @@ -1058,8 +1081,8 @@ multi_learn_in_addr_t (struct multi_context *m, struct mroute_addr addr; CLEAR (remote_si); - remote_si.sa.sin_family = AF_INET; - remote_si.sa.sin_addr.s_addr = htonl (a); + remote_si.addr.in4.sin_family = AF_INET; + remote_si.addr.in4.sin_addr.s_addr = htonl (a); ASSERT (mroute_extract_openvpn_sockaddr (&addr, &remote_si, false)); if (netbits >= 0) @@ -1078,6 +1101,37 @@ multi_learn_in_addr_t (struct multi_context *m, } } +static struct multi_instance * +multi_learn_in6_addr (struct multi_context *m, + struct multi_instance *mi, + struct in6_addr a6, + int netbits, /* -1 if host route, otherwise # of network bits in address */ + bool primary) +{ + struct mroute_addr addr; + + addr.len = 16; + addr.type = MR_ADDR_IPV6; + addr.netbits = 0; + memcpy( &addr.addr, &a6, sizeof(a6) ); + + if (netbits >= 0) + { + addr.type |= MR_WITH_NETBITS; + addr.netbits = (uint8_t) netbits; + mroute_addr_mask_host_bits( &addr ); + } + + { + struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0); +#ifdef MANAGEMENT_DEF_AUTH + if (management && owner) + management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary); +#endif + return owner; + } +} + /* * A new client has connected, add routes (server -> client) * to internal routing table. @@ -1088,6 +1142,7 @@ multi_add_iroutes (struct multi_context *m, { struct gc_arena gc = gc_new (); const struct iroute *ir; + const struct iroute_ipv6 *ir6; if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN) { mi->did_iroutes = true; @@ -1107,6 +1162,22 @@ multi_add_iroutes (struct multi_context *m, 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", + 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); + + multi_learn_in6_addr (m, mi, ir6->network, ir6->netbits, false); + } } gc_free (&gc); } @@ -1151,6 +1222,32 @@ multi_delete_dup (struct multi_context *m, struct multi_instance *new_mi) } } +static void +check_stale_routes (struct multi_context *m) +{ + + struct gc_arena gc = gc_new (); + struct hash_iterator hi; + struct hash_element *he; + + dmsg (D_MULTI_DEBUG, "MULTI: Checking stale routes"); + hash_iterator_init_range (m->vhash, &hi, 0, hash_n_buckets (m->vhash)); + while ((he = hash_iterator_next (&hi)) != NULL) + { + struct multi_route *r = (struct multi_route *) he->value; + if (multi_route_defined (m, r) && difftime(now, r->last_reference) >= m->top.options.stale_routes_ageing_time) + { + dmsg (D_MULTI_DEBUG, "MULTI: Deleting stale route for address '%s'", + mroute_addr_print (&r->addr, &gc)); + learn_address_script (m, NULL, "delete", &r->addr); + multi_route_del (r); + hash_iterator_delete_element (&hi); + } + } + hash_iterator_free (&hi); + gc_free (&gc); +} + /* * Ensure that endpoint to be pushed to client * complies with --ifconfig-push-constraint directive. @@ -1192,21 +1289,43 @@ 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 && + ! 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." ); + } } else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */ { in_addr_t local=0, remote=0; + struct in6_addr remote_ipv6; const char *cn = NULL; if (!mi->context.options.duplicate_cn) cn = tls_common_name (mi->context.c2.tls_multi, true); - mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, cn); + CLEAR(remote_ipv6); + mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, &remote_ipv6, cn); if (mi->vaddr_handle >= 0) { const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap); const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap); + msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s", + print_in_addr_t( remote, 0, &gc ), + (mi->context.options.ifconfig_ipv6_pool_defined + ? print_in6_addr( remote_ipv6, 0, &gc ) + : "(Not enabled)") ); + /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */ mi->context.c2.push_ifconfig_local = remote; if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET)) @@ -1228,12 +1347,46 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi) else msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s", multi_instance_string (mi, false, &gc)); + + 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.c1.tuntap->local_ipv6; + mi->context.c2.push_ifconfig_ipv6_netbits = + mi->context.options.ifconfig_ipv6_pool_netbits; + mi->context.c2.push_ifconfig_ipv6_defined = true; + } } else { msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available"); } } + + /* IPv6 push_ifconfig is a bit problematic - since IPv6 shares the + * pool handling with IPv4, the combination "static IPv4, dynamic IPv6" + * will fail (because no pool will be allocated in this case). + * OTOH, this doesn't make too much sense in reality - and the other + * 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 ) + { + mi->context.c2.push_ifconfig_ipv6_local = + mi->context.options.push_ifconfig_ipv6_local; + mi->context.c2.push_ifconfig_ipv6_remote = + mi->context.options.push_ifconfig_ipv6_remote; + mi->context.c2.push_ifconfig_ipv6_netbits = + mi->context.options.push_ifconfig_ipv6_netbits; + mi->context.c2.push_ifconfig_ipv6_defined = true; + + msg( M_INFO, "MULTI_sva: push_ifconfig_ipv6 %s/%d", + print_in6_addr( mi->context.c2.push_ifconfig_ipv6_local, 0, &gc ), + mi->context.c2.push_ifconfig_ipv6_netbits ); + } + gc_free (&gc); } @@ -1272,6 +1425,11 @@ multi_set_virtual_addr_env (struct multi_context *m, struct multi_instance *mi) SA_SET_IF_NONZERO); } } + + /* TODO: I'm not exactly sure what these environment variables are + * used for, but if we have them for IPv4, we should also have + * them for IPv6, no? + */ } /* @@ -1294,7 +1452,7 @@ multi_client_connect_post (struct multi_context *m, option_types_found, mi->context.c2.es); - if (!delete_file (dc_file)) + if (!platform_unlink (dc_file)) msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s", dc_file); @@ -1661,6 +1819,15 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc)); } + if (mi->context.c2.push_ifconfig_ipv6_defined) + { + multi_learn_in6_addr (m, mi, mi->context.c2.push_ifconfig_ipv6_local, -1, true); + /* TODO: find out where addresses are "unlearned"!! */ + msg (D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s", + multi_instance_string (mi, false, &gc), + print_in6_addr (mi->context.c2.push_ifconfig_ipv6_local, 0, &gc)); + } + /* add routes locally, pointing to new client, if --iroute options have been specified */ multi_add_iroutes (m, mi); @@ -1695,6 +1862,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi /* increment number of current authenticated clients */ ++m->n_clients; + update_mstat_n_clients(m->n_clients); --mi->n_clients_delta; #ifdef MANAGEMENT_DEF_AUTH @@ -2356,6 +2524,14 @@ gremlin_flood_clients (struct multi_context *m) } #endif +bool +stale_route_check_trigger (struct multi_context *m) +{ + struct timeval null; + CLEAR (null); + return event_timeout_trigger (&m->stale_routes_check_et, &null, ETT_DEFAULT); +} + /* * Process timers in the top-level context */ @@ -2378,6 +2554,10 @@ multi_process_per_second_timers_dowork (struct multi_context *m) #ifdef ENABLE_DEBUG gremlin_flood_clients (m); #endif + + /* Should we check for stale routes? */ + if (m->top.options.stale_routes_check_interval && stale_route_check_trigger (m)) + check_stale_routes (m); } void @@ -2496,9 +2676,9 @@ management_callback_kill_by_addr (void *arg, const in_addr_t addr, const int por int count = 0; CLEAR (saddr); - saddr.sa.sin_family = AF_INET; - saddr.sa.sin_addr.s_addr = htonl (addr); - saddr.sa.sin_port = htons (port); + saddr.addr.in4.sin_family = AF_INET; + saddr.addr.in4.sin_addr.s_addr = htonl (addr); + saddr.addr.in4.sin_port = htons (port); if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true)) { hash_iterator_init (m->iter, &hi); @@ -2541,13 +2721,14 @@ lookup_by_cid (struct multi_context *m, const unsigned long cid) } static bool -management_kill_by_cid (void *arg, const unsigned long cid) +management_kill_by_cid (void *arg, const unsigned long cid, const char *kill_msg) { struct multi_context *m = (struct multi_context *) arg; struct multi_instance *mi = lookup_by_cid (m, cid); if (mi) { - send_restart (&mi->context); /* was: multi_signal_instance (m, mi, SIGTERM); */ + send_restart (&mi->context, kill_msg); /* was: multi_signal_instance (m, mi, SIGTERM); */ + multi_schedule_context_wakeup(m, mi); return true; } else @@ -2675,16 +2856,10 @@ tunnel_server (struct context *top) { ASSERT (top->options.mode == MODE_SERVER); - switch (top->options.ce.proto) { - case PROTO_UDPv4: - tunnel_server_udp (top); - break; - case PROTO_TCPv4_SERVER: - tunnel_server_tcp (top); - break; - default: - ASSERT (0); - } + if (proto_is_dgram(top->options.ce.proto)) + tunnel_server_udp(top); + else + tunnel_server_tcp(top); } #else diff --git a/multi.h b/src/openvpn/multi.h index 08964a2..2bc0c8a 100644 --- a/multi.h +++ b/src/openvpn/multi.h @@ -22,6 +22,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/** + * @file Header file for server-mode related structures and functions. + */ + #ifndef MULTI_H #define MULTI_H @@ -50,8 +54,16 @@ struct multi_reap time_t last_call; }; -/* - * One multi_instance object per client instance. + +/** + * Server-mode state structure for one single VPN tunnel. + * + * This structure is used by OpenVPN processes running in server-mode to + * store state information related to one single VPN tunnel. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes the role the structure plays when OpenVPN is running in + * server-mode. */ struct multi_instance { struct schedule_entry se; /* this must be the first element of the structure */ @@ -60,9 +72,13 @@ struct multi_instance { bool halt; int refcount; int route_count; /* number of routes (including cached routes) owned by this instance */ - time_t created; + time_t created; /**< Time at which a VPN tunnel instance + * was created. This parameter is set + * by the \c multi_create_instance() + * function. */ struct timeval wakeup; /* absolute time */ - struct mroute_addr real; + struct mroute_addr real; /**< External network address of the + * remote peer. */ ifconfig_pool_handle vaddr_handle; const char *msg_prefix; @@ -84,11 +100,20 @@ struct multi_instance { bool did_iroutes; int n_clients_delta; /* added to multi_context.n_clients when instance is closed */ - struct context context; + struct context context; /**< The context structure storing state + * for this VPN tunnel. */ }; -/* - * One multi_context object per server daemon thread. + +/** + * Main OpenVPN server state structure. + * + * This structure is used by OpenVPN processes running in server-mode to + * store all the VPN tunnel and process-wide state. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes the role the structure plays when OpenVPN is running in + * server-mode. */ struct multi_context { # define MC_UNDEF 0 @@ -99,12 +124,19 @@ struct multi_context { # define MC_WORK_THREAD (MC_MULTI_THREADED_WORKER|MC_MULTI_THREADED_SCHEDULER) int thread_mode; - struct hash *hash; /* client instances indexed by real address */ - struct hash *vhash; /* client instances indexed by virtual address */ - struct hash *iter; /* like real address hash but optimized for iteration */ + struct hash *hash; /**< VPN tunnel instances indexed by real + * address of the remote peer. */ + struct hash *vhash; /**< VPN tunnel instances indexed by + * virtual address of remote hosts. */ + struct hash *iter; /**< VPN tunnel instances indexed by real + * address of the remote peer, optimized + * for iteration. */ struct schedule *schedule; - struct mbuf_set *mbuf; - struct multi_tcp *mtcp; + struct mbuf_set *mbuf; /**< Set of buffers for passing data + * channel packets between VPN tunnel + * instances. */ + struct multi_tcp *mtcp; /**< State specific to OpenVPN using TCP + * as external transport. */ struct ifconfig_pool *ifconfig_pool; struct frequency_limit *new_connection_limiter; struct mroute_helper *route_helper; @@ -127,7 +159,13 @@ struct multi_context { struct context_buffers *context_buffers; time_t per_second_trigger; - struct context top; + struct context top; /**< Storage structure for process-wide + * configuration. */ + + /* + * Timer object for stale route check + */ + struct event_timeout stale_routes_check_et; }; /* @@ -146,11 +184,22 @@ struct multi_route time_t last_reference; }; -/* - * top level function, called by openvpn.c + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in server mode. + * @ingroup eventloop + * + * This function calls the appropriate main event loop function depending + * on the transport protocol used: + * - \c tunnel_server_udp() + * - \c tunnel_server_tcp() + * + * @param top - Top-level context structure. */ void tunnel_server (struct context *top); + const char *multi_instance_string (const struct multi_instance *mi, bool null, struct gc_arena *gc); /* @@ -172,11 +221,77 @@ bool multi_process_timeout (struct multi_context *m, const unsigned int mpp_flag #define MPP_CONDITIONAL_PRE_SELECT (1<<1) #define MPP_CLOSE_ON_SIGNAL (1<<2) #define MPP_RECORD_TOUCH (1<<3) + + +/**************************************************************************/ +/** + * Perform postprocessing of a VPN tunnel instance. + * + * After some VPN tunnel activity has taken place, the VPN tunnel's state + * may need updating and some follow-up action may be required. This + * function controls the necessary postprocessing. It is called by many + * other functions that handle VPN tunnel related activity, such as \c + * multi_process_incoming_link(), \c multi_process_outgoing_link(), \c + * multi_process_incoming_tun(), \c multi_process_outgoing_tun(), and \c + * multi_process_timeout(), among others. + * + * @param m - The single \c multi_context structure. + * @param mi - The \c multi_instance of the VPN tunnel to be + * postprocessed. + * @param flags - Fast I/O optimization flags. + * + * @return + * - True, if the VPN tunnel instance \a mi was not closed due to a + * signal during processing. + * - False, if the VPN tunnel instance \a mi was closed. + */ bool multi_process_post (struct multi_context *m, struct multi_instance *mi, const unsigned int flags); + +/**************************************************************************/ +/** + * Demultiplex and process a packet received over the external network + * interface. + * @ingroup external_multiplexer + * + * This function determines which VPN tunnel instance the incoming packet + * is associated with, and then calls \c process_incoming_link() to handle + * it. Afterwards, if the packet is destined for a broadcast/multicast + * address or a remote host reachable through a different VPN tunnel, this + * function takes care of sending it they are. + * + * @note This function is only used by OpenVPN processes which are running + * in server mode, and can therefore sustain multiple active VPN + * tunnels. + * + * @param m - The single \c multi_context structure. + * @param instance - The VPN tunnel state structure associated with + * the incoming packet, if known, as is the case + * when using TCP transport. Otherwise NULL, as is + * the case when using UDP transport. + * @param mpp_flags - Fast I/O optimization flags. + */ bool multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags); + + +/** + * Determine the destination VPN tunnel of a packet received over the + * virtual tun/tap network interface and then process it accordingly. + * @ingroup internal_multiplexer + * + * This function determines which VPN tunnel instance the packet is + * destined for, and then calls \c process_outgoing_tun() to handle it. + * + * @note This function is only used by OpenVPN processes which are running + * in server mode, and can therefore sustain multiple active VPN + * tunnels. + * + * @param m - The single \c multi_context structure. + * @param mpp_flags - Fast I/O optimization flags. + */ bool multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flags); + void multi_process_drop_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags); void multi_print_status (struct multi_context *m, struct status_output *so, const int version); @@ -397,8 +512,23 @@ multi_get_timeout (struct multi_context *m, struct timeval *dest) } } -/* - * Send a packet to TUN/TAP interface. + +/** + * Send a packet over the virtual tun/tap network interface to its locally + * reachable destination. + * @ingroup internal_multiplexer + * + * This function calls \c process_outgoing_tun() to perform the actual + * sending of the packet. Afterwards, it calls \c multi_process_post() to + * perform server-mode postprocessing. + * + * @param m - The single \c multi_context structure. + * @param mpp_flags - Fast I/O optimization flags. + * + * @return + * - True, if the \c multi_instance associated with the packet sent was + * not closed due to a signal during processing. + * - Falls, if the \c multi_instance was closed. */ static inline bool multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags) @@ -419,6 +549,8 @@ multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flag return ret; } + + static inline bool multi_process_outgoing_link_dowork (struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags) { diff --git a/ntlm.c b/src/openvpn/ntlm.c index 0453358..3390bdd 100644 --- a/ntlm.c +++ b/src/openvpn/ntlm.c @@ -21,6 +21,12 @@ * 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 NTLM @@ -63,34 +69,31 @@ create_des_keys(const unsigned char *hash, unsigned char *key) key[5] = ((hash[4]&31)<<3)|(hash[5]>>5); key[6] = ((hash[5]&63)<<2)|(hash[6]>>6); key[7] = ((hash[6]&127)<<1); - des_set_odd_parity((des_cblock *)key); + key_des_fixup(key, 8, 1); } static void gen_md4_hash (const char* data, int data_len, char *result) { /* result is 16 byte md4 hash */ + const md_kt_t *md4_kt = md_kt_get("MD4"); + char md[MD4_DIGEST_LENGTH]; - MD4_CTX c; - char md[16]; - - MD4_Init (&c); - MD4_Update (&c, data, data_len); - MD4_Final ((unsigned char *)md, &c); - - memcpy (result, md, 16); + md_full(md4_kt, data, data_len, md); + memcpy (result, md, MD4_DIGEST_LENGTH); } static void gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result) { - unsigned int len; - - HMAC_CTX c; - HMAC_Init (&c, key, key_len, EVP_md5()); - HMAC_Update (&c, (const unsigned char *)data, data_len); - HMAC_Final (&c, (unsigned char *)result, &len); - HMAC_CTX_cleanup(&c); + const md_kt_t *md5_kt = md_kt_get("MD5"); + hmac_ctx_t hmac_ctx; + CLEAR(hmac_ctx); + + hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt); + hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len); + hmac_ctx_final(&hmac_ctx, (unsigned char *)result); + hmac_ctx_cleanup(&hmac_ctx); } static void @@ -193,16 +196,14 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar char buf2[128]; /* decoded reply from proxy */ unsigned char phase3[464]; - char md4_hash[21]; + char md4_hash[MD4_DIGEST_LENGTH+5]; char challenge[8], ntlm_response[24]; int i, ret_val; - des_cblock key1, key2, key3; - des_key_schedule sched1, sched2, sched3; char ntlmv2_response[144]; char userdomain_u[256]; /* for uppercase unicode username and domain */ char userdomain[128]; /* the same as previous but ascii */ - char ntlmv2_hash[16]; + char ntlmv2_hash[MD5_DIGEST_LENGTH]; char ntlmv2_hmacmd5[16]; char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */ int ntlmv2_blob_size=0; @@ -240,9 +241,9 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar gen_md4_hash (pwbuf, unicodize (pwbuf, p->up.password) - 2, md4_hash); /* pad to 21 bytes */ - memset (md4_hash + 16, 0, 5); + memset(md4_hash + MD4_DIGEST_LENGTH, 0, 5); - ret_val = base64_decode( phase_2, (void *)buf2); + ret_val = openvpn_base64_decode( phase_2, (void *)buf2, -1); if (ret_val < 0) return NULL; @@ -265,7 +266,7 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar else msg (M_INFO, "Warning: Username or domain too long"); unicodize (userdomain_u, userdomain); - gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 16, ntlmv2_hash); + gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, MD5_DIGEST_LENGTH, ntlmv2_hash); /* NTLMv2 Blob */ memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */ @@ -297,27 +298,25 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar memcpy(&ntlmv2_response[8], challenge, 8); /* hmac-md5 */ - gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, 16, ntlmv2_hmacmd5); + gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, MD5_DIGEST_LENGTH, ntlmv2_hmacmd5); /* Add hmac-md5 result to the blob */ - memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */ + memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */ } else { /* Generate NTLM response */ + unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH], key3[DES_KEY_LENGTH]; create_des_keys ((unsigned char *)md4_hash, key1); - des_set_key_unchecked ((des_cblock *)key1, sched1); - des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)ntlm_response, sched1, DES_ENCRYPT); + cipher_des_encrypt_ecb (key1, challenge, ntlm_response); - create_des_keys ((unsigned char *)&(md4_hash[7]), key2); - des_set_key_unchecked ((des_cblock *)key2, sched2); - des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[8]), sched2, DES_ENCRYPT); + create_des_keys ((unsigned char *)&(md4_hash[DES_KEY_LENGTH-1]), key2); + cipher_des_encrypt_ecb (key2, challenge, &ntlm_response[DES_KEY_LENGTH]); - create_des_keys ((unsigned char *)&(md4_hash[14]), key3); - des_set_key_unchecked ((des_cblock *)key3, sched3); - des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[16]), sched3, DES_ENCRYPT); + create_des_keys ((unsigned char *)&(md4_hash[2*(DES_KEY_LENGTH-1)]), key3); + cipher_des_encrypt_ecb (key3, challenge, &ntlm_response[DES_KEY_LENGTH*2]); } - - + + memset (phase3, 0, sizeof (phase3)); /* clear reply */ strcpy ((char *)phase3, "NTLMSSP\0"); /* signature */ diff --git a/ntlm.h b/src/openvpn/ntlm.h index 77903b0..77903b0 100644 --- a/ntlm.h +++ b/src/openvpn/ntlm.h diff --git a/occ-inline.h b/src/openvpn/occ-inline.h index 516eb4d..516eb4d 100644 --- a/occ-inline.h +++ b/src/openvpn/occ-inline.h diff --git a/occ.c b/src/openvpn/occ.c index b84b18d..ff48706 100644 --- a/occ.c +++ b/src/openvpn/occ.c @@ -22,6 +22,12 @@ * 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_OCC @@ -368,8 +374,8 @@ process_received_occ_msg (struct context *c) c->c2.max_recv_size_remote, c->c2.max_send_size_remote, c->c2.max_recv_size_local); - if (!c->options.fragment - && c->options.ce.proto == PROTO_UDPv4 + if (!c->options.ce.fragment + && (proto_is_dgram(c->options.ce.proto)) && 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)) diff --git a/occ.h b/src/openvpn/occ.h index 5d88cc9..5d88cc9 100644 --- a/occ.h +++ b/src/openvpn/occ.h diff --git a/openvpn.c b/src/openvpn/openvpn.c index 99b343b..104c9e9 100644 --- a/openvpn.c +++ b/src/openvpn/openvpn.c @@ -22,6 +22,12 @@ * 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" #include "init.h" @@ -42,6 +48,16 @@ process_signal_p2p (struct context *c) return process_signal (c); } + + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in client mode, where only one VPN tunnel + * is active. + * @ingroup eventloop + * + * @param c - The context structure of the single active VPN tunnel. + */ static void tunnel_point_to_point (struct context *c) { @@ -90,8 +106,30 @@ tunnel_point_to_point (struct context *c) #undef PROCESS_SIGNAL_P2P + +/**************************************************************************/ +/** + * OpenVPN's main init-run-cleanup loop. + * @ingroup eventloop + * + * This function contains the two outer OpenVPN loops. Its structure is + * as follows: + * - Once-per-process initialization. + * - Outer loop, run at startup and then once per \c SIGHUP: + * - Level 1 initialization + * - Inner loop, run at startup and then once per \c SIGUSR1: + * - Call event loop function depending on client or server mode: + * - \c tunnel_point_to_point() + * - \c tunnel_server() + * - Level 1 cleanup + * - Once-per-process cleanup. + * + * @param argc - Commandline argument count. + * @param argv - Commandline argument values. + */ +static int -main (int argc, char *argv[]) +openvpn_main (int argc, char *argv[]) { struct context c; @@ -100,6 +138,10 @@ main (int argc, char *argv[]) return 1; #endif +#ifdef WIN32 + SetConsoleOutputCP (CP_UTF8); +#endif + CLEAR (c); /* signify first time for components which can @@ -129,9 +171,9 @@ main (int argc, char *argv[]) gc_init (&c.gc); /* initialize environmental variable store */ - c.es = env_set_create (NULL); + c.es = env_set_create (&c.gc); #ifdef WIN32 - env_set_add_win32 (c.es); + set_win_sys_path_via_env (c.es); #endif #ifdef ENABLE_MANAGEMENT @@ -248,3 +290,37 @@ main (int argc, char *argv[]) openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ return 0; /* NOTREACHED */ } + +#ifdef WIN32 +int +wmain (int argc, wchar_t *wargv[]) { + char **argv; + int ret; + int i; + + if ((argv = calloc(argc+1, sizeof(char*))) == NULL) + return 1; + + for (i = 0; i < argc; i++) + { + int n = WideCharToMultiByte (CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc (n); + WideCharToMultiByte (CP_UTF8, 0, wargv[i], -1, argv[i], n, NULL, NULL); + } + + ret = openvpn_main(argc, argv); + + for (i=0; i < argc; i++ ) + { + free (argv[i]); + } + free(argv); + + return ret; +} +#else +int +main (int argc, char *argv[]) { + return openvpn_main(argc, argv); +} +#endif diff --git a/openvpn.h b/src/openvpn/openvpn.h index 641bf93..7abfb08 100644 --- a/openvpn.h +++ b/src/openvpn/openvpn.h @@ -55,24 +55,24 @@ struct key_schedule { -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* which cipher, HMAC digest, and key sizes are we using? */ struct key_type key_type; /* pre-shared static key, read from a file */ struct key_ctx_bi static_key; -#ifdef USE_SSL +#ifdef ENABLE_SSL /* our global SSL context */ - SSL_CTX *ssl_ctx; + struct tls_root_ctx ssl_ctx; /* optional authentication HMAC key for TLS control channel */ struct key_ctx_bi tls_auth_key; -#endif /* USE_SSL */ -#else /* USE_CRYPTO */ +#endif /* ENABLE_SSL */ +#else /* ENABLE_CRYPTO */ int dummy; -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ }; /* @@ -99,13 +99,13 @@ struct context_buffers struct buffer aux_buf; /* workspace buffers used by crypto routines */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO struct buffer encrypt_buf; struct buffer decrypt_buf; #endif /* workspace buffers for LZO compression */ -#ifdef USE_LZO +#ifdef ENABLE_LZO struct buffer lzo_compress_buf; struct buffer lzo_decompress_buf; #endif @@ -126,10 +126,14 @@ struct context_persist int restart_sleep_seconds; }; -/* - * level 0 context contains data related to - * once-per OpenVPN instantiation events - * such as daemonization. + +/**************************************************************************/ +/** + * Level 0 %context containing information related to the OpenVPN process. + * + * Level 0 state is initialized once at program startup, and then remains + * throughout the lifetime of the OpenVPN process. This structure + * contains information related to the process's PID, user, and group. */ struct context_0 { @@ -139,18 +143,25 @@ struct context_0 /* workspace for --user/--group */ bool uid_gid_specified; bool uid_gid_set; - struct user_state user_state; - struct group_state group_state; + struct platform_state_user platform_state_user; + struct platform_state_group platform_state_group; }; -/* - * Contains the persist-across-restart OpenVPN tunnel instance state. - * Reset only for SIGHUP restarts. + +/** + * Level 1 %context containing state that persists across \c SIGUSR1 + * restarts. + * + * Level 1 state is reset on \c SIGHUP restarts. This structure is + * initialized for every iteration of the \c main() function's outer \c + * SIGHUP loop, but persists over iteration of that function's inner \c + * SIGUSR1 loop. */ struct context_1 { - /* local and remote addresses */ struct link_socket_addr link_socket_addr; + /**< Local and remote addresses on the + * external network. */ /* tunnel session keys */ struct key_schedule ks; @@ -158,12 +169,17 @@ struct context_1 /* persist crypto sequence number to/from file */ struct packet_id_persist pid_persist; - /* TUN/TAP interface */ - struct tuntap *tuntap; - bool tuntap_owned; + struct tuntap *tuntap; /**< Tun/tap virtual network interface. */ + bool tuntap_owned; /**< Whether the tun/tap interface should + * be cleaned up when this %context is + * cleaned up. */ - /* list of --route directives */ struct route_list *route_list; + /**< List of routing information. See the + * \c --route command line option. */ + + /* list of --route-ipv6 directives */ + struct route_ipv6_list *route_ipv6_list; /* --status file */ struct status_output *status_output; @@ -191,20 +207,30 @@ struct context_1 /* if client mode, hash of option strings we pulled from server */ struct md5_digest pulled_options_digest_save; + /**< Hash of option strings received from the + * remote OpenVPN server. Only used in + * client-mode. */ - /* save user/pass for authentication */ struct user_pass *auth_user_pass; + /**< Username and password for + * authentication. */ #endif }; -/* - * Contains the OpenVPN tunnel instance state, wiped across - * SIGUSR1 and SIGHUP restarts. +/** + * Level 2 %context containing state that is reset on both \c SIGHUP and + * \c SIGUSR1 restarts. + * + * This structure is initialized at the top of the \c + * tunnel_point_to_point(), \c tunnel_server_udp_single_threaded(), and \c + * tunnel_server_tcp() functions. In other words, it is reset for every + * iteration of the \c main() function's inner \c SIGUSR1 loop. */ struct context_2 { - /* garbage collection arena for context_2 scope */ - struct gc_arena gc; + struct gc_arena gc; /**< Garbage collection arena for + * allocations done in the level 2 scope + * of this context_2 structure. */ /* our global wait events */ struct event_set *event_set; @@ -243,7 +269,7 @@ struct context_2 struct frame frame_fragment_omit; #endif -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER /* * Traffic shaper object. */ @@ -305,19 +331,26 @@ struct context_2 int occ_mtu_load_n_tries; #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* * TLS-mode crypto objects. */ -#ifdef USE_SSL +#ifdef ENABLE_SSL - /* master OpenVPN SSL/TLS object */ - struct tls_multi *tls_multi; + struct tls_multi *tls_multi; /**< TLS state structure for this VPN + * tunnel. */ - /* check --tls-auth signature without needing - a full-size tls_multi object */ struct tls_auth_standalone *tls_auth_standalone; + /**< TLS state structure required for the + * initial authentication of a client's + * connection attempt. This structure + * is used by the \c + * tls_pre_decrypt_lite() function when + * it performs the HMAC firewall check + * on the first connection packet + * received from a new client. See the + * \c --tls-auth commandline option. */ /* used to optimize calls to tls_multi_process */ struct interval tmp_int; @@ -325,24 +358,25 @@ struct context_2 /* throw this signal on TLS errors */ int tls_exit_signal; -#endif /* USE_SSL */ +#endif /* ENABLE_SSL */ - /* passed to encrypt or decrypt, contains all - crypto-related command line options related - to data channel encryption/decryption */ 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 /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ - /* - * LZO compression library workspace. - */ -#ifdef USE_LZO +#ifdef ENABLE_LZO struct lzo_compress_workspace lzo_compwork; + /**< Compression workspace used by the + * \link compression Data Channel + * Compression module\endlink. */ #endif /* @@ -414,8 +448,17 @@ struct context_2 /* --ifconfig endpoints to be pushed to client */ bool push_reply_deferred; 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; + int push_ifconfig_ipv6_netbits; + struct in6_addr push_ifconfig_ipv6_remote; /* client authentication state, CAS_SUCCEEDED must be 0 */ # define CAS_SUCCEEDED 0 @@ -427,6 +470,7 @@ struct context_2 #endif struct event_timeout push_request_interval; + int n_sent_push_requests; bool did_pre_pull_restore; /* hash of pulled options, so we can compare when options change */ @@ -449,16 +493,25 @@ struct context_2 #endif }; -/* + +/** * Contains all state information for one tunnel. + * + * This structure represents one VPN tunnel. It is used to store state + * information related to a VPN tunnel, but also includes process-wide + * data, such as configuration options. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes how this structure is used in client-mode and + * server-mode. */ struct context { - /* command line or config file options */ - struct options options; + struct options options; /**< Options loaded from command line or + * configuration file. */ - /* true on initial VPN iteration */ - bool first_time; + bool first_time; /**< True on the first iteration of + * OpenVPN's main loop. */ /* context modes */ # define CM_P2P 0 /* standalone point-to-point session or client */ @@ -466,41 +519,32 @@ struct context # define CM_TOP_CLONE 2 /* clone of a CM_TOP context for one thread */ # define CM_CHILD_UDP 3 /* child context of a CM_TOP or CM_THREAD */ # define CM_CHILD_TCP 4 /* child context of a CM_TOP or CM_THREAD */ - int mode; + int mode; /**< Role of this context within the + * OpenVPN process. Valid values are \c + * CM_P2P, \c CM_TOP, \c CM_TOP_CLONE, + * \c CM_CHILD_UDP, and \c CM_CHILD_TCP. */ - /* garbage collection for context scope - allocations */ - struct gc_arena gc; + struct gc_arena gc; /**< Garbage collection arena for + * allocations done in the scope of this + * context structure. */ - /* environmental variable settings */ - struct env_set *es; + struct env_set *es; /**< Set of environment variables. */ - /* signal info */ - struct signal_info *sig; + struct signal_info *sig; /**< Internal error signaling object. */ - /* shared object plugins */ - struct plugin_list *plugins; - bool plugins_owned; + struct plugin_list *plugins; /**< List of plug-ins. */ + bool plugins_owned; /**< Whether the plug-ins should be + * cleaned up when this %context is + * cleaned up. */ - /* set to true after we daemonize */ - bool did_we_daemonize; + bool did_we_daemonize; /**< Whether demonization has already + * taken place. */ - /* persistent across SIGHUP */ struct context_persist persist; - - /* level 0 context contains data related to - once-per OpenVPN instantiation events - such as daemonization */ - struct context_0 *c0; - - /* level 1 context is preserved for - SIGUSR1 restarts, but initialized - for SIGHUP restarts */ - struct context_1 c1; - - /* level 2 context is initialized for all - restarts (SIGUSR1 and SIGHUP) */ - struct context_2 c2; + /**< Persistent %context. */ + struct context_0 *c0; /**< Level 0 %context. */ + struct context_1 c1; /**< Level 1 %context. */ + struct context_2 c2; /**< Level 2 %context. */ }; /* @@ -522,7 +566,7 @@ struct context * have been compiled in. */ -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) #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), \ @@ -535,13 +579,13 @@ struct context #define PROTO_DUMP(buf, gc) format_hex (BPTR (buf), BLEN (buf), 80, gc) #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO #define MD5SUM(buf, len, gc) md5sum((buf), (len), 0, (gc)) #else #define MD5SUM(buf, len, gc) "[unavailable]" #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO #define CIPHER_ENABLED(c) (c->c1.ks.key_type.cipher != NULL) #else #define CIPHER_ENABLED(c) (false) diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj new file mode 100755 index 0000000..3b2340e --- /dev/null +++ b/src/openvpn/openvpn.vcxproj @@ -0,0 +1,263 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{29DF226E-4D4E-440F-ADAF-5829CFD4CA94}</ProjectGuid> + <RootNamespace>openvpn</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(SOURCEBASE);$(SOURCEBASE)/src/compat;$(SOURCEBASE)/include;$(TAP_WINDOWS_HOME)/include;$(OPENSSL_HOME)/include;$(LZO_HOME)/include;$(PKCS11H_HOME)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <UndefinePreprocessorDefinitions>UNICODE</UndefinePreprocessorDefinitions> + </ClCompile> + <ResourceCompile> + <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;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>$(SOURCEBASE);$(SOURCEBASE)/src/compat;$(SOURCEBASE)/include;$(TAP_WINDOWS_HOME)/include;$(OPENSSL_HOME)/include;$(LZO_HOME)/include;$(PKCS11H_HOME)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <UndefinePreprocessorDefinitions>UNICODE</UndefinePreprocessorDefinitions> + </ClCompile> + <ResourceCompile> + <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;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="base64.c" /> + <ClCompile Include="buffer.c" /> + <ClCompile Include="clinat.c" /> + <ClCompile Include="console.c" /> + <ClCompile Include="crypto.c" /> + <ClCompile Include="crypto_openssl.c" /> + <ClCompile Include="cryptoapi.c" /> + <ClCompile Include="dhcp.c" /> + <ClCompile Include="error.c" /> + <ClCompile Include="event.c" /> + <ClCompile Include="fdmisc.c" /> + <ClCompile Include="forward.c" /> + <ClCompile Include="fragment.c" /> + <ClCompile Include="gremlin.c" /> + <ClCompile Include="helper.c" /> + <ClCompile Include="httpdigest.c" /> + <ClCompile Include="init.c" /> + <ClCompile Include="interval.c" /> + <ClCompile Include="list.c" /> + <ClCompile Include="lladdr.c" /> + <ClCompile Include="lzo.c" /> + <ClCompile Include="manage.c" /> + <ClCompile Include="mbuf.c" /> + <ClCompile Include="misc.c" /> + <ClCompile Include="mroute.c" /> + <ClCompile Include="mss.c" /> + <ClCompile Include="mstats.c" /> + <ClCompile Include="mtcp.c" /> + <ClCompile Include="mtu.c" /> + <ClCompile Include="mudp.c" /> + <ClCompile Include="multi.c" /> + <ClCompile Include="ntlm.c" /> + <ClCompile Include="occ.c" /> + <ClCompile Include="openvpn.c" /> + <ClCompile Include="options.c" /> + <ClCompile Include="otime.c" /> + <ClCompile Include="packet_id.c" /> + <ClCompile Include="perf.c" /> + <ClCompile Include="pf.c" /> + <ClCompile Include="ping.c" /> + <ClCompile Include="pkcs11.c" /> + <ClCompile Include="pkcs11_openssl.c" /> + <ClCompile Include="platform.c" /> + <ClCompile Include="plugin.c" /> + <ClCompile Include="pool.c" /> + <ClCompile Include="proto.c" /> + <ClCompile Include="proxy.c" /> + <ClCompile Include="ps.c" /> + <ClCompile Include="push.c" /> + <ClCompile Include="reliable.c" /> + <ClCompile Include="route.c" /> + <ClCompile Include="schedule.c" /> + <ClCompile Include="session_id.c" /> + <ClCompile Include="shaper.c" /> + <ClCompile Include="sig.c" /> + <ClCompile Include="socket.c" /> + <ClCompile Include="socks.c" /> + <ClCompile Include="ssl.c" /> + <ClCompile Include="ssl_openssl.c" /> + <ClCompile Include="ssl_verify.c" /> + <ClCompile Include="ssl_verify_openssl.c" /> + <ClCompile Include="status.c" /> + <ClCompile Include="tun.c" /> + <ClCompile Include="win32.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="base64.h" /> + <ClInclude Include="basic.h" /> + <ClInclude Include="buffer.h" /> + <ClInclude Include="circ_list.h" /> + <ClInclude Include="clinat.h" /> + <ClInclude Include="common.h" /> + <ClInclude Include="console.h" /> + <ClInclude Include="crypto.h" /> + <ClInclude Include="crypto_backend.h" /> + <ClInclude Include="crypto_openssl.h" /> + <ClInclude Include="cryptoapi.h" /> + <ClInclude Include="dhcp.h" /> + <ClInclude Include="errlevel.h" /> + <ClInclude Include="error.h" /> + <ClInclude Include="event.h" /> + <ClInclude Include="fdmisc.h" /> + <ClInclude Include="forward-inline.h" /> + <ClInclude Include="forward.h" /> + <ClInclude Include="fragment.h" /> + <ClInclude Include="gremlin.h" /> + <ClInclude Include="helper.h" /> + <ClInclude Include="httpdigest.h" /> + <ClInclude Include="init.h" /> + <ClInclude Include="integer.h" /> + <ClInclude Include="interval.h" /> + <ClInclude Include="list.h" /> + <ClInclude Include="lladdr.h" /> + <ClInclude Include="lzo.h" /> + <ClInclude Include="manage.h" /> + <ClInclude Include="mbuf.h" /> + <ClInclude Include="memdbg.h" /> + <ClInclude Include="misc.h" /> + <ClInclude Include="mroute.h" /> + <ClInclude Include="mss.h" /> + <ClInclude Include="mstats.h" /> + <ClInclude Include="mtcp.h" /> + <ClInclude Include="mtu.h" /> + <ClInclude Include="mudp.h" /> + <ClInclude Include="multi.h" /> + <ClInclude Include="ntlm.h" /> + <ClInclude Include="occ-inline.h" /> + <ClInclude Include="occ.h" /> + <ClInclude Include="openvpn.h" /> + <ClInclude Include="options.h" /> + <ClInclude Include="otime.h" /> + <ClInclude Include="packet_id.h" /> + <ClInclude Include="perf.h" /> + <ClInclude Include="pf-inline.h" /> + <ClInclude Include="pf.h" /> + <ClInclude Include="ping-inline.h" /> + <ClInclude Include="ping.h" /> + <ClInclude Include="pkcs11.h" /> + <ClInclude Include="pkcs11_backend.h" /> + <ClInclude Include="platform.h" /> + <ClInclude Include="plugin.h" /> + <ClInclude Include="pool.h" /> + <ClInclude Include="proto.h" /> + <ClInclude Include="proxy.h" /> + <ClInclude Include="ps.h" /> + <ClInclude Include="push.h" /> + <ClInclude Include="pushlist.h" /> + <ClInclude Include="reliable.h" /> + <ClInclude Include="route.h" /> + <ClInclude Include="schedule.h" /> + <ClInclude Include="session_id.h" /> + <ClInclude Include="shaper.h" /> + <ClInclude Include="sig.h" /> + <ClInclude Include="socket.h" /> + <ClInclude Include="socks.h" /> + <ClInclude Include="ssl.h" /> + <ClInclude Include="ssl_backend.h" /> + <ClInclude Include="ssl_common.h" /> + <ClInclude Include="ssl_openssl.h" /> + <ClInclude Include="ssl_verify.h" /> + <ClInclude Include="ssl_verify_backend.h" /> + <ClInclude Include="ssl_verify_openssl.h" /> + <ClInclude Include="status.h" /> + <ClInclude Include="syshead.h" /> + <ClInclude Include="tun.h" /> + <ClInclude Include="win32.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="openvpn_win32_resources.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\build\msvc\msvc-generate\msvc-generate.vcxproj"> + <Project>{8598c2c8-34c4-47a1-99b0-7c295a890615}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\compat\compat.vcxproj"> + <Project>{4b2e2719-e661-45d7-9203-f6f456b22f19}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/openvpn/openvpn.vcxproj.filters b/src/openvpn/openvpn.vcxproj.filters new file mode 100644 index 0000000..40336ba --- /dev/null +++ b/src/openvpn/openvpn.vcxproj.filters @@ -0,0 +1,458 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="base64.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="buffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="clinat.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="console.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="crypto.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="crypto_openssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="cryptoapi.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dhcp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="error.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="event.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="fdmisc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="forward.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="fragment.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="gremlin.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="helper.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="httpdigest.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="init.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="interval.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="list.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="lladdr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="lzo.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="manage.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mbuf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="misc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mroute.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mss.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mstats.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mtcp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mtu.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="mudp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="multi.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ntlm.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="occ.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="openvpn.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="options.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="otime.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="packet_id.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="perf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ping.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pkcs11.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pkcs11_openssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="platform.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pool.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="proto.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="proxy.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ps.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="push.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="reliable.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="route.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="schedule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="session_id.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="shaper.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sig.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="socket.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="socks.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl_openssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl_verify.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl_verify_openssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="status.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="tun.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="win32.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="base64.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="basic.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="buffer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="circ_list.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="clinat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="console.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto_backend.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto_openssl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="cryptoapi.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dhcp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="errlevel.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="error.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="event.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="fdmisc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="forward-inline.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="forward.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="fragment.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="gremlin.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="helper.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="httpdigest.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="init.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="integer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="interval.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="list.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="lladdr.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="lzo.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="manage.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mbuf.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="memdbg.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="misc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mroute.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mss.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mstats.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mtcp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mtu.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="mudp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="multi.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ntlm.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="occ-inline.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="occ.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="openvpn.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="options.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="otime.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="packet_id.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="perf.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pf-inline.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pf.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ping-inline.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ping.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pkcs11.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pkcs11_backend.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="platform.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="plugin.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pool.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="proto.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="proxy.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ps.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="push.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pushlist.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="reliable.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="route.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="schedule.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="session_id.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="shaper.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sig.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="socket.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="socks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_backend.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_openssl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_verify.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_verify_backend.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl_verify_openssl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="status.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="syshead.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="tun.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="win32.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="openvpn_win32_resources.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/openvpn/openvpn_win32_resources.rc b/src/openvpn/openvpn_win32_resources.rc new file mode 100644 index 0000000..d092e21 --- /dev/null +++ b/src/openvpn/openvpn_win32_resources.rc @@ -0,0 +1,43 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#else +#include <config-msvc-version.h> +#endif +#include <winresrc.h> + +#pragma code_page(65001) /* UTF8 */ + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENVPN_VERSION_RESOURCE + PRODUCTVERSION OPENVPN_VERSION_RESOURCE + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The OpenVPN Project" + VALUE "FileDescription", "OpenVPN Daemon" + VALUE "FileVersion", PACKAGE_VERSION ".0" + VALUE "InternalName", "OpenVPN" + VALUE "LegalCopyright", "Copyright © The OpenVPN Project" + VALUE "OriginalFilename", "openvpn.exe" + VALUE "ProductName", "OpenVPN" + VALUE "ProductVersion", PACKAGE_VERSION ".0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/options.c b/src/openvpn/options.c index 7a5e35d..9baa4ff 100644 --- a/options.c +++ b/src/openvpn/options.c @@ -30,6 +30,15 @@ * (Christof Meerwald, http://cmeerw.org) */ +#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" #include "buffer.h" @@ -49,7 +58,6 @@ #include "helper.h" #include "manage.h" #include "forward.h" -#include "configure.h" #include <ctype.h> #include "memdbg.h" @@ -57,16 +65,32 @@ const char title_string[] = PACKAGE_STRING " " TARGET_ALIAS -#ifdef USE_CRYPTO -#ifdef USE_SSL +#ifdef ENABLE_CRYPTO +#ifdef ENABLE_SSL +#if defined(ENABLE_CRYPTO_POLARSSL) + " [SSL (PolarSSL)]" +#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 /* ENABLE_CRYPTO */ +#ifdef ENABLE_LZO +#ifdef ENABLE_LZO_STUB + " [LZO (STUB)]" +#else + " [LZO]" #endif #endif -#ifdef USE_LZO - " [LZO" LZO_VERSION_NUM "]" -#endif #if EPOLL " [EPOLL]" #endif @@ -79,6 +103,10 @@ const char title_string[] = #ifdef ENABLE_EUREPHIA " [eurephia]" #endif +#if ENABLE_IP_PKTINFO + " [MH]" +#endif + " [IPv6]" " built on " __DATE__ ; @@ -101,14 +129,11 @@ static const char usage_message[] = "--proto p : Use protocol p for communicating with peer.\n" " p = udp (default), tcp-server, or tcp-client\n" "--proto-force p : only consider protocol p in list of connection profiles.\n" + " 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-max n : Maximum connection attempt retries, default infinite.\n" -#ifdef GENERAL_PROXY_SUPPORT - "--auto-proxy : Try to sense proxy settings (or lack thereof) automatically.\n" - "--show-proxy-settings : Show sensed proxy settings.\n" -#endif #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" @@ -139,7 +164,7 @@ static const char usage_message[] = " Set n=\"infinite\" to retry indefinitely.\n" "--float : Allow remote to change its IP address/port, such as through\n" " DHCP (this is the default if --remote is not used).\n" - "--ipchange cmd : Execute shell command cmd on remote ip address initial\n" + "--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" @@ -163,7 +188,7 @@ static const char usage_message[] = "--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 CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE "--iproute cmd : Use this command instead of default " IPROUTE_PATH ".\n" #endif "--ifconfig l rn : TUN: configure device to use IP address l as a local\n" @@ -172,6 +197,8 @@ static const char usage_message[] = " addresses outside of the subnets used by either peer.\n" " TAP: configure device to use IP address l as a local\n" " endpoint and rn as a subnet mask.\n" + "--ifconfig-ipv6 l r : configure device to use IPv6 address l as local\n" + " endpoint (as a /64) and r as remote endpoint\n" "--ifconfig-noexec : Don't actually execute ifconfig/netsh command, instead\n" " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" @@ -182,6 +209,10 @@ static const char usage_message[] = " netmask default: 255.255.255.255\n" " gateway default: taken from --route-gateway or --ifconfig\n" " Specify default by leaving blank or setting to \"nil\".\n" + "--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" "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n" @@ -190,11 +221,12 @@ static const char usage_message[] = " adding routes (may be 0). If not specified, routes will\n" " be added immediately after tun/tap open. On Windows, wait\n" " up to w seconds for TUN/TAP adapter to come up.\n" - "--route-up cmd : Execute shell cmd after routes are added.\n" + "--route-up cmd : Run command cmd after routes are added.\n" + "--route-pre-down cmd : Run command cmd before routes are removed.\n" "--route-noexec : Don't add routes automatically. Instead pass routes to\n" " --route-up script using environmental variables.\n" "--route-nopull : When used with --client or --pull, accept options pushed\n" - " by server EXCEPT for routes.\n" + " by server EXCEPT for routes and dhcp options.\n" "--allow-pull-fqdn : Allow client to pull DNS names from server for\n" " --ifconfig, --route, and --route-gateway.\n" "--redirect-gateway [flags]: Automatically execute routing\n" @@ -207,13 +239,16 @@ 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 "--setenv name value : Set a custom environmental variable to pass to script.\n" "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n" " directives for future OpenVPN versions to be ignored.\n" - "--script-security level mode : mode='execve' (default) or 'system', level=\n" + "--script-security level: Where level can be:\n" " 0 -- strictly no calling of external programs\n" " 1 -- (default) only call built-ins such as ifconfig\n" " 2 -- allow calling of built-ins and scripts\n" @@ -264,25 +299,32 @@ static const char usage_message[] = " or --fragment max value, whichever is lower.\n" "--sndbuf size : Set the TCP/UDP send buffer size.\n" "--rcvbuf size : Set the TCP/UDP receive buffer size.\n" +#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK + "--mark value : Mark encrypted packets being sent with value. The mark value\n" + " can be matched in policy routing and packetfilter rules.\n" +#endif "--txqueuelen n : Set the tun/tap TX queue length to n (Linux only).\n" +#ifdef ENABLE_MEMSTATS + "--memstats file : Write live usage stats to memory mapped binary file.\n" +#endif "--mlock : Disable Paging -- ensures key material and tunnel\n" " data will never be written to disk.\n" - "--up cmd : Shell cmd to execute after successful tun device open.\n" + "--up cmd : Run command cmd after successful tun device open.\n" " Execute as: cmd tun/tap-dev tun-mtu link-mtu \\\n" " ifconfig-local-ip ifconfig-remote-ip\n" " (pre --user or --group UID/GID change)\n" "--up-delay : Delay tun/tap open and possible --up script execution\n" " until after TCP/UDP connection establishment with peer.\n" - "--down cmd : Shell cmd to run after tun device close.\n" + "--down cmd : Run command cmd after tun device close.\n" " (post --user/--group UID/GID change and/or --chroot)\n" - " (script parameters are same as --up option)\n" - "--down-pre : Call --down cmd/script before TUN/TAP close.\n" - "--up-restart : Run up/down scripts for all restarts including those\n" + " (command parameters are same as --up option)\n" + "--down-pre : Run --down command before TUN/TAP close.\n" + "--up-restart : Run up/down commands for all restarts including those\n" " caused by --ping-restart or SIGUSR1\n" "--user user : Set UID to user after initialization.\n" "--group group : Set GID to group after initialization.\n" "--chroot dir : Chroot to this directory after initialization.\n" -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX "--setcon context: Apply this SELinux context after initialization.\n" #endif "--cd dir : Change to this directory before initialization.\n" @@ -320,7 +362,7 @@ static const char usage_message[] = #ifdef ENABLE_DEBUG "--gremlin mask : Special stress testing mode (for debugging only).\n" #endif -#ifdef USE_LZO +#ifdef ENABLE_LZO "--comp-lzo : Use fast 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" @@ -338,11 +380,14 @@ static const char usage_message[] = " ip/port rather than listen as a TCP server.\n" "--management-query-passwords : Query management channel for private key\n" " and auth-user-pass passwords.\n" + "--management-query-proxy : Query management channel for proxy information.\n" + "--management-query-remote : Query management channel for --remote directive.\n" "--management-hold : Start " PACKAGE_NAME " in a hibernating state, until a client\n" " of the management interface explicitly starts it.\n" "--management-signal : Issue SIGUSR1 when management disconnect event occurs.\n" "--management-forget-disconnect : Forget passwords when management disconnect\n" " event occurs.\n" + "--management-up-down : Report tunnel up/down events to management interface.\n" "--management-log-cache n : Cache n lines of log file history for usage\n" " by the management channel.\n" #if UNIX_SOCK_SUPPORT @@ -370,6 +415,7 @@ static const char usage_message[] = "\n" "Multi-Client Server options (when --mode server is used):\n" "--server network netmask : Helper option to easily configure server mode.\n" + "--server-ipv6 network/bits : Configure IPv6 server mode.\n" "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n" " easily configure ethernet bridging server mode.\n" "--push \"option\" : Push a config file option back to the peer for remote\n" @@ -383,10 +429,16 @@ static const char usage_message[] = "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n" " data to file, at seconds intervals (default=600).\n" " If seconds=0, file will be treated as read-only.\n" + "--ifconfig-ipv6-pool base-IP/bits : set aside an IPv6 network block\n" + " to be dynamically allocated to connecting clients.\n" "--ifconfig-push local remote-netmask : Push an ifconfig option to remote,\n" " overrides --ifconfig-pool dynamic allocation.\n" " Only valid in a client-specific config file.\n" + "--ifconfig-ipv6-push local/bits remote : Push an ifconfig-ipv6 option to\n" + " remote, overrides --ifconfig-ipv6-pool allocation.\n" + " Only valid in a client-specific config file.\n" "--iroute network [netmask] : Route subnet to client.\n" + "--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n" " Sets up internal routes only.\n" " Only valid in a client-specific config file.\n" "--disable : Client is disabled.\n" @@ -397,7 +449,7 @@ static const char usage_message[] = " the authenticated username as the common name,\n" " rather than the common name from the client cert.\n" "--auth-user-pass-verify cmd method: Query client for username/password and\n" - " run script cmd to verify. If method='via-env', pass\n" + " 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" "--opt-verify : Clients that connect with options that are incompatible\n" @@ -409,8 +461,8 @@ static const char usage_message[] = "--client-to-client : Internally route client-to-client traffic.\n" "--duplicate-cn : Allow multiple clients with the same common name to\n" " concurrently connect.\n" - "--client-connect cmd : Run script cmd on client connection.\n" - "--client-disconnect cmd : Run script cmd on client disconnection.\n" + "--client-connect cmd : Run command cmd on client connection.\n" + "--client-disconnect cmd : Run command cmd on client disconnection.\n" "--client-config-dir dir : Directory for custom client config files.\n" "--ccd-exclusive : Refuse connection unless custom client config is found.\n" "--tmp-dir dir : Temporary directory, used for --client-connect return file and plugin communication.\n" @@ -420,13 +472,17 @@ static const char usage_message[] = "--tcp-queue-limit n : Maximum number of queued TCP output packets.\n" "--tcp-nodelay : Macro that sets TCP_NODELAY socket flag on the server\n" " as well as pushes it to connecting clients.\n" - "--learn-address cmd : Run script cmd to validate client virtual addresses.\n" + "--learn-address cmd : Run command cmd to validate client virtual addresses.\n" "--connect-freq n s : Allow a maximum of n new connections per s seconds.\n" "--max-clients n : Allow a maximum of n simultaneously connected clients.\n" "--max-routes-per-client n : Allow a maximum of n internal routes per client.\n" + "--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" #if PORT_SHARE - "--port-share host port : When run in TCP mode, proxy incoming HTTPS sessions\n" - " to a web server at host:port.\n" + "--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" + " optional directory to write origin IP:port data.\n" #endif #endif "\n" @@ -440,6 +496,8 @@ static const char usage_message[] = " when connecting to a '--mode server' remote host.\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" " in a round-robin fashion, spend no more than n seconds\n" " waiting for a response before trying the next server.\n" @@ -448,7 +506,7 @@ static const char usage_message[] = "--explicit-exit-notify [n] : On exit/restart, send exit signal to\n" " server/remote. n = # of retries, default=1.\n" #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO "\n" "Data Channel Encryption Options (must be compatible between peers):\n" "(These options are meaningful for both Static Key & TLS-mode)\n" @@ -471,7 +529,9 @@ static const char usage_message[] = "--keysize n : Size of cipher key in bits (optional).\n" " If unspecified, defaults to cipher-specific default.\n" #endif +#ifndef ENABLE_CRYPTO_POLARSSL "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n" +#endif "--no-replay : Disable replay protection.\n" "--mute-replay-warnings : Silence the output of replay warnings to log file.\n" "--replay-window n [t] : Use a replay protection sliding window of size n\n" @@ -482,7 +542,11 @@ static const char usage_message[] = " using file.\n" "--test-crypto : Run a self-test of crypto features enabled.\n" " For debugging only.\n" -#ifdef USE_SSL +#ifdef ENABLE_PREDICTION_RESISTANCE + "--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" @@ -492,25 +556,31 @@ 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 "--capath dir : A directory of trusted certificates (CAs" #if OPENSSL_VERSION_NUMBER >= 0x00907000L " and CRLs).\n" -#else +#else /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ ").\n" " WARNING: no support of CRL available with this version.\n" -#endif +#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ +#endif /* ENABLE_CRYPTO_POLARSSL */ "--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" "--cert file : Local certificate in .pem format -- must be signed\n" " by a Certificate Authority in --ca file.\n" + "--extra-certs file : one or more PEM certs that complete the cert chain.\n" "--key file : Local private key in .pem format.\n" +#ifndef ENABLE_CRYPTO_POLARSSL "--pkcs12 file : PKCS#12 file containing local private key, local certificate\n" " and optionally the root CA certificate.\n" +#endif #ifdef ENABLE_X509ALTUSERNAME "--x509-username-field : Field used in x509 certificate to be username.\n" " Default is CN.\n" #endif + "--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n" #ifdef WIN32 "--cryptoapicert select-string : Load the certificate and private key from the\n" " Windows Certificate System Store.\n" @@ -535,12 +605,12 @@ static const char usage_message[] = " 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: Check peer certificate against a CRL.\n" - "--tls-verify cmd: Execute shell command cmd to verify the X509 name of a\n" + "--crl-verify crl ['dir']: Check peer certificate against a CRL.\n" + "--tls-verify cmd: Run command cmd to verify the X509 name of a\n" " pending TLS connection that has otherwise passed all other\n" " tests of certification. cmd should return 0 to allow\n" " TLS handshake to proceed, or 1 to fail. (cmd is\n" - " executed as 'cmd certificate_depth X509_NAME_oneline')\n" + " executed as 'cmd certificate_depth subject')\n" "--tls-export-cert [directory] : Get peer cert in PEM format and store it \n" " in an openvpn temporary file in [directory]. Peer cert is \n" " stored before tls-verify script execution and deleted after.\n" @@ -549,7 +619,11 @@ 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" -#if OPENSSL_VERSION_NUMBER >= 0x00907000L +#ifdef ENABLE_X509_TRACK + "--x509-track x : Save peer X509 attribute x in environment for use by\n" + " plugins and management interface.\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" @@ -559,8 +633,8 @@ 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 */ -#endif /* USE_SSL */ +#endif /* OPENSSL_VERSION_NUMBER || ENABLE_CRYPTO_POLARSSL */ +#endif /* ENABLE_SSL */ #ifdef ENABLE_PKCS11 "\n" "PKCS#11 Options:\n" @@ -585,15 +659,15 @@ 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 USE_SSL +#ifdef ENABLE_SSL "--show-tls : Show all TLS ciphers (TLS used only as a control channel).\n" #endif #ifdef WIN32 "\n" "Windows Specific:\n" - "--win-sys path|'env' : Pathname of Windows system directory, C:\\WINDOWS by default.\n" - " If specified as 'env', read the pathname from SystemRoot env var.\n" - "--ip-win32 method : When using --ifconfig on Windows, set TAP-Win32 adapter\n" + "--win-sys path : Pathname of Windows system directory. Default is the pathname\n" + " from SystemRoot environment variable.\n" + "--ip-win32 method : When using --ifconfig on Windows, set TAP-Windows adapter\n" " IP address using method = manual, netsh, ipapi,\n" " dynamic, or adaptive (default = adaptive).\n" " Dynamic method allows two optional parameters:\n" @@ -609,7 +683,7 @@ static const char usage_message[] = " adaptive (default) -- Try ipapi then fall back to exe.\n" " ipapi -- Use IP helper API.\n" " exe -- Call the route.exe shell command.\n" - "--dhcp-option type [parm] : Set extended TAP-Win32 properties, must\n" + "--dhcp-option type [parm] : Set extended TAP-Windows properties, must\n" " be used with --ip-win32 dynamic. For options\n" " which allow multiple addresses,\n" " --dhcp-option must be repeated.\n" @@ -640,7 +714,7 @@ static const char usage_message[] = " after TAP adapter is up and routes have been added.\n" "Windows Standalone Options:\n" "\n" - "--show-adapters : Show all TAP-Win32 adapters.\n" + "--show-adapters : Show all TAP-Windows adapters.\n" "--show-net : Show " PACKAGE_NAME "'s view of routing table and net adapter list.\n" "--show-valid-subnets : Show valid subnets for --dev tun emulation.\n" "--allow-nonadmin [TAP-adapter] : Allow " PACKAGE_NAME " running without admin privileges\n" @@ -651,8 +725,8 @@ static const char usage_message[] = "--genkey : Generate a random key to be used as a shared secret,\n" " for use with the --secret option.\n" "--secret file : Write key to file.\n" -#endif /* USE_CRYPTO */ -#ifdef TUNSETPERSIST +#endif /* ENABLE_CRYPTO */ +#ifdef ENABLE_FEATURE_TUN_PERSIST "\n" "Tun/tap config mode (available with linux 2.4+):\n" "--mktun : Create a persistent tunnel.\n" @@ -668,6 +742,11 @@ static const char usage_message[] = "--show-pkcs11-ids provider [cert_private] : Show PKCS#11 available ids.\n" " --verb option can be added *BEFORE* this.\n" #endif /* ENABLE_PKCS11 */ + "\n" + "General Standalone Options:\n" +#ifdef ENABLE_DEBUG + "--show-gateway : Show info about default gateway.\n" +#endif ; #endif /* !ENABLE_SMALL */ @@ -697,10 +776,10 @@ init_options (struct options *o, const bool init_gc) o->status_file_update_freq = 60; o->status_file_version = 1; o->ce.bind_local = true; - o->tun_mtu = TUN_MTU_DEFAULT; - o->link_mtu = LINK_MTU_DEFAULT; - o->mtu_discover_type = -1; - o->mssfix = MSSFIX_DEFAULT; + o->ce.tun_mtu = TUN_MTU_DEFAULT; + o->ce.link_mtu = LINK_MTU_DEFAULT; + 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; @@ -713,7 +792,7 @@ init_options (struct options *o, const bool init_gc) o->management_echo_buffer_size = 100; o->management_state_buffer_size = 100; #endif -#ifdef TUNSETPERSIST +#ifdef ENABLE_FEATURE_TUN_PERSIST o->persist_mode = 1; #endif #ifndef WIN32 @@ -740,13 +819,14 @@ init_options (struct options *o, const bool init_gc) o->tcp_queue_limit = 64; o->max_clients = 1024; o->max_routes_per_client = 256; + o->stale_routes_check_interval = 0; o->ifconfig_pool_persist_refresh_freq = 600; #endif #if P2MP o->scheduled_exit_interval = 5; o->server_poll_timeout = 0; #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO o->ciphername = "BF-CBC"; o->ciphername_defined = true; o->authname = "SHA1"; @@ -758,7 +838,10 @@ init_options (struct options *o, const bool init_gc) o->replay_time = DEFAULT_TIME_BACKTRACK; o->use_iv = true; o->key_direction = KEY_DIRECTION_BIDIRECTIONAL; -#ifdef USE_SSL +#ifdef ENABLE_PREDICTION_RESISTANCE + o->use_prediction_resistance = false; +#endif +#ifdef ENABLE_SSL o->key_method = 2; o->tls_timeout = 2; o->renegotiate_seconds = 3600; @@ -767,12 +850,14 @@ init_options (struct options *o, const bool init_gc) #ifdef ENABLE_X509ALTUSERNAME o->x509_username_field = X509_USERNAME_FIELD_DEFAULT; #endif -#endif /* USE_SSL */ -#endif /* USE_CRYPTO */ +#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 */ +#if P2MP_SERVER /* Set default --tmp-dir */ #ifdef WIN32 /* On Windows, find temp dir via enviroment variables */ @@ -784,6 +869,7 @@ init_options (struct options *o, const bool init_gc) o->tmp_dir = "/tmp"; } #endif /* WIN32 */ +#endif /* P2MP_SERVER */ } void @@ -841,9 +927,8 @@ setenv_settings (struct env_set *es, const struct options *o) setenv_int (es, "daemon", o->daemon); setenv_int (es, "daemon_log_redirect", o->log); setenv_unsigned (es, "daemon_start_time", time(NULL)); - setenv_int (es, "daemon_pid", openvpn_getpid()); + setenv_int (es, "daemon_pid", platform_getpid()); -#ifdef ENABLE_CONNECTION if (o->connection_list) { int i; @@ -851,7 +936,6 @@ setenv_settings (struct env_set *es, const struct options *o) setenv_connection_entry (es, o->connection_list->array[i], i+1); } else -#endif setenv_connection_entry (es, &o->ce, 1); } @@ -871,6 +955,78 @@ get_ip_addr (const char *ip_string, int msglevel, bool *error) return ret; } +/* helper: parse a text string containing an IPv6 address + netbits + * in "standard format" (2001:dba::/32) + * "/nn" is optional, default to /64 if missing + * + * return true if parsing succeeded, modify *network and *netbits + * return address part without "/nn" in *printable_ipv6 (if != NULL) + */ +bool +get_ipv6_addr( const char * prefix_str, struct in6_addr *network, + unsigned int * netbits, char ** printable_ipv6, int msglevel ) +{ + int rc; + char * sep, * endp; + int bits; + struct in6_addr t_network; + + sep = strchr( prefix_str, '/' ); + if ( sep == NULL ) + { + bits = 64; + } + else + { + bits = strtol( sep+1, &endp, 10 ); + if ( *endp != '\0' || bits < 0 || bits > 128 ) + { + msg (msglevel, "IPv6 prefix '%s': invalid '/bits' spec", prefix_str); + return false; + } + } + + /* temporary replace '/' in caller-provided string with '\0', otherwise + * inet_pton() will refuse prefix string + * (alternative would be to strncpy() the prefix to temporary buffer) + */ + + if ( sep != NULL ) *sep = '\0'; + + rc = inet_pton( AF_INET6, prefix_str, &t_network ); + + if ( rc == 1 && printable_ipv6 != NULL ) + { + *printable_ipv6 = string_alloc( prefix_str, NULL ); + } + + if ( sep != NULL ) *sep = '/'; + + if ( rc != 1 ) + { + msg (msglevel, "IPv6 prefix '%s': invalid IPv6 address", prefix_str); + return false; + } + + if ( netbits != NULL ) + { + *netbits = bits; + } + if ( network != NULL ) + { + *network = t_network; + } + return true; /* parsing OK, values set */ +} + +static bool ipv6_addr_safe_hexplusbits( const char * ipv6_prefix_spec ) +{ + struct in6_addr t_addr; + unsigned int t_bits; + + return get_ipv6_addr( ipv6_prefix_spec, &t_addr, &t_bits, NULL, M_WARN ); +} + static char * string_substitute (const char *src, int from, int to, struct gc_arena *gc) { @@ -889,21 +1045,39 @@ string_substitute (const char *src, int from, int to, struct gc_arena *gc) return ret; } -bool -is_persist_option (const struct options *o) -{ - return o->persist_tun - || o->persist_key - || o->persist_local_ip - || o->persist_remote_ip - ; -} - -bool -is_stateful_restart (const struct options *o) +#ifdef ENABLE_SSL +static uint8_t * +parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc) { - return is_persist_option (o) || connection_list_defined (o); + int i; + const char *cp = str; + uint8_t *ret = (uint8_t *) gc_malloc (nbytes, true, gc); + char term = 1; + int byte; + char bs[3]; + + for (i = 0; i < nbytes; ++i) + { + if (strlen(cp) < 2) + msg (msglevel, "format error in hash fingerprint: %s", str); + bs[0] = *cp++; + bs[1] = *cp++; + bs[2] = 0; + byte = 0; + if (sscanf(bs, "%x", &byte) != 1) + msg (msglevel, "format error in hash fingerprint hex byte: %s", str); + ret[i] = (uint8_t)byte; + term = *cp++; + if (term != ':' && term != 0) + msg (msglevel, "format error in hash fingerprint delimiter: %s", str); + if (term == 0) + break; + } + if (term != 0 || i != nbytes-1) + msg (msglevel, "hash fingerprint is different length than expected (%d bytes): %s", nbytes, str); + return ret; } +#endif #ifdef WIN32 @@ -989,6 +1163,8 @@ show_p2mp_parms (const struct options *o) #if P2MP_SERVER msg (D_SHOW_PARMS, " server_network = %s", print_in_addr_t (o->server_network, 0, &gc)); msg (D_SHOW_PARMS, " server_netmask = %s", print_in_addr_t (o->server_netmask, 0, &gc)); + msg (D_SHOW_PARMS, " server_network_ipv6 = %s", print_in6_addr (o->server_network_ipv6, 0, &gc) ); + SHOW_INT (server_netbits_ipv6); msg (D_SHOW_PARMS, " server_bridge_ip = %s", print_in_addr_t (o->server_bridge_ip, 0, &gc)); msg (D_SHOW_PARMS, " server_bridge_netmask = %s", print_in_addr_t (o->server_bridge_netmask, 0, &gc)); msg (D_SHOW_PARMS, " server_bridge_pool_start = %s", print_in_addr_t (o->server_bridge_pool_start, 0, &gc)); @@ -1009,6 +1185,9 @@ show_p2mp_parms (const struct options *o) msg (D_SHOW_PARMS, " ifconfig_pool_netmask = %s", print_in_addr_t (o->ifconfig_pool_netmask, 0, &gc)); SHOW_STR (ifconfig_pool_persist_filename); SHOW_INT (ifconfig_pool_persist_refresh_freq); + SHOW_BOOL (ifconfig_ipv6_pool_defined); + msg (D_SHOW_PARMS, " ifconfig_ipv6_pool_base = %s", print_in6_addr (o->ifconfig_ipv6_pool_base, 0, &gc)); + SHOW_INT (ifconfig_ipv6_pool_netbits); SHOW_INT (n_bcast_buf); SHOW_INT (tcp_queue_limit); SHOW_INT (real_hash_size); @@ -1022,6 +1201,9 @@ show_p2mp_parms (const struct options *o) SHOW_BOOL (push_ifconfig_defined); msg (D_SHOW_PARMS, " push_ifconfig_local = %s", print_in_addr_t (o->push_ifconfig_local, 0, &gc)); msg (D_SHOW_PARMS, " push_ifconfig_remote_netmask = %s", print_in_addr_t (o->push_ifconfig_remote_netmask, 0, &gc)); + SHOW_BOOL (push_ifconfig_ipv6_defined); + msg (D_SHOW_PARMS, " push_ifconfig_ipv6_local = %s/%d", print_in6_addr (o->push_ifconfig_ipv6_local, 0, &gc), o->push_ifconfig_ipv6_netbits ); + msg (D_SHOW_PARMS, " push_ifconfig_ipv6_remote = %s", print_in6_addr (o->push_ifconfig_ipv6_remote, 0, &gc)); SHOW_BOOL (enable_c2c); SHOW_BOOL (duplicate_cn); SHOW_INT (cf_max); @@ -1030,7 +1212,6 @@ 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_INT (ssl_flags); #if PORT_SHARE SHOW_STR (port_share_host); SHOW_INT (port_share_port); @@ -1076,6 +1257,25 @@ option_iroute (struct options *o, o->iroutes = ir; } +static void +option_iroute_ipv6 (struct options *o, + const char *prefix_str, + int msglevel) +{ + struct iroute_ipv6 *ir; + + ALLOC_OBJ_GC (ir, struct iroute_ipv6, &o->gc); + + if ( get_ipv6_addr (prefix_str, &ir->network, &ir->netbits, NULL, msglevel ) < 0 ) + { + msg (msglevel, "in --iroute-ipv6 %s: Bad IPv6 prefix specification", + prefix_str); + return; + } + + ir->next = o->iroutes_ipv6; + o->iroutes_ipv6 = ir; +} #endif /* P2MP_SERVER */ #endif /* P2MP */ @@ -1101,6 +1301,9 @@ 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 @@ -1113,6 +1316,22 @@ rol_check_alloc (struct options *options) options->routes = new_route_option_list (options->max_routes, &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); +} + +#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 + #ifdef ENABLE_DEBUG static void show_connection_entry (const struct connection_entry *o) @@ -1138,14 +1357,31 @@ show_connection_entry (const struct connection_entry *o) SHOW_INT (socks_proxy_port); SHOW_BOOL (socks_proxy_retry); #endif + SHOW_INT (tun_mtu); + SHOW_BOOL (tun_mtu_defined); + SHOW_INT (link_mtu); + SHOW_BOOL (link_mtu_defined); + SHOW_INT (tun_mtu_extra); + SHOW_BOOL (tun_mtu_extra_defined); + + SHOW_INT (mtu_discover_type); + +#ifdef ENABLE_FRAGMENT + SHOW_INT (fragment); +#endif + SHOW_INT (mssfix); + +#ifdef ENABLE_OCC + SHOW_INT (explicit_exit_notification); +#endif } + static void show_connection_entries (const struct options *o) { msg (D_SHOW_PARMS, "Connection profiles [default]:"); show_connection_entry (&o->ce); -#ifdef ENABLE_CONNECTION if (o->connection_list) { const struct connection_list *l = o->connection_list; @@ -1156,7 +1392,6 @@ show_connection_entries (const struct options *o) show_connection_entry (l->array[i]); } } -#endif msg (D_SHOW_PARMS, "Connection profiles END"); } @@ -1172,17 +1407,17 @@ show_settings (const struct options *o) SHOW_INT (mode); -#ifdef TUNSETPERSIST +#ifdef ENABLE_FEATURE_TUN_PERSIST SHOW_BOOL (persist_config); SHOW_INT (persist_mode); #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO SHOW_BOOL (show_ciphers); SHOW_BOOL (show_digests); SHOW_BOOL (show_engines); SHOW_BOOL (genkey); -#ifdef USE_SSL +#ifdef ENABLE_SSL SHOW_STR (key_pass_file); SHOW_BOOL (show_tls_ciphers); #endif @@ -1203,23 +1438,13 @@ show_settings (const struct options *o) SHOW_STR (ifconfig_remote_netmask); SHOW_BOOL (ifconfig_noexec); SHOW_BOOL (ifconfig_nowarn); + SHOW_STR (ifconfig_ipv6_local); + SHOW_INT (ifconfig_ipv6_netbits); + SHOW_STR (ifconfig_ipv6_remote); -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER SHOW_INT (shaper); #endif - SHOW_INT (tun_mtu); - SHOW_BOOL (tun_mtu_defined); - SHOW_INT (link_mtu); - SHOW_BOOL (link_mtu_defined); - SHOW_INT (tun_mtu_extra); - SHOW_BOOL (tun_mtu_extra_defined); - -#ifdef ENABLE_FRAGMENT - SHOW_INT (fragment); -#endif - - SHOW_INT (mtu_discover_type); - #ifdef ENABLE_OCC SHOW_INT (mtu_test); #endif @@ -1234,16 +1459,11 @@ show_settings (const struct options *o) SHOW_INT (ping_rec_timeout_action); SHOW_BOOL (ping_timer_remote); SHOW_INT (remap_sigusr1); -#ifdef ENABLE_OCC - SHOW_INT (explicit_exit_notification); -#endif SHOW_BOOL (persist_tun); SHOW_BOOL (persist_local_ip); SHOW_BOOL (persist_remote_ip); SHOW_BOOL (persist_key); - SHOW_INT (mssfix); - #if PASSTOS_CAPABILITY SHOW_BOOL (passtos); #endif @@ -1254,7 +1474,7 @@ show_settings (const struct options *o) SHOW_STR (groupname); SHOW_STR (chroot_dir); SHOW_STR (cd_dir); -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX SHOW_STR (selinux_context); #endif SHOW_STR (writepid); @@ -1282,11 +1502,14 @@ show_settings (const struct options *o) #endif SHOW_INT (rcvbuf); SHOW_INT (sndbuf); +#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK + SHOW_INT (mark); +#endif SHOW_INT (sockflags); SHOW_BOOL (fast_io); -#ifdef USE_LZO +#ifdef ENABLE_LZO SHOW_INT (lzo); #endif @@ -1303,6 +1526,11 @@ show_settings (const struct options *o) SHOW_BOOL (allow_pull_fqdn); 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); @@ -1320,7 +1548,7 @@ show_settings (const struct options *o) plugin_option_list_print (o->plugin_list, D_SHOW_PARMS); #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO SHOW_STR (shared_secret_file); SHOW_INT (key_direction); SHOW_BOOL (ciphername_defined); @@ -1330,7 +1558,9 @@ show_settings (const struct options *o) SHOW_STR (prng_hash); SHOW_INT (prng_nonce_secret_len); SHOW_INT (keysize); +#ifndef ENABLE_CRYPTO_POLARSSL SHOW_BOOL (engine); +#endif /* ENABLE_CRYPTO_POLARSSL */ SHOW_BOOL (replay); SHOW_BOOL (mute_replay_warnings); SHOW_INT (replay_window); @@ -1338,8 +1568,11 @@ show_settings (const struct options *o) SHOW_STR (packet_id_file); SHOW_BOOL (use_iv); SHOW_BOOL (test_crypto); +#ifdef ENABLE_PREDICTION_RESISTANCE + SHOW_BOOL (use_prediction_resistance); +#endif -#ifdef USE_SSL +#ifdef ENABLE_SSL SHOW_BOOL (tls_server); SHOW_BOOL (tls_client); SHOW_INT (key_method); @@ -1347,9 +1580,17 @@ show_settings (const struct options *o) SHOW_STR (ca_path); SHOW_STR (dh_file); SHOW_STR (cert_file); + +#ifdef MANAGMENT_EXTERNAL_KEY + if((o->management_flags & MF_EXTERNAL_KEY)) + SHOW_PARM ("priv_key_file","EXTERNAL_PRIVATE_KEY","%s"); + else +#endif SHOW_STR (priv_key_file); +#ifndef ENABLE_CRYPTO_POLARSSL SHOW_STR (pkcs12_file); -#ifdef WIN32 +#endif +#ifdef ENABLE_CRYPTOAPI SHOW_STR (cryptoapi_cert); #endif SHOW_STR (cipher_list); @@ -1364,6 +1605,7 @@ show_settings (const struct options *o) SHOW_INT (remote_cert_ku[i]); } SHOW_STR (remote_cert_eku); + SHOW_INT (ssl_flags); SHOW_INT (tls_timeout); @@ -1427,24 +1669,7 @@ show_settings (const struct options *o) #undef SHOW_INT #undef SHOW_BOOL -#ifdef ENABLE_HTTP_PROXY - -struct http_proxy_options * -init_http_options_if_undefined (struct options *o) -{ - if (!o->ce.http_proxy_options) - { - ALLOC_OBJ_CLEAR_GC (o->ce.http_proxy_options, struct http_proxy_options, &o->gc); - /* http proxy defaults */ - o->ce.http_proxy_options->timeout = 5; - o->ce.http_proxy_options->http_version = "1.0"; - } - return o->ce.http_proxy_options; -} - -#endif - -#if HTTP_PROXY_FALLBACK +#if HTTP_PROXY_OVERRIDE static struct http_proxy_options * parse_http_proxy_override (const char *server, @@ -1481,68 +1706,6 @@ parse_http_proxy_override (const char *server, return NULL; } -struct http_proxy_options * -parse_http_proxy_fallback (struct context *c, - const char *server, - const char *port, - const char *flags, - const int msglevel) -{ - struct gc_arena gc = gc_new (); - struct http_proxy_options *ret = NULL; - struct http_proxy_options *hp = parse_http_proxy_override(server, port, flags, msglevel, &gc); - if (hp) - { - struct hpo_store *hpos = c->options.hpo_store; - if (!hpos) - { - ALLOC_OBJ_CLEAR_GC (hpos, struct hpo_store, &c->options.gc); - c->options.hpo_store = hpos; - } - hpos->hpo = *hp; - hpos->hpo.server = hpos->server; - strncpynt(hpos->server, hp->server, sizeof(hpos->server)); - ret = &hpos->hpo; - } - gc_free (&gc); - return ret; -} - -static void -http_proxy_warn(const char *name) -{ - msg (M_WARN, "Note: option %s ignored because no TCP-based connection profiles are defined", name); -} - -void -options_postprocess_http_proxy_fallback (struct options *o) -{ - struct connection_list *l = o->connection_list; - if (l) - { - int i; - for (i = 0; i < l->len; ++i) - { - struct connection_entry *ce = l->array[i]; - if (ce->proto == PROTO_TCPv4_CLIENT || ce->proto == PROTO_TCPv4) - { - if (l->len < CONNECTION_LIST_SIZE) - { - struct connection_entry *newce; - ALLOC_OBJ_GC (newce, struct connection_entry, &o->gc); - *newce = *ce; - newce->flags |= CE_HTTP_PROXY_FALLBACK; - newce->http_proxy_options = NULL; - newce->ce_http_proxy_fallback_timestamp = 0; - l->array[l->len++] = newce; - } - return; - } - } - } - http_proxy_warn("http-proxy-fallback"); -} - void options_postprocess_http_proxy_override (struct options *o) { @@ -1572,16 +1735,12 @@ options_postprocess_http_proxy_override (struct options *o) } } else - { - http_proxy_warn("http-proxy-override"); - } + msg (M_WARN, "Note: option http-proxy-override ignored because no TCP-based connection profiles are defined"); } } #endif -#if ENABLE_CONNECTION - static struct connection_list * alloc_connection_list_if_undef (struct options *options) { @@ -1630,8 +1789,6 @@ alloc_remote_entry (struct options *options, const int msglevel) return e; } -#endif - void connection_entry_load_re (struct connection_entry *ce, const struct remote_entry *re) { @@ -1652,7 +1809,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne init_options (&defaults, true); -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO if (options->test_crypto) { notnull (options->shared_secret_file, "key file (--secret)"); @@ -1690,7 +1847,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--inetd nowait can only be used with --proto tcp-server"); if (options->inetd == INETD_NOWAIT -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && !(options->tls_server || options->tls_client) #endif ) @@ -1707,20 +1864,24 @@ options_postprocess_verify_ce (const struct options *options, const struct conne * Sanity check on TCP mode options */ - if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT) - msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client"); + 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) - msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-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->tun_mtu_defined && options->link_mtu_defined) + if (options->ce.tun_mtu_defined && options->ce.link_mtu_defined) msg (M_USAGE, "only one of --tun-mtu or --link-mtu may be defined (note that --ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT); #ifdef ENABLE_OCC - if (ce->proto != PROTO_UDPv4 && options->mtu_test) + if (!proto_is_udp(ce->proto) && options->mtu_test) msg (M_USAGE, "--mtu-test only makes sense with --proto udp"); #endif @@ -1733,7 +1894,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne * Sanity check on --local, --remote, and --ifconfig */ - if (string_defined_equal (ce->local, ce->remote) + if (proto_is_net(ce->proto) + && string_defined_equal (ce->local, ce->remote) && ce->local_port == ce->remote_port) msg (M_USAGE, "--remote and --local addresses are the same"); @@ -1798,21 +1960,22 @@ options_postprocess_verify_ce (const struct options *options, const struct conne */ #ifdef ENABLE_FRAGMENT - if (ce->proto != PROTO_UDPv4 && options->fragment) + if (!proto_is_udp(ce->proto) && ce->fragment) msg (M_USAGE, "--fragment can only be used with --proto udp"); #endif #ifdef ENABLE_OCC - if (ce->proto != PROTO_UDPv4 && options->explicit_exit_notification) + if (!proto_is_udp(ce->proto) && ce->explicit_exit_notification) msg (M_USAGE, "--explicit-exit-notify can only be used with --proto udp"); #endif - if (!ce->remote && ce->proto == PROTO_TCPv4_CLIENT) + if (!ce->remote && (ce->proto == PROTO_TCPv4_CLIENT + || ce->proto == PROTO_TCPv6_CLIENT)) msg (M_USAGE, "--remote MUST be used in TCP Client mode"); #ifdef ENABLE_HTTP_PROXY - if ((ce->http_proxy_options || options->auto_proxy_info) && ce->proto != PROTO_TCPv4_CLIENT) - msg (M_USAGE, "--http-proxy or --auto-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)"); + if ((ce->http_proxy_options) && ce->proto != PROTO_TCPv4_CLIENT) + msg (M_USAGE, "--http-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)"); #endif #if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_SOCKS) @@ -1825,7 +1988,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--socks-proxy can not be used in TCP Server mode"); #endif - if (ce->proto == PROTO_TCPv4_SERVER && connection_list_defined (options)) + if ((ce->proto == PROTO_TCPv4_SERVER || ce->proto == PROTO_TCPv6_SERVER) + && connection_list_defined (options)) msg (M_USAGE, "TCP server mode allows at most one --remote address"); #if P2MP_SERVER @@ -1839,11 +2003,15 @@ 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 (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER)) - msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); + if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCPv4_SERVER + || ce->proto == PROTO_TCPv6_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) - msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server)"); + if ((options->port_share_host || options->port_share_port) && + (ce->proto != PROTO_TCPv4_SERVER && ce->proto != PROTO_TCPv6_SERVER)) + msg (M_USAGE, "--port-share only works in TCP server mode " + "(--proto tcp-server or tcp6-server)"); #endif if (!options->tls_server) msg (M_USAGE, "--mode server requires --tls-server"); @@ -1859,26 +2027,28 @@ options_postprocess_verify_ce (const struct options *options, const struct conne if (ce->socks_proxy_server) msg (M_USAGE, "--socks-proxy cannot be used with --mode server"); #endif -#ifdef ENABLE_CONNECTION if (options->connection_list) msg (M_USAGE, "<connection> cannot be used with --mode server"); -#endif +#if 0 if (options->tun_ipv6) msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server"); +#endif 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 (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER)) - msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); - if (ce->proto != PROTO_UDPv4 && (options->cf_max || options->cf_per)) + if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCPv4_SERVER + || ce->proto == PROTO_TCPv6_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 (options->explicit_exit_notification) + 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)) @@ -1889,6 +2059,11 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--up-delay cannot be used with --mode server"); if (!options->ifconfig_pool_defined && options->ifconfig_pool_persist_filename) 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->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) @@ -1908,9 +2083,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne if ((options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) && !ccnr) msg (M_USAGE, "--auth-user-pass-optional %s", postfix); } - - if ((options->ssl_flags & SSLF_NO_NAME_REMAPPING) && script_method == SM_SYSTEM) - msg (M_USAGE, "--script-security method='system' cannot be combined with --no-name-remapping"); } else { @@ -1920,6 +2092,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne */ if (options->ifconfig_pool_defined || options->ifconfig_pool_persist_filename) msg (M_USAGE, "--ifconfig-pool/--ifconfig-pool-persist requires --mode server"); + if (options->ifconfig_ipv6_pool_defined) + msg (M_USAGE, "--ifconfig-ipv6-pool requires --mode server"); if (options->real_hash_size != defaults.real_hash_size || options->virtual_hash_size != defaults.virtual_hash_size) msg (M_USAGE, "--hash-size requires --mode server"); @@ -1943,8 +2117,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--username-as-common-name requires --mode server"); if (options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) msg (M_USAGE, "--auth-user-pass-optional requires --mode server"); - if (options->ssl_flags & SSLF_NO_NAME_REMAPPING) - msg (M_USAGE, "--no-name-remapping requires --mode server"); if (options->ssl_flags & SSLF_OPT_VERIFY) msg (M_USAGE, "--opt-verify requires --mode server"); if (options->server_flags & SF_TCP_NODELAY_HELPER) @@ -1956,15 +2128,20 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)"); #endif + if (options->stale_routes_check_interval) + msg (M_USAGE, "--stale-routes-check requires --mode server"); + + if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING)) + msg (M_USAGE, "--compat-x509-names no-remapping requires --mode server"); } #endif /* P2MP_SERVER */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* * Check consistency of replay options */ - if ((ce->proto != PROTO_UDPv4) + 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"); @@ -1978,7 +2155,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne * SSL/TLS mode sanity checks. */ -#ifdef USE_SSL +#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"); @@ -2002,17 +2179,28 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified."); if (options->priv_key_file) msg(M_USAGE, "Parameter --key cannot be used when --pkcs11-provider is also specified."); +#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."); +#endif if (options->pkcs12_file) msg(M_USAGE, "Parameter --pkcs12 cannot be used when --pkcs11-provider is also specified."); -#ifdef WIN32 +#ifdef ENABLE_CRYPTOAPI if (options->cryptoapi_cert) msg(M_USAGE, "Parameter --cryptoapicert cannot be used when --pkcs11-provider is also specified."); #endif } else #endif -#ifdef WIN32 - if (options->cryptoapi_cert) +#ifdef MANAGMENT_EXTERNAL_KEY + if((options->management_flags & MF_EXTERNAL_KEY) && options->priv_key_file) + { + msg (M_USAGE, "--key and --management-external-key are mutually exclusive"); + } + else +#endif +#ifdef ENABLE_CRYPTOAPI + if (options->cryptoapi_cert) { if ((!(options->ca_file)) && (!(options->ca_path))) msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)"); @@ -2022,25 +2210,52 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg(M_USAGE, "Parameter --key cannot be used when --cryptoapicert is also specified."); if (options->pkcs12_file) msg(M_USAGE, "Parameter --pkcs12 cannot be used when --cryptoapicert is also specified."); +#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."); +#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."); +#else if (options->ca_path) msg(M_USAGE, "Parameter --capath cannot be used when --pkcs12 is also specified."); if (options->cert_file) msg(M_USAGE, "Parameter --cert cannot be used when --pkcs12 is also specified."); if (options->priv_key_file) 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."); +#endif +#endif } else { +#ifdef ENABLE_CRYPTO_POLARSSL + 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."); +#else if ((!(options->ca_file)) && (!(options->ca_path))) msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)"); +#endif if (pull) { - const int sum = (options->cert_file != NULL) + (options->priv_key_file != NULL); + + const int sum = (options->cert_file != NULL) + +#ifdef MANAGMENT_EXTERNAL_KEY + ((options->priv_key_file != NULL) || (options->management_flags & MF_EXTERNAL_KEY)); +#else + (options->priv_key_file != NULL); +#endif + + if (sum == 0) { #if P2MP @@ -2058,6 +2273,9 @@ options_postprocess_verify_ce (const struct options *options, const struct conne else { notnull (options->cert_file, "certificate file (--cert) or PKCS#12 file (--pkcs12)"); +#ifdef MANAGMENT_EXTERNAL_KEY + if (!options->management_flags & MF_EXTERNAL_KEY) +#endif notnull (options->priv_key_file, "private key file (--key) or PKCS#12 file (--pkcs12)"); } } @@ -2078,7 +2296,9 @@ 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 MUST_BE_UNDEF (pkcs12_file); +#endif MUST_BE_UNDEF (cipher_list); MUST_BE_UNDEF (tls_verify); MUST_BE_UNDEF (tls_export_cert); @@ -2111,8 +2331,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne msg (M_USAGE, err, "--pull"); } #undef MUST_BE_UNDEF -#endif /* USE_CRYPTO */ -#endif /* USE_SSL */ +#endif /* ENABLE_CRYPTO */ +#endif /* ENABLE_SSL */ #if P2MP if (options->auth_user_pass_file && !options->pull) @@ -2125,6 +2345,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne static void options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce) { + const int dev = dev_type_enum (o->dev, o->dev_type); + #if P2MP_SERVER if (o->server_defined || o->server_bridge_defined || o->server_bridge_proxy_dhcp) { @@ -2137,6 +2359,8 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce) { if (ce->proto == PROTO_TCPv4) ce->proto = PROTO_TCPv4_CLIENT; + else if (ce->proto == PROTO_TCPv6) + ce->proto = PROTO_TCPv6_CLIENT; } #endif @@ -2152,51 +2376,52 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce) ce->local_port = 0; /* if protocol forcing is enabled, disable all protocols except for the forced one */ - if (o->proto_force >= 0 && is_proto_tcp(o->proto_force) != is_proto_tcp(ce->proto)) + if (o->proto_force >= 0 && proto_is_tcp(o->proto_force) != proto_is_tcp(ce->proto)) ce->flags |= CE_DISABLED; -} - -static void -options_postprocess_mutate_invariant (struct options *options) -{ - const int dev = dev_type_enum (options->dev, options->dev_type); /* * If --mssfix is supplied without a parameter, default * it to --fragment value, if --fragment is specified. */ - if (options->mssfix_default) + if (o->ce.mssfix_default) { #ifdef ENABLE_FRAGMENT - if (options->fragment) - options->mssfix = options->fragment; + if (ce->fragment) + o->ce.mssfix = ce->fragment; #else msg (M_USAGE, "--mssfix must specify a parameter"); #endif } /* - * In forking TCP server mode, you don't need to ifconfig - * the tap device (the assumption is that it will be bridged). - */ - if (options->inetd == INETD_NOWAIT) - options->ifconfig_noexec = true; - - /* * Set MTU defaults */ { - if (!options->tun_mtu_defined && !options->link_mtu_defined) + if (!ce->tun_mtu_defined && !ce->link_mtu_defined) { - options->tun_mtu_defined = true; + ce->tun_mtu_defined = true; } - if ((dev == DEV_TYPE_TAP) && !options->tun_mtu_extra_defined) + if ((dev == DEV_TYPE_TAP) && !ce->tun_mtu_extra_defined) { - options->tun_mtu_extra_defined = true; - options->tun_mtu_extra = TAP_MTU_EXTRA_DEFAULT; + ce->tun_mtu_extra_defined = true; + ce->tun_mtu_extra = TAP_MTU_EXTRA_DEFAULT; } } +} + +static void +options_postprocess_mutate_invariant (struct options *options) +{ + const int dev = dev_type_enum (options->dev, options->dev_type); + + /* + * In forking TCP server mode, you don't need to ifconfig + * the tap device (the assumption is that it will be bridged). + */ + if (options->inetd == INETD_NOWAIT) + options->ifconfig_noexec = true; + #ifdef WIN32 if ((dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP) && !options->route_delay_defined) { @@ -2237,7 +2462,6 @@ options_postprocess_mutate_invariant (struct options *options) static void options_postprocess_verify (const struct options *o) { -#ifdef ENABLE_CONNECTION if (o->connection_list) { int i; @@ -2245,7 +2469,6 @@ options_postprocess_verify (const struct options *o) options_postprocess_verify_ce (o, o->connection_list->array[i]); } else -#endif options_postprocess_verify_ce (o, &o->ce); } @@ -2262,7 +2485,6 @@ options_postprocess_mutate (struct options *o) options_postprocess_mutate_invariant (o); -#ifdef ENABLE_CONNECTION if (o->remote_list && !o->connection_list) { /* @@ -2301,15 +2523,12 @@ options_postprocess_mutate (struct options *o) for (i = 0; i < o->connection_list->len; ++i) options_postprocess_mutate_ce (o, o->connection_list->array[i]); -#if HTTP_PROXY_FALLBACK +#if HTTP_PROXY_OVERRIDE if (o->http_proxy_override) options_postprocess_http_proxy_override(o); - else if (o->http_proxy_fallback) - options_postprocess_http_proxy_fallback(o); #endif } else -#endif options_postprocess_mutate_ce (o, &o->ce); #if P2MP @@ -2321,6 +2540,224 @@ options_postprocess_mutate (struct options *o) } /* + * Check file/directory sanity + * + */ +#ifndef ENABLE_SMALL /** Expect people using the stripped down version to know what they do */ + +#define CHKACC_FILE (1<<0) /** Check for a file/directory precense */ +#define CHKACC_DIRPATH (1<<1) /** Check for directory precense where a file should reside */ +#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" */ + +static bool +check_file_access(const int type, const char *file, const int mode, const char *opt) +{ + int errcode = 0; + + /* If no file configured, no errors to look for */ + if (!file) + return false; + + /* If this may be an inline file, and the proper inline "filename" is set - no issues */ + if ((type & CHKACC_INLINE) && streq(file, INLINE_FILE_TAG) ) + return false; + + /* If stdin is allowed and the file name is 'stdin', then do no + * further checks as stdin is always available + */ + if( (type & CHKACC_ACPTSTDIN) && streq(file, "stdin") ) + return false; + + /* Is the directory path leading to the given file accessible? */ + if (type & CHKACC_DIRPATH) + { + char *fullpath = strdup(file); /* POSIX dirname() implementaion may modify its arguments */ + char *dirpath = dirname(fullpath); + + if (platform_access (dirpath, mode|X_OK) != 0) + errcode = errno; + free(fullpath); + } + + /* Is the file itself accessible? */ + if (!errcode && (type & CHKACC_FILE) && (platform_access (file, mode) != 0) ) + errcode = errno; + + /* If the file exists and is accessible, is it writable? */ + if (!errcode && (type & CHKACC_FILEXSTWR) && (platform_access (file, F_OK) == 0) ) + if (platform_access (file, W_OK) != 0) + errcode = errno; + + /* Scream if an error is found */ + if( errcode > 0 ) + msg (M_NOPREFIX|M_OPTERR, "%s fails with '%s': %s", + opt, file, strerror(errno)); + + /* Return true if an error occured */ + return (errcode != 0 ? true : false); +} + +/* + * Verifies that the path in the "command" that comes after certain script options (e.g., --up) is a + * valid file with appropriate permissions. + * + * "command" consists of a path, optionally followed by a space, which may be + * followed by arbitrary arguments. It is NOT a full shell command line -- shell expansion is not + * performed. + * + * The path and arguments in "command" may be single- or double-quoted or escaped. + * + * The path is extracted from "command", then check_file_access() is called to check it. The + * arguments, if any, are ignored. + * + * Note that the type, mode, and opt arguments to this routine are the same as the corresponding + * check_file_access() arguments. + */ +static bool +check_cmd_access(const char *command, const char *opt) +{ + struct argv argv; + bool return_code; + + /* If no command was set, there are no errors to look for */ + if (! command) + return false; + + /* Extract executable path and arguments */ + argv = argv_new (); + argv_printf (&argv, "%sc", command); + + /* if an executable is specified then check it; otherwise, complain */ + if (argv.argv[0]) + /* Scripts requires R_OK as well, but that might fail on binaries which + * only requires X_OK to function on Unix - a scenario not unlikely to + * be seen on suid binaries. + */ + return_code = check_file_access(CHKACC_FILE, argv.argv[0], X_OK, opt); + else + { + msg (M_NOPREFIX|M_OPTERR, "%s fails with '%s': No path to executable.", + opt, command); + return_code = true; + } + + argv_reset (&argv); + + return return_code; +} + +/* + * Sanity check of all file/dir options. Checks that file/dir + * is accessible by OpenVPN + */ +static void +options_postprocess_filechecks (struct options *options) +{ + bool errs = false; + + /* ** 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 (CHKACC_FILE, options->ca_path, R_OK, "--capath"); + errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->cert_file, R_OK, "--cert"); + errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->extra_certs_file, R_OK, + "--extra-certs"); +#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"); + + if (options->ssl_flags & SSLF_CRL_VERIFY_DIR) + errs |= check_file_access (CHKACC_FILE, options->crl_file, R_OK|X_OK, + "--crl-verify directory"); + else + errs |= check_file_access (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 (CHKACC_DIRPATH|CHKACC_FILEXSTWR, + options->packet_id_file, R_OK|W_OK, "--replay-persist"); +#endif /* ENABLE_CRYPTO */ + + + /* ** Password files ** */ +#ifdef ENABLE_SSL + errs |= check_file_access (CHKACC_FILE, options->key_pass_file, R_OK, + "--askpass"); +#endif /* ENABLE_SSL */ +#ifdef ENABLE_MANAGEMENT + errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN, + options->management_user_pass, R_OK, + "--management user/password file"); +#endif /* ENABLE_MANAGEMENT */ +#if P2MP + errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN, + options->auth_user_pass_file, R_OK, + "--auth-user-pass"); +#endif /* P2MP */ + + /* ** System related ** */ + errs |= check_file_access (CHKACC_FILE, options->chroot_dir, + R_OK|X_OK, "--chroot directory"); + errs |= check_file_access (CHKACC_DIRPATH|CHKACC_FILEXSTWR, options->writepid, + R_OK|W_OK, "--writepid"); + + /* ** Log related ** */ + errs |= check_file_access (CHKACC_DIRPATH|CHKACC_FILEXSTWR, options->status_file, + R_OK|W_OK, "--status"); + + /* ** Config related ** */ +#ifdef ENABLE_SSL + errs |= check_file_access (CHKACC_FILE, options->tls_export_cert, + R_OK|W_OK|X_OK, "--tls-export-cert"); +#endif /* ENABLE_SSL */ +#if P2MP_SERVER + errs |= check_file_access (CHKACC_FILE, options->client_config_dir, + R_OK|X_OK, "--client-config-dir"); + errs |= check_file_access (CHKACC_FILE, options->tmp_dir, + R_OK|W_OK|X_OK, "Temporary directory (--tmp-dir)"); + + /* ** Script hooks that accept an optionally quoted and/or escaped executable path, ** */ + /* ** optionally followed by arguments ** */ + errs |= check_cmd_access (options->auth_user_pass_verify_script, + "--auth-user-pass-verify script"); + errs |= check_cmd_access (options->client_connect_script, + "--client-connect script"); + errs |= check_cmd_access (options->client_disconnect_script, + "--client-disconnect script"); + errs |= check_cmd_access (options->tls_verify, + "--tls-verify script"); + errs |= check_cmd_access (options->up_script, + "--up script"); + errs |= check_cmd_access (options->down_script, + "--down script"); + errs |= check_cmd_access (options->ipchange, + "--ipchange script"); + errs |= check_cmd_access (options->route_script, + "--route-up script"); + errs |= check_cmd_access (options->route_predown_script, + "--route-pre-down script"); + errs |= check_cmd_access (options->learn_address_script, + "--learn-address script"); +#endif /* P2MP_SERVER */ + + if (errs) + msg (M_USAGE, "Please correct these errors."); +} +#endif /* !ENABLE_SMALL */ + +/* * Sanity check on options. * Also set some options based on other * options. @@ -2330,6 +2767,9 @@ options_postprocess (struct options *options) { options_postprocess_mutate (options); options_postprocess_verify (options); +#ifndef ENABLE_SMALL + options_postprocess_filechecks (options); +#endif /* !ENABLE_SMALL */ } #if P2MP @@ -2352,6 +2792,18 @@ pre_pull_save (struct options *o) o->pre_pull->routes = clone_route_option_list(o->routes, &o->gc); o->pre_pull->routes_defined = true; } + if (o->routes_ipv6) + { + 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 } } @@ -2373,6 +2825,24 @@ pre_pull_restore (struct options *o) else o->routes = NULL; + if (pp->routes_ipv6_defined) + { + rol6_check_alloc (o); + copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6); + } + else + o->routes_ipv6 = NULL; + +#ifdef ENABLE_CLIENT_NAT + if (pp->client_nat_defined) + { + cnol_check_alloc (o); + copy_client_nat_option_list (o->client_nat, pp->client_nat); + } + else + o->client_nat = NULL; +#endif + o->foreign_option_index = pp->foreign_option_index; } @@ -2461,6 +2931,9 @@ options_string (const struct options *o, o->topology, o->ifconfig_local, o->ifconfig_remote_netmask, + o->ifconfig_ipv6_local, + o->ifconfig_ipv6_netbits, + o->ifconfig_ipv6_remote, (in_addr_t)0, (in_addr_t)0, false, @@ -2481,19 +2954,19 @@ options_string (const struct options *o, tt = NULL; } -#ifdef USE_LZO +#ifdef ENABLE_LZO if (o->lzo & LZO_SELECTED) buf_printf (&out, ",comp-lzo"); #endif #ifdef ENABLE_FRAGMENT - if (o->fragment) + if (o->ce.fragment) buf_printf (&out, ",mtu-dynamic"); #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO -#ifdef USE_SSL +#ifdef ENABLE_SSL #define TLS_CLIENT (o->tls_client) #define TLS_SERVER (o->tls_server) #else @@ -2526,18 +2999,23 @@ options_string (const struct options *o, o->authname, o->authname_defined, o->keysize, true, false); - buf_printf (&out, ",cipher %s", kt_cipher_name (&kt)); - buf_printf (&out, ",auth %s", kt_digest_name (&kt)); - buf_printf (&out, ",keysize %d", kt_key_size (&kt)); + buf_printf (&out, ",cipher %s", 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) buf_printf (&out, ",secret"); if (!o->replay) buf_printf (&out, ",no-replay"); if (!o->use_iv) buf_printf (&out, ",no-iv"); + +#ifdef ENABLE_PREDICTION_RESISTANCE + if (o->use_prediction_resistance) + buf_printf (&out, ",use-prediction-resistance"); +#endif } -#ifdef USE_SSL +#ifdef ENABLE_SSL /* * SSL Options */ @@ -2566,12 +3044,12 @@ options_string (const struct options *o, buf_printf (&out, ",tls-server"); } } -#endif /* USE_SSL */ +#endif /* ENABLE_SSL */ #undef TLS_CLIENT #undef TLS_SERVER -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ return BSTR (&out); } @@ -2714,7 +3192,7 @@ options_cmp_equal_safe (char *actual, const char *expected, size_t actual_n) if (actual_n > 0) { actual[actual_n - 1] = 0; -#ifndef STRICT_OPTIONS_CHECK +#ifndef ENABLE_STRICT_OPTIONS_CHECK if (strncmp (actual, expected, 2)) { msg (D_SHOW_OCC, "NOTE: Options consistency check may be skewed by version differences"); @@ -2880,7 +3358,7 @@ usage (void) struct options o; init_options (&o, true); -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) fprintf (fp, usage_message, title_string, o.ce.connect_retry_seconds, @@ -2891,7 +3369,7 @@ usage (void) o.replay_window, o.replay_time, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window); -#elif defined(USE_CRYPTO) +#elif defined(ENABLE_CRYPTO) fprintf (fp, usage_message, title_string, o.ce.connect_retry_seconds, @@ -2929,12 +3407,15 @@ usage_version (void) msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan"); msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>"); #ifndef ENABLE_SMALL -#ifdef CONFIGURE_CALL - msg (M_INFO|M_NOPREFIX, "\n%s\n", CONFIGURE_CALL); -#endif #ifdef CONFIGURE_DEFINES msg (M_INFO|M_NOPREFIX, "Compile time defines: %s", CONFIGURE_DEFINES); #endif +#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 */ } @@ -3145,8 +3626,6 @@ bypass_doubledash (char **p) *p += 2; } -#if ENABLE_INLINE_FILES - struct in_src { # define IS_TYPE_FP 1 # define IS_TYPE_BUF 2 @@ -3239,8 +3718,6 @@ check_inline_file_via_buf (struct buffer *multiline, char *p[], struct gc_arena return check_inline_file (&is, p, gc); } -#endif - static void add_option (struct options *options, char *p[], @@ -3275,7 +3752,7 @@ read_config_file (struct options *options, if (streq (file, "stdin")) fp = stdin; else - fp = fopen (file, "r"); + fp = platform_fopen (file, "r"); if (fp) { line_num = 0; @@ -3286,9 +3763,7 @@ read_config_file (struct options *options, if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc)) { bypass_doubledash (&p[0]); -#if ENABLE_INLINE_FILES check_inline_file_via_fp (fp, p, &options->gc); -#endif add_option (options, p, file, line_num, level, msglevel, permission_mask, option_types_found, es); } } @@ -3331,9 +3806,7 @@ read_config_string (const char *prefix, if (parse_line (line, p, SIZE (p), prefix, line_num, msglevel, &options->gc)) { bypass_doubledash (&p[0]); -#if ENABLE_INLINE_FILES check_inline_file_via_buf (&multiline, p, &options->gc); -#endif add_option (options, p, NULL, line_num, 0, msglevel, permission_mask, option_types_found, es); } CLEAR (p); @@ -3454,10 +3927,11 @@ void options_string_import (struct options *options, #if P2MP -#define VERIFY_PERMISSION(mask) { if (!verify_permission(p[0], (mask), permission_mask, option_types_found, msglevel)) goto err; } +#define VERIFY_PERMISSION(mask) { if (!verify_permission(p[0], file, (mask), permission_mask, option_types_found, msglevel)) goto err; } static bool verify_permission (const char *name, + const char* file, const unsigned int type, const unsigned int allowed, unsigned int *found, @@ -3465,7 +3939,7 @@ verify_permission (const char *name, { if (!(type & allowed)) { - msg (msglevel, "option '%s' cannot be used in this context", name); + msg (msglevel, "option '%s' cannot be used in this context (%s)", name, file); return false; } else @@ -3569,6 +4043,16 @@ add_option (struct options *options, read_config_file (options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es); } +#ifdef ENABLE_DEBUG + else if (streq (p[0], "show-gateway")) + { + struct route_gateway_info rgi; + VERIFY_PERMISSION (OPT_P_GENERAL); + get_default_gateway(&rgi); + print_default_gateway(M_INFO, &rgi); + openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ + } +#endif #if 0 else if (streq (p[0], "foreign-option") && p[1]) { @@ -3594,9 +4078,13 @@ add_option (struct options *options, } if (good) { +#if 0 + /* removed for now since ECHO can potentially include + security-sensitive strings */ msg (M_INFO, "%s:%s", pull_mode ? "ECHO-PULL" : "ECHO", BSTR (&string)); +#endif #ifdef ENABLE_MANAGEMENT if (management) management_echo (management, BSTR (&string), pull_mode); @@ -3652,6 +4140,17 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->management_flags |= MF_QUERY_PASSWORDS; } + else if (streq (p[0], "management-query-remote")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->management_flags |= MF_QUERY_REMOTE; + } + else if (streq (p[0], "management-query-proxy")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->management_flags |= MF_QUERY_PROXY; + options->force_connection_list = true; + } else if (streq (p[0], "management-hold")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -3667,12 +4166,24 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->management_flags |= MF_FORGET_DISCONNECT; } + else if (streq (p[0], "management-up-down")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->management_flags |= MF_UP_DOWN; + } else if (streq (p[0], "management-client")) { 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")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->management_flags |= MF_EXTERNAL_KEY; + } +#endif #ifdef MANAGEMENT_DEF_AUTH else if (streq (p[0], "management-client-auth")) { @@ -3680,6 +4191,13 @@ add_option (struct options *options, options->management_flags |= MF_CLIENT_AUTH; } #endif +#ifdef ENABLE_X509_TRACK + else if (streq (p[0], "x509-track") && p[1]) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + x509_track_add (&options->x509_track, p[1], msglevel, &options->gc); + } +#endif #ifdef MANAGEMENT_PF else if (streq (p[0], "management-client-pf")) { @@ -3765,7 +4283,7 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_UP); options->tun_ipv6 = true; } -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE else if (streq (p[0], "iproute") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -3786,6 +4304,35 @@ add_option (struct options *options, goto err; } } + else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] ) + { + unsigned int netbits; + char * ipv6_local; + + VERIFY_PERMISSION (OPT_P_UP); + if ( get_ipv6_addr( p[1], NULL, &netbits, &ipv6_local, msglevel ) && + ipv6_addr_safe( p[2] ) ) + { + if ( netbits < 64 || netbits > 124 ) + { + msg( msglevel, "ifconfig-ipv6: /netbits must be between 64 and 124, not '/%d'", netbits ); + goto err; + } + + if (options->ifconfig_ipv6_local) + /* explicitly ignoring this is a const char */ + free ((char *) options->ifconfig_ipv6_local); + + options->ifconfig_ipv6_local = ipv6_local; + options->ifconfig_ipv6_netbits = netbits; + options->ifconfig_ipv6_remote = p[2]; + } + else + { + msg (msglevel, "ifconfig-ipv6 parms '%s' and '%s' must be valid addresses", p[1], p[2]); + goto err; + } + } else if (streq (p[0], "ifconfig-noexec")) { VERIFY_PERMISSION (OPT_P_UP); @@ -3806,7 +4353,6 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->remote_random = true; } -#if ENABLE_CONNECTION else if (streq (p[0], "connection") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -3832,21 +4378,12 @@ add_option (struct options *options, uninit_options (&sub); } } -#endif -#ifdef ENABLE_CONNECTION else if (streq (p[0], "remote-ip-hint") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->remote_ip_hint = p[1]; } -#endif -#if HTTP_PROXY_FALLBACK - else if (streq (p[0], "http-proxy-fallback")) - { - VERIFY_PERMISSION (OPT_P_GENERAL); - options->http_proxy_fallback = true; - options->force_connection_list = true; - } +#if HTTP_PROXY_OVERRIDE else if (streq (p[0], "http-proxy-override") && p[1] && p[2]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -3884,7 +4421,6 @@ add_option (struct options *options, re.proto = proto; } } -#ifdef ENABLE_CONNECTION if (permission_mask & OPT_P_GENERAL) { struct remote_entry *e = alloc_remote_entry (options, msglevel); @@ -3893,7 +4429,6 @@ add_option (struct options *options, *e = re; } else if (permission_mask & OPT_P_CONNECTION) -#endif { connection_entry_load_re (&options->ce, &re); } @@ -3951,14 +4486,14 @@ add_option (struct options *options, else if (streq (p[0], "cd") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); - if (openvpn_chdir (p[1])) + if (platform_chdir (p[1])) { msg (M_ERR, "cd to '%s' failed", p[1]); goto err; } options->cd_dir = p[1]; } -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX else if (streq (p[0], "setcon") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -4097,6 +4632,13 @@ add_option (struct options *options, options->log = true; redirect_stdout_stderr (p[1], true); } +#ifdef ENABLE_MEMSTATS + else if (streq (p[0], "memstats") && p[1]) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->memstats_fn = p[1]; + } +#endif else if (streq (p[0], "mlock")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -4161,39 +4703,40 @@ add_option (struct options *options, } else if ((streq (p[0], "link-mtu") || streq (p[0], "udp-mtu")) && p[1]) { - VERIFY_PERMISSION (OPT_P_MTU); - options->link_mtu = positive_atoi (p[1]); - options->link_mtu_defined = true; + 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]) { - VERIFY_PERMISSION (OPT_P_MTU); - options->tun_mtu = positive_atoi (p[1]); - options->tun_mtu_defined = true; + 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]) { - VERIFY_PERMISSION (OPT_P_MTU); - options->tun_mtu_extra = positive_atoi (p[1]); - options->tun_mtu_extra_defined = true; + VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION); + options->ce.tun_mtu_extra = positive_atoi (p[1]); + options->ce.tun_mtu_extra_defined = true; } #ifdef ENABLE_FRAGMENT else if (streq (p[0], "mtu-dynamic")) { - VERIFY_PERMISSION (OPT_P_GENERAL); + VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION); msg (msglevel, "--mtu-dynamic has been replaced by --fragment"); goto err; } else if (streq (p[0], "fragment") && p[1]) { - VERIFY_PERMISSION (OPT_P_MTU); - options->fragment = positive_atoi (p[1]); +/* 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]) { - VERIFY_PERMISSION (OPT_P_MTU); - options->mtu_discover_type = translate_mtu_discover_type_name (p[1]); + 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")) @@ -4217,6 +4760,13 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_SOCKBUF); options->sndbuf = positive_atoi (p[1]); } + else if (streq (p[0], "mark") && p[1]) + { +#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK + VERIFY_PERMISSION (OPT_P_GENERAL); + options->mark = atoi(p[1]); +#endif + } else if (streq (p[0], "socket-flags")) { int j; @@ -4241,7 +4791,7 @@ add_option (struct options *options, } else if (streq (p[0], "shaper") && p[1]) { -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER int shaper; VERIFY_PERMISSION (OPT_P_SHAPER); @@ -4253,11 +4803,11 @@ add_option (struct options *options, goto err; } options->shaper = shaper; -#else /* HAVE_GETTIMEOFDAY */ +#else /* ENABLE_FEATURE_SHAPER */ VERIFY_PERMISSION (OPT_P_GENERAL); msg (msglevel, "--shaper requires the gettimeofday() function which is missing"); goto err; -#endif /* HAVE_GETTIMEOFDAY */ +#endif /* ENABLE_FEATURE_SHAPER */ } else if (streq (p[0], "port") && p[1]) { @@ -4270,7 +4820,6 @@ add_option (struct options *options, msg (msglevel, "Bad port number: %s", p[1]); goto err; } - options->ce.port_option_used = true; options->ce.local_port = options->ce.remote_port = port; } else if (streq (p[0], "lport") && p[1]) @@ -4285,7 +4834,6 @@ add_option (struct options *options, goto err; } options->ce.local_port_defined = true; - options->ce.port_option_used = true; options->ce.local_port = port; } else if (streq (p[0], "rport") && p[1]) @@ -4299,7 +4847,6 @@ add_option (struct options *options, msg (msglevel, "Bad remote port number: %s", p[1]); goto err; } - options->ce.port_option_used = true; options->ce.remote_port = port; } else if (streq (p[0], "bind")) @@ -4351,38 +4898,6 @@ add_option (struct options *options, options->proto_force = proto_force; options->force_connection_list = true; } -#ifdef GENERAL_PROXY_SUPPORT - else if (streq (p[0], "auto-proxy")) - { - char *error = NULL; - - VERIFY_PERMISSION (OPT_P_GENERAL); - options->auto_proxy_info = get_proxy_settings (&error, &options->gc); - if (error) - msg (M_WARN, "PROXY: %s", error); - } - else if (streq (p[0], "show-proxy-settings")) - { - struct auto_proxy_info *pi; - char *error = NULL; - - VERIFY_PERMISSION (OPT_P_GENERAL); - pi = get_proxy_settings (&error, &options->gc); - if (pi) - { - msg (M_INFO|M_NOPREFIX, "HTTP Server: %s", np(pi->http.server)); - msg (M_INFO|M_NOPREFIX, "HTTP Port: %d", pi->http.port); - msg (M_INFO|M_NOPREFIX, "SOCKS Server: %s", np(pi->socks.server)); - msg (M_INFO|M_NOPREFIX, "SOCKS Port: %d", pi->socks.port); - } - if (error) - msg (msglevel, "Proxy error: %s", error); -#ifdef WIN32 - show_win_proxy_settings (M_INFO|M_NOPREFIX); -#endif - openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ - } -#endif /* GENERAL_PROXY_SUPPORT */ #ifdef ENABLE_HTTP_PROXY else if (streq (p[0], "http-proxy") && p[1]) { @@ -4404,7 +4919,7 @@ add_option (struct options *options, goto err; } - ho = init_http_options_if_undefined (options); + ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc); ho->server = p[1]; ho->port = port; @@ -4439,7 +4954,7 @@ add_option (struct options *options, { struct http_proxy_options *ho; VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); - ho = init_http_options_if_undefined (options); + ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc); ho->retry = true; } else if (streq (p[0], "http-proxy-timeout") && p[1]) @@ -4447,7 +4962,7 @@ add_option (struct options *options, struct http_proxy_options *ho; VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); - ho = init_http_options_if_undefined (options); + ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc); ho->timeout = positive_atoi (p[1]); } else if (streq (p[0], "http-proxy-option") && p[1]) @@ -4455,7 +4970,7 @@ add_option (struct options *options, struct http_proxy_options *ho; VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); - ho = init_http_options_if_undefined (options); + ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc); if (streq (p[1], "VERSION") && p[2]) { @@ -4531,14 +5046,15 @@ add_option (struct options *options, #ifdef ENABLE_OCC else if (streq (p[0], "explicit-exit-notify")) { - VERIFY_PERMISSION (OPT_P_EXPLICIT_NOTIFY); + VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); +/* VERIFY_PERMISSION (OPT_P_EXPLICIT_NOTIFY); */ if (p[1]) { - options->explicit_exit_notification = positive_atoi (p[1]); + options->ce.explicit_exit_notification = positive_atoi (p[1]); } else { - options->explicit_exit_notification = 1; + options->ce.explicit_exit_notification = 1; } } #endif @@ -4562,6 +5078,14 @@ add_option (struct options *options, 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]) + { + 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]) { VERIFY_PERMISSION (OPT_P_ROUTE); @@ -4586,6 +5110,26 @@ 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]) + { + VERIFY_PERMISSION (OPT_P_ROUTE); + rol6_check_alloc (options); + if (pull_mode) + { + if (!ipv6_addr_safe_hexplusbits (p[1])) + { + msg (msglevel, "route-ipv6 parameter network/IP '%s' must be a valid address", p[1]); + goto err; + } + if (p[2] && !ipv6_addr_safe (p[2])) + { + msg (msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); + goto err; + } + /* p[3] is metric, if present */ + } + add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]); + } else if (streq (p[0], "max-routes") && p[1]) { int max_routes; @@ -4649,6 +5193,14 @@ add_option (struct options *options, warn_multiple_script (options->route_script, "route-up"); options->route_script = p[1]; } + else if (streq (p[0], "route-pre-down") && p[1]) + { + VERIFY_PERMISSION (OPT_P_SCRIPT); + if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT)) + goto err; + warn_multiple_script (options->route_predown_script, "route-pre-down"); + options->route_predown_script = p[1]; + } else if (streq (p[0], "route-noexec")) { VERIFY_PERMISSION (OPT_P_SCRIPT); @@ -4683,6 +5235,8 @@ add_option (struct options *options, options->routes->flags |= RG_BYPASS_DHCP; else if (streq (p[j], "bypass-dns")) options->routes->flags |= RG_BYPASS_DNS; + else if (streq (p[j], "block-local")) + options->routes->flags |= RG_BLOCK_LOCAL; else { msg (msglevel, "unknown --%s flag: %s", p[0], p[j]); @@ -4708,6 +5262,12 @@ add_option (struct options *options, msg (msglevel, "this is a generic configuration and cannot directly be used"); goto err; } +#ifdef ENABLE_PUSH_PEER_INFO + else if (streq (p[1], "PUSH_PEER_INFO")) + { + options->push_peer_info = true; + } +#endif #if P2MP else if (streq (p[1], "SERVER_POLL_TIMEOUT") && p[2]) { @@ -4733,30 +5293,16 @@ add_option (struct options *options, { VERIFY_PERMISSION (OPT_P_GENERAL); script_security = atoi (p[1]); - if (p[2]) - { - if (streq (p[2], "execve")) - script_method = SM_EXECVE; - else if (streq (p[2], "system")) - script_method = SM_SYSTEM; - else - { - msg (msglevel, "unknown --script-security method: %s", p[2]); - goto err; - } - } - else - script_method = SM_EXECVE; } else if (streq (p[0], "mssfix")) { - VERIFY_PERMISSION (OPT_P_GENERAL); + VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); if (p[1]) { - options->mssfix = positive_atoi (p[1]); + options->ce.mssfix = positive_atoi (p[1]); } else - options->mssfix_default = true; + options->ce.mssfix_default = true; } #ifdef ENABLE_OCC @@ -4797,6 +5343,33 @@ add_option (struct options *options, } } } + else if (streq (p[0], "server-ipv6") && p[1] ) + { + const int lev = M_WARN; + struct in6_addr network; + unsigned int netbits = 0; + + VERIFY_PERMISSION (OPT_P_GENERAL); + if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev) ) + { + msg (msglevel, "error parsing --server-ipv6 parameter"); + goto err; + } + if ( netbits < 64 || netbits > 112 ) + { + msg( msglevel, "--server-ipv6 settings: only /64../112 supported right now (not /%d)", netbits ); + goto err; + } + options->server_ipv6_defined = true; + options->server_network_ipv6 = network; + options->server_netbits_ipv6 = netbits; + + if (p[2]) /* no "nopool" options or similar for IPv6 */ + { + msg (msglevel, "error parsing --server-ipv6: %s is not a recognized flag", p[3]); + goto err; + } + } else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4]) { const int lev = M_WARN; @@ -4881,6 +5454,28 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->topology = TOP_P2P; } + else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] ) + { + const int lev = M_WARN; + struct in6_addr network; + unsigned int netbits = 0; + + VERIFY_PERMISSION (OPT_P_GENERAL); + if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev ) ) + { + msg (msglevel, "error parsing --ifconfig-ipv6-pool parameters"); + goto err; + } + if ( netbits != 64 ) + { + msg( msglevel, "--ifconfig-ipv6-pool settings: only /64 supported right now (not /%d)", netbits ); + goto err; + } + + options->ifconfig_ipv6_pool_defined = true; + options->ifconfig_ipv6_pool_base = network; + options->ifconfig_ipv6_pool_netbits = netbits; + } else if (streq (p[0], "hash-size") && p[1] && p[2]) { int real, virtual; @@ -4944,10 +5539,12 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->ssl_flags |= SSLF_AUTH_USER_PASS_OPTIONAL; } - else if (streq (p[0], "no-name-remapping")) + else if (streq (p[0], "compat-names")) { VERIFY_PERMISSION (OPT_P_GENERAL); - options->ssl_flags |= SSLF_NO_NAME_REMAPPING; + compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES); + if (p[1] && streq (p[1], "no-remapping")) + compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING); } else if (streq (p[0], "opt-verify")) { @@ -5053,6 +5650,7 @@ add_option (struct options *options, options->port_share_host = p[1]; options->port_share_port = port; + options->port_share_journal_dir = p[3]; } #endif else if (streq (p[0], "client-to-client")) @@ -5076,6 +5674,11 @@ add_option (struct options *options, } option_iroute (options, p[1], netmask, msglevel); } + else if (streq (p[0], "iroute-ipv6") && p[1]) + { + VERIFY_PERMISSION (OPT_P_INSTANCE); + option_iroute_ipv6 (options, p[1], msglevel); + } else if (streq (p[0], "ifconfig-push") && p[1] && p[2]) { in_addr_t local, remote_netmask; @@ -5088,6 +5691,10 @@ 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 { @@ -5114,6 +5721,43 @@ add_option (struct options *options, goto err; } } + else if (streq (p[0], "ifconfig-ipv6-push") && p[1] ) + { + struct in6_addr local, remote; + unsigned int netbits; + + VERIFY_PERMISSION (OPT_P_INSTANCE); + + if ( ! get_ipv6_addr( p[1], &local, &netbits, NULL, msglevel ) ) + { + msg (msglevel, "cannot parse --ifconfig-ipv6-push addresses"); + goto err; + } + + if ( p[2] ) + { + if ( !get_ipv6_addr( p[2], &remote, NULL, NULL, msglevel ) ) + { + msg( msglevel, "cannot parse --ifconfig-ipv6-push addresses"); + goto err; + } + } + else + { + if ( ! options->ifconfig_ipv6_local || + ! get_ipv6_addr( options->ifconfig_ipv6_local, &remote, + NULL, NULL, msglevel ) ) + { + msg( msglevel, "second argument to --ifconfig-ipv6-push missing and no global --ifconfig-ipv6 address set"); + goto err; + } + } + + options->push_ifconfig_ipv6_defined = true; + options->push_ifconfig_ipv6_local = local; + options->push_ifconfig_ipv6_netbits = netbits; + options->push_ifconfig_ipv6_remote = remote; + } else if (streq (p[0], "disable")) { VERIFY_PERMISSION (OPT_P_INSTANCE); @@ -5124,6 +5768,25 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->server_flags |= SF_TCP_NODELAY_HELPER; } + else if (streq (p[0], "stale-routes-check") && p[1]) + { + int ageing_time, check_interval; + + VERIFY_PERMISSION (OPT_P_GENERAL); + ageing_time = atoi (p[1]); + if (p[2]) + check_interval = atoi (p[2]); + else + check_interval = ageing_time; + + if (ageing_time < 1 || check_interval < 1) + { + msg (msglevel, "--stale-routes-check aging time and check interval must be >= 1"); + goto err; + } + options->stale_routes_ageing_time = ageing_time; + options->stale_routes_check_interval = check_interval; + } #endif /* P2MP_SERVER */ else if (streq (p[0], "client")) @@ -5161,13 +5824,24 @@ add_option (struct options *options, 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]) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->sc_info.challenge_text = p[1]; + if (atoi(p[2])) + options->sc_info.flags |= SC_ECHO; + } +#endif #endif #ifdef WIN32 else if (streq (p[0], "win-sys") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); if (streq (p[1], "env")) - set_win_sys_path_via_env (es); + msg (M_INFO, "NOTE: --win-sys env is default from OpenVPN v2.3. " + "This entry will now be ignored. " + "Please remove this entry from your configuration file."); else set_win_sys_path (p[1], es); } @@ -5294,7 +5968,7 @@ add_option (struct options *options, else if (streq (p[0], "show-adapters")) { VERIFY_PERMISSION (OPT_P_GENERAL); - show_tap_win32_adapters (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX); + 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")) @@ -5432,7 +6106,7 @@ add_option (struct options *options, options->passtos = true; } #endif -#ifdef USE_LZO +#ifdef ENABLE_LZO else if (streq (p[0], "comp-lzo")) { VERIFY_PERMISSION (OPT_P_COMP); @@ -5458,8 +6132,8 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_COMP); options->lzo &= ~LZO_ADAPTIVE; } -#endif /* USE_LZO */ -#ifdef USE_CRYPTO +#endif /* ENABLE_LZO */ +#ifdef ENABLE_CRYPTO else if (streq (p[0], "show-ciphers")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5488,13 +6162,11 @@ add_option (struct options *options, else if (streq (p[0], "secret") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->shared_secret_file_inline = p[2]; } else -#endif if (p[2]) { int key_direction; @@ -5631,6 +6303,7 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->test_crypto = true; } +#ifndef ENABLE_CRYPTO_POLARSSL else if (streq (p[0], "engine")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5641,6 +6314,7 @@ add_option (struct options *options, else options->engine = "auto"; } +#endif /* ENABLE_CRYPTO_POLARSSL */ #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH else if (streq (p[0], "keysize") && p[1]) { @@ -5656,7 +6330,14 @@ add_option (struct options *options, options->keysize = keysize; } #endif -#ifdef USE_SSL +#ifdef ENABLE_PREDICTION_RESISTANCE + else if (streq (p[0], "use-prediction-resistance")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->use_prediction_resistance = true; + } +#endif +#ifdef ENABLE_SSL else if (streq (p[0], "show-tls")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5676,41 +6357,51 @@ add_option (struct options *options, { VERIFY_PERMISSION (OPT_P_GENERAL); options->ca_file = p[1]; -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->ca_file_inline = p[2]; } -#endif } +#ifndef ENABLE_CRYPTO_POLARSSL else if (streq (p[0], "capath") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->ca_path = p[1]; } +#endif /* ENABLE_CRYPTO_POLARSSL */ else if (streq (p[0], "dh") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->dh_file = p[1]; -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->dh_file_inline = p[2]; } -#endif } else if (streq (p[0], "cert") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->cert_file = p[1]; -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->cert_file_inline = p[2]; } -#endif } -#ifdef WIN32 + else if (streq (p[0], "extra-certs") && p[1]) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->extra_certs_file = p[1]; + if (streq (p[1], INLINE_FILE_TAG) && p[2]) + { + options->extra_certs_file_inline = p[2]; + } + } + else if (streq (p[0], "verify-hash") && p[1]) + { + 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]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5721,24 +6412,22 @@ add_option (struct options *options, { VERIFY_PERMISSION (OPT_P_GENERAL); options->priv_key_file = p[1]; -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->priv_key_file_inline = p[2]; } -#endif } +#ifndef ENABLE_CRYPTO_POLARSSL else if (streq (p[0], "pkcs12") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->pkcs12_file = p[1]; -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->pkcs12_file_inline = p[2]; } -#endif } +#endif /* ENABLE_CRYPTO_POLARSSL */ else if (streq (p[0], "askpass")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5754,6 +6443,15 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); ssl_set_auth_nocache (); } + else if (streq (p[0], "auth-token") && p[1]) + { + VERIFY_PERMISSION (OPT_P_ECHO); + ssl_set_auth_token(p[1]); +#ifdef ENABLE_MANAGEMENT + if (management) + management_auth_token (management, p[1]); +#endif + } else if (streq (p[0], "single-session")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5779,6 +6477,8 @@ add_option (struct options *options, else if (streq (p[0], "crl-verify") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); + if (p[2] && streq(p[2], "dir")) + options->ssl_flags |= SSLF_CRL_VERIFY_DIR; options->crl_file = p[1]; } else if (streq (p[0], "tls-verify") && p[1]) @@ -5789,11 +6489,13 @@ add_option (struct options *options, warn_multiple_script (options->tls_verify, "tls-verify"); options->tls_verify = string_substitute (p[1], ',', ' ', &options->gc); } +#ifndef ENABLE_CRYPTO_POLARSSL else if (streq (p[0], "tls-export-cert") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); options->tls_export_cert = p[1]; } +#endif else if (streq (p[0], "tls-remote") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -5803,16 +6505,16 @@ add_option (struct options *options, { VERIFY_PERMISSION (OPT_P_GENERAL); if (streq (p[1], "server")) - options->ns_cert_type = NS_SSL_SERVER; + options->ns_cert_type = NS_CERT_CHECK_SERVER; else if (streq (p[1], "client")) - options->ns_cert_type = NS_SSL_CLIENT; + options->ns_cert_type = NS_CERT_CHECK_CLIENT; else { msg (msglevel, "--ns-cert-type must be 'client' or 'server'"); goto err; } } -#if OPENSSL_VERSION_NUMBER >= 0x00907000L +#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL else if (streq (p[0], "remote-cert-ku")) { int j; @@ -5884,13 +6586,11 @@ add_option (struct options *options, else if (streq (p[0], "tls-auth") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); -#if ENABLE_INLINE_FILES if (streq (p[1], INLINE_FILE_TAG) && p[2]) { options->tls_auth_file_inline = p[2]; } else -#endif if (p[2]) { int key_direction; @@ -5924,12 +6624,13 @@ add_option (struct options *options, { char *s = p[1]; VERIFY_PERMISSION (OPT_P_GENERAL); - while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */ + if( strncmp ("ext:",s,4) != 0 ) + while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */ options->x509_username_field = p[1]; } #endif /* ENABLE_X509ALTUSERNAME */ -#endif /* USE_SSL */ -#endif /* USE_CRYPTO */ +#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ #ifdef ENABLE_PKCS11 else if (streq (p[0], "show-pkcs11-ids") && p[1]) { @@ -5994,7 +6695,7 @@ add_option (struct options *options, options->pkcs11_id_management = true; } #endif -#ifdef TUNSETPERSIST +#ifdef ENABLE_FEATURE_TUN_PERSIST else if (streq (p[0], "rmtun")) { VERIFY_PERMISSION (OPT_P_GENERAL); diff --git a/options.h b/src/openvpn/options.h index dd49355..306520b 100644 --- a/options.h +++ b/src/openvpn/options.h @@ -41,6 +41,7 @@ #include "proxy.h" #include "lzo.h" #include "pushlist.h" +#include "clinat.h" /* * Maximum number of parameters associated with an option, @@ -67,10 +68,21 @@ struct options_pre_pull bool routes_defined; struct route_option_list *routes; + 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." +#endif struct connection_entry { @@ -78,7 +90,6 @@ struct connection_entry int local_port; bool local_port_defined; int remote_port; - bool port_option_used; const char *local; const char *remote; bool remote_float; @@ -99,12 +110,33 @@ struct connection_entry bool socks_proxy_retry; #endif -# define CE_DISABLED (1<<0) -#if HTTP_PROXY_FALLBACK -# define CE_HTTP_PROXY_FALLBACK (1<<1) - time_t ce_http_proxy_fallback_timestamp; /* time when fallback http_proxy_options was last updated */ + int tun_mtu; /* MTU of tun device */ + bool tun_mtu_defined; /* true if user overriding parm with command line option */ + int tun_mtu_extra; + bool tun_mtu_extra_defined; + int link_mtu; /* MTU of device over which tunnel packets pass via TCP/UDP */ + bool link_mtu_defined; /* true if user overriding parm with command line option */ + + /* Advanced MTU negotiation and datagram fragmentation options */ + int mtu_discover_type; /* used if OS supports setting Path MTU discovery options on socket */ + + int fragment; /* internal fragmentation size */ + 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 +# define CE_DISABLED (1<<0) +# define CE_MAN_QUERY_PROXY (1<<1) +# define CE_MAN_QUERY_REMOTE_UNDEF 0 +# define CE_MAN_QUERY_REMOTE_QUERY 1 +# define CE_MAN_QUERY_REMOTE_ACCEPT 2 +# define CE_MAN_QUERY_REMOTE_MOD 3 +# define CE_MAN_QUERY_REMOTE_SKIP 4 +# define CE_MAN_QUERY_REMOTE_MASK (0x07) +# define CE_MAN_QUERY_REMOTE_SHIFT (2) unsigned int flags; }; @@ -115,8 +147,6 @@ struct remote_entry int proto; }; -#ifdef ENABLE_CONNECTION - #define CONNECTION_LIST_SIZE 64 struct connection_list @@ -134,15 +164,11 @@ struct remote_list struct remote_entry *array[CONNECTION_LIST_SIZE]; }; -#endif - -#if HTTP_PROXY_FALLBACK -struct hpo_store +struct remote_host_store { - struct http_proxy_options hpo; - char server[80]; +# define RH_HOST_LEN 80 + char host[RH_HOST_LEN]; }; -#endif /* Command line options */ struct options @@ -165,12 +191,12 @@ struct options bool persist_config; int persist_mode; -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO const char *key_pass_file; bool show_ciphers; bool show_digests; bool show_engines; -#ifdef USE_SSL +#ifdef ENABLE_SSL bool show_tls_ciphers; #endif bool genkey; @@ -178,24 +204,17 @@ struct options /* Networking parms */ struct connection_entry ce; - -#ifdef ENABLE_CONNECTION char *remote_ip_hint; struct connection_list *connection_list; struct remote_list *remote_list; bool force_connection_list; -#endif - -#ifdef GENERAL_PROXY_SUPPORT - struct auto_proxy_info *auto_proxy_info; -#endif -#if HTTP_PROXY_FALLBACK - bool http_proxy_fallback; +#if HTTP_PROXY_OVERRIDE struct http_proxy_options *http_proxy_override; - struct hpo_store *hpo_store; /* used to store dynamic proxy info given by management interface */ #endif + struct remote_host_store *rh_store; + bool remote_random; const char *ipchange; const char *dev; @@ -205,28 +224,24 @@ struct options int topology; /* one of the TOP_x values from proto.h */ const char *ifconfig_local; const char *ifconfig_remote_netmask; + const char *ifconfig_ipv6_local; + int ifconfig_ipv6_netbits; + const char *ifconfig_ipv6_remote; bool ifconfig_noexec; bool ifconfig_nowarn; -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER int shaper; #endif - int tun_mtu; /* MTU of tun device */ - int tun_mtu_extra; - bool tun_mtu_extra_defined; - int link_mtu; /* MTU of device over which tunnel packets pass via TCP/UDP */ - bool tun_mtu_defined; /* true if user overriding parm with command line option */ - bool link_mtu_defined; /* true if user overriding parm with command line option */ int proto_force; - /* Advanced MTU negotiation and datagram fragmentation options */ - int mtu_discover_type; /* used if OS supports setting Path MTU discovery options on socket */ - #ifdef ENABLE_OCC bool mtu_test; #endif - int fragment; /* internal fragmentation size */ +#ifdef ENABLE_MEMSTATS + char *memstats_fn; +#endif bool mlock; @@ -246,18 +261,11 @@ struct options # define PING_RESTART 2 int ping_rec_timeout_action; /* What action to take on ping_rec_timeout (exit or restart)? */ -#ifdef ENABLE_OCC - int explicit_exit_notification; /* Explicitly tell peer when we are exiting via OCC_EXIT message */ -#endif - bool persist_tun; /* Don't close/reopen TUN/TAP dev on SIGUSR1 or PING_RESTART */ bool persist_local_ip; /* Don't re-resolve local address on SIGUSR1 or PING_RESTART */ bool persist_remote_ip; /* Don't re-resolve remote address on SIGUSR1 or PING_RESTART */ bool persist_key; /* Don't re-read key files on SIGUSR1 or PING_RESTART */ - int mssfix; /* Upper bound on TCP MSS */ - bool mssfix_default; /* true if --mssfix was supplied without a parameter */ - #if PASSTOS_CAPABILITY bool passtos; #endif @@ -271,7 +279,7 @@ struct options const char *groupname; const char *chroot_dir; const char *cd_dir; -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX char *selinux_context; #endif const char *writepid; @@ -304,7 +312,7 @@ struct options /* optimize TUN/TAP/UDP writes */ bool fast_io; -#ifdef USE_LZO +#ifdef ENABLE_LZO /* LZO_x flags from lzo.h */ unsigned int lzo; #endif @@ -313,11 +321,15 @@ struct options int rcvbuf; int sndbuf; + /* mark value */ + int mark; + /* socket flags */ unsigned int sockflags; /* route management */ const char *route_script; + const char *route_predown_script; const char *route_default_gateway; int route_default_metric; bool route_noexec; @@ -326,10 +338,15 @@ struct options 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 */ bool occ; @@ -355,14 +372,19 @@ struct options struct plugin_option_list *plugin_list; #endif - const char *tmp_dir; + #if P2MP #if P2MP_SERVER + /* the tmp dir is for now only used in the P2P server context */ + const char *tmp_dir; bool server_defined; in_addr_t server_network; in_addr_t server_netmask; + bool server_ipv6_defined; /* IPv6 */ + struct in6_addr server_network_ipv6; /* IPv6 */ + unsigned int server_netbits_ipv6; /* IPv6 */ # define SF_NOPOOL (1<<0) # define SF_TCP_NODELAY_HELPER (1<<1) @@ -384,6 +406,11 @@ struct options in_addr_t ifconfig_pool_netmask; const char *ifconfig_pool_persist_filename; int ifconfig_pool_persist_refresh_freq; + + bool ifconfig_ipv6_pool_defined; /* IPv6 */ + struct in6_addr ifconfig_ipv6_pool_base; /* IPv6 */ + int ifconfig_ipv6_pool_netbits; /* IPv6 */ + int real_hash_size; int virtual_hash_size; const char *client_connect_script; @@ -395,25 +422,35 @@ struct options int n_bcast_buf; int tcp_queue_limit; struct iroute *iroutes; + struct iroute_ipv6 *iroutes_ipv6; /* IPv6 */ 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; + bool push_ifconfig_ipv6_defined; /* IPv6 */ + struct in6_addr push_ifconfig_ipv6_local; /* IPv6 */ + int push_ifconfig_ipv6_netbits; /* IPv6 */ + struct in6_addr push_ifconfig_ipv6_remote; /* IPv6 */ bool enable_c2c; bool duplicate_cn; int cf_max; int cf_per; int max_clients; int max_routes_per_client; + int stale_routes_check_interval; + int stale_routes_ageing_time; const char *auth_user_pass_verify_script; bool auth_user_pass_verify_script_via_file; - unsigned int ssl_flags; /* set to SSLF_x flags from ssl.h */ #if PORT_SHARE char *port_share_host; int port_share_port; + const char *port_share_journal_dir; #endif #endif @@ -427,14 +464,15 @@ struct options int scheduled_exit_interval; +#ifdef ENABLE_CLIENT_CR + struct static_challenge_info sc_info; +#endif #endif -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO /* Cipher parms */ const char *shared_secret_file; -#if ENABLE_INLINE_FILES const char *shared_secret_file_inline; -#endif int key_direction; bool ciphername_defined; const char *ciphername; @@ -451,8 +489,11 @@ struct options const char *packet_id_file; bool use_iv; bool test_crypto; +#ifdef ENABLE_PREDICTION_RESISTANCE + bool use_prediction_resistance; +#endif -#ifdef USE_SSL +#ifdef ENABLE_SSL /* TLS (control channel) parms */ bool tls_server; bool tls_client; @@ -460,6 +501,7 @@ struct options const char *ca_path; const char *dh_file; const char *cert_file; + const char *extra_certs_file; const char *priv_key_file; const char *pkcs12_file; const char *cipher_list; @@ -468,17 +510,18 @@ struct options const char *tls_remote; const char *crl_file; -#if ENABLE_INLINE_FILES const char *ca_file_inline; const char *cert_file_inline; + const char *extra_certs_file_inline; char *priv_key_file_inline; const char *dh_file_inline; const char *pkcs12_file_inline; /* contains the base64 encoding of pkcs12 file */ -#endif - int ns_cert_type; /* set to 0, NS_SSL_SERVER, or NS_SSL_CLIENT */ + int ns_cert_type; /* set to 0, NS_CERT_CHECK_SERVER, or NS_CERT_CHECK_CLIENT */ unsigned remote_cert_ku[MAX_PARMS]; const char *remote_cert_eku; + uint8_t *verify_hash; + unsigned int ssl_flags; /* set to SSLF_x flags from ssl.h */ #ifdef ENABLE_PKCS11 const char *pkcs11_providers[MAX_PARMS]; @@ -490,7 +533,7 @@ struct options bool pkcs11_id_management; #endif -#ifdef WIN32 +#ifdef ENABLE_CRYPTOAPI const char *cryptoapi_cert; #endif @@ -519,9 +562,7 @@ struct options /* Special authentication MAC for TLS control channel */ const char *tls_auth_file; /* shared secret */ -#if ENABLE_INLINE_FILES const char *tls_auth_file_inline; -#endif /* Allow only one session */ bool single_session; @@ -532,8 +573,12 @@ struct options bool tls_exit; -#endif /* USE_SSL */ -#endif /* USE_CRYPTO */ +#endif /* ENABLE_SSL */ +#endif /* ENABLE_CRYPTO */ + +#ifdef ENABLE_X509_TRACK + const struct x509_track *x509_track; +#endif /* special state parms */ int foreign_option_index; @@ -603,7 +648,7 @@ struct options #define ROUTE_OPTION_FLAGS(o) (0) #endif -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER #define SHAPER_DEFINED(opt) ((opt)->shaper) #else #define SHAPER_DEFINED(opt) (false) @@ -669,9 +714,6 @@ bool apply_push_options (struct options *options, unsigned int *option_types_found, struct env_set *es); -bool is_persist_option (const struct options *o); -bool is_stateful_restart (const struct options *o); - void options_detach (struct options *o); void options_server_import (struct options *o, @@ -723,37 +765,24 @@ void options_string_import (struct options *options, unsigned int *option_types_found, struct env_set *es); +bool get_ipv6_addr( const char * prefix_str, struct in6_addr *network, + unsigned int * netbits, char ** printable_ipv6, + int msglevel ); + /* * inline functions */ static inline bool connection_list_defined (const struct options *o) { -#ifdef ENABLE_CONNECTION return o->connection_list != NULL; -#else - return false; -#endif } static inline void connection_list_set_no_advance (struct options *o) { -#ifdef ENABLE_CONNECTION if (o->connection_list) o->connection_list->no_advance = true; -#endif } -#if HTTP_PROXY_FALLBACK - -struct http_proxy_options * -parse_http_proxy_fallback (struct context *c, - const char *server, - const char *port, - const char *flags, - const int msglevel); - -#endif /* HTTP_PROXY_FALLBACK */ - #endif diff --git a/otime.c b/src/openvpn/otime.c index b295646..2c1e5b1 100644 --- a/otime.c +++ b/src/openvpn/otime.c @@ -22,6 +22,12 @@ * 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" #include "otime.h" @@ -30,7 +36,7 @@ time_t now = 0; /* GLOBAL */ -#if TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) +#if TIME_BACKTRACK_PROTECTION static time_t now_adj = 0; /* GLOBAL */ time_t now_usec = 0; /* GLOBAL */ @@ -70,7 +76,7 @@ update_now_usec (struct timeval *tv) now_usec = tv->tv_usec; } -#endif /* TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) */ +#endif /* TIME_BACKTRACK_PROTECTION */ /* * Return a numerical string describing a struct timeval. @@ -114,13 +120,7 @@ time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc) } else { -#ifdef HAVE_GETTIMEOFDAY - if (gettimeofday (&tv, NULL)) -#endif - { - tv.tv_sec = time (NULL); - tv.tv_usec = 0; - } + gettimeofday (&tv, NULL); } t = tv.tv_sec; @@ -179,78 +179,6 @@ frequency_limit_event_allowed (struct frequency_limit *f) return true; } -#ifdef WIN32 - -static time_t gtc_base = 0; -static DWORD gtc_last = 0; -static time_t last_sec = 0; -static unsigned int last_msec = 0; -static bool bt_last = false; - -static void -gettimeofday_calibrate (void) -{ - const time_t t = time(NULL); - const DWORD gtc = GetTickCount(); - gtc_base = t - gtc/1000; - gtc_last = gtc; -} - -/* - * Rewritten by JY for OpenVPN 2.1, after I realized that - * QueryPerformanceCounter takes nearly 2 orders of magnitude - * more processor cycles than GetTickCount. - */ -int -gettimeofday (struct timeval *tv, void *tz) -{ - const DWORD gtc = GetTickCount(); - bool bt = false; - time_t sec; - unsigned int msec; - const int backtrack_hold_seconds = 10; - - /* recalibrate at the dreaded 49.7 day mark */ - if (!gtc_base || gtc < gtc_last) - gettimeofday_calibrate (); - gtc_last = gtc; - - sec = gtc_base + gtc / 1000; - msec = gtc % 1000; - - if (sec == last_sec) - { - if (msec < last_msec) - { - msec = last_msec; - bt = true; - } - } - else if (sec < last_sec) - { - /* We try to dampen out backtracks of less than backtrack_hold_seconds. - Larger backtracks will be passed through and dealt with by the - TIME_BACKTRACK_PROTECTION code (if enabled) */ - if (sec > last_sec - backtrack_hold_seconds) - { - sec = last_sec; - msec = last_msec; - } - bt = true; - } - - tv->tv_sec = last_sec = sec; - tv->tv_usec = (last_msec = msec) * 1000; - - if (bt && !bt_last) - gettimeofday_calibrate (); - bt_last = bt; - - return 0; -} - -#endif /* WIN32 */ - #ifdef TIME_TEST void time_test (void) diff --git a/otime.h b/src/openvpn/otime.h index fd73bbd..4ca1032 100644 --- a/otime.h +++ b/src/openvpn/otime.h @@ -41,10 +41,6 @@ struct frequency_limit *frequency_limit_init (int max, int per); void frequency_limit_free (struct frequency_limit *f); bool frequency_limit_event_allowed (struct frequency_limit *f); -#ifdef WIN32 -int gettimeofday(struct timeval *tv, void *tz); -#endif - /* format a time_t as ascii, or use current time if 0 */ const char* time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc); @@ -57,7 +53,7 @@ extern time_t now; /* updated frequently to time(NULL) */ void time_test (void); -#if TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) +#if TIME_BACKTRACK_PROTECTION void update_now (const time_t system_time); @@ -89,12 +85,13 @@ update_time (void) #endif } -#else /* !(TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY)) */ +#else /* !TIME_BACKTRACK_PROTECTION */ static inline void update_time (void) { -#if defined(WIN32) && defined(HAVE_GETTIMEOFDAY) +#if defined(WIN32) + /* on WIN32, gettimeofday is faster than time(NULL) */ struct timeval tv; if (!gettimeofday (&tv, NULL)) { @@ -108,17 +105,13 @@ update_time (void) #endif } -#ifdef HAVE_GETTIMEOFDAY - static inline int openvpn_gettimeofday (struct timeval *tv, void *tz) { return gettimeofday (tv, tz); } -#endif - -#endif /* TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) */ +#endif /* TIME_BACKTRACK_PROTECTION */ static inline time_t openvpn_time (time_t *t) diff --git a/packet_id.c b/src/openvpn/packet_id.c index b11e71f..baa4966 100644 --- a/packet_id.c +++ b/src/openvpn/packet_id.c @@ -31,9 +31,15 @@ * to IPSec. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO #include "packet_id.h" #include "misc.h" @@ -41,6 +47,8 @@ #include "memdbg.h" +/* #define PID_SIMULATE_BACKTRACK */ + /* * Special time_t value that indicates that * sequence number has expired. @@ -48,17 +56,39 @@ #define SEQ_UNSEEN ((time_t)0) #define SEQ_EXPIRED ((time_t)1) +static void packet_id_debug_print (int msglevel, + const struct packet_id_rec *p, + const struct packet_id_net *pin, + const char *message, + int value); + +static inline void +packet_id_debug (int msglevel, + const struct packet_id_rec *p, + const struct packet_id_net *pin, + const char *message, + int value) +{ +#ifdef ENABLE_DEBUG + if (unlikely(check_debug_level(msglevel))) + packet_id_debug_print (msglevel, p, pin, message, value); +#endif +} + void -packet_id_init (struct packet_id *p, int seq_backtrack, int time_backtrack) +packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_backtrack, const char *name, int unit) { - dmsg (D_PID_DEBUG_LOW, "PID packet_id_init seq_backtrack=%d time_backtrack=%d", - seq_backtrack, - time_backtrack); + dmsg (D_PID_DEBUG, "PID packet_id_init tcp_mode=%d seq_backtrack=%d time_backtrack=%d", + tcp_mode, + seq_backtrack, + time_backtrack); ASSERT (p); CLEAR (*p); - if (seq_backtrack) + p->rec.name = name; + p->rec.unit = unit; + if (seq_backtrack && !tcp_mode) { ASSERT (MIN_SEQ_BACKTRACK <= seq_backtrack && seq_backtrack <= MAX_SEQ_BACKTRACK); ASSERT (MIN_TIME_BACKTRACK <= time_backtrack && time_backtrack <= MAX_TIME_BACKTRACK); @@ -74,7 +104,7 @@ packet_id_free (struct packet_id *p) { if (p) { - dmsg (D_PID_DEBUG_LOW, "PID packet_id_free"); + dmsg (D_PID_DEBUG, "PID packet_id_free"); if (p->rec.seq_list) free (p->rec.seq_list); CLEAR (*p); @@ -105,7 +135,11 @@ packet_id_add (struct packet_id_rec *p, const struct packet_id_net *pin) CIRC_LIST_RESET (p->seq_list); } - while (p->id < pin->id) + while (p->id < pin->id +#ifdef PID_SIMULATE_BACKTRACK + || (get_random() % 64) < 31 +#endif + ) { CIRC_LIST_PUSH (p->seq_list, SEQ_UNSEEN); ++p->id; @@ -155,17 +189,13 @@ packet_id_reap (struct packet_id_rec *p) * it is a replay. */ bool -packet_id_test (const struct packet_id_rec *p, +packet_id_test (struct packet_id_rec *p, const struct packet_id_net *pin) { - static int max_backtrack_stat; packet_id_type diff; - dmsg (D_PID_DEBUG, - "PID TEST " time_format ":" packet_id_format " " time_format ":" packet_id_format "", - (time_type)p->time, (packet_id_print_type)p->id, (time_type)pin->time, - (packet_id_print_type)pin->id); - + packet_id_debug (D_PID_DEBUG, p, pin, "PID_TEST", 0); + ASSERT (p->initialized); if (!pin->id) @@ -189,19 +219,35 @@ packet_id_test (const struct packet_id_rec *p, diff = p->id - pin->id; /* keep track of maximum backtrack seen for debugging purposes */ - if ((int)diff > max_backtrack_stat) + if ((int)diff > p->max_backtrack_stat) { - max_backtrack_stat = (int)diff; - msg (D_BACKTRACK, "Replay-window backtrack occurred [%d]", max_backtrack_stat); + p->max_backtrack_stat = (int)diff; + packet_id_debug (D_PID_DEBUG_LOW, p, pin, "PID_ERR replay-window backtrack occurred", p->max_backtrack_stat); } if (diff >= (packet_id_type) CIRC_LIST_SIZE (p->seq_list)) - return false; + { + packet_id_debug (D_PID_DEBUG_LOW, p, pin, "PID_ERR large diff", diff); + return false; + } - return CIRC_LIST_ITEM (p->seq_list, diff) == 0; + { + const time_t v = CIRC_LIST_ITEM (p->seq_list, diff); + if (v == 0) + return true; + else + { + /* raised from D_PID_DEBUG_LOW to reduce verbosity */ + packet_id_debug (D_PID_DEBUG_MEDIUM, p, pin, "PID_ERR replay", diff); + return false; + } + } } else if (pin->time < p->time) /* if time goes back, reject */ - return false; + { + packet_id_debug (D_PID_DEBUG_LOW, p, pin, "PID_ERR time backtrack", 0); + return false; + } else /* time moved forward */ return true; } @@ -322,9 +368,9 @@ packet_id_persist_load (struct packet_id_persist *p, const char *filename) if (!packet_id_persist_enabled (p)) { /* open packet-id persist file for both read and write */ - p->fd = open (filename, - O_CREAT | O_RDWR | O_BINARY, - S_IRUSR | S_IWUSR); + p->fd = platform_open (filename, + O_CREAT | O_RDWR | O_BINARY, + S_IRUSR | S_IWUSR); if (p->fd == -1) { msg (D_PID_PERSIST | M_ERRNO, @@ -434,6 +480,80 @@ packet_id_persist_print (const struct packet_id_persist *p, struct gc_arena *gc) return (char *)out.data; } +#ifdef ENABLE_DEBUG + +static void +packet_id_debug_print (int msglevel, + const struct packet_id_rec *p, + const struct packet_id_net *pin, + const char *message, + int value) +{ + struct gc_arena gc = gc_new (); + struct buffer out = alloc_buf_gc (256, &gc); + struct timeval tv; + const time_t prev_now = now; + const struct seq_list *sl = p->seq_list; + int i; + + CLEAR (tv); + gettimeofday (&tv, NULL); + + buf_printf (&out, "%s [%d]", message, value); + buf_printf (&out, " [%s-%d] [", p->name, p->unit); + for (i = 0; sl != NULL && i < sl->x_size; ++i) + { + char c; + time_t v; + int diff; + + v = CIRC_LIST_ITEM(sl, i); + if (v == SEQ_UNSEEN) + c = '_'; + else if (v == SEQ_EXPIRED) + c = 'E'; + else + { + diff = (int) prev_now - v; + if (diff < 0) + c = 'N'; + else if (diff < 10) + c = '0' + diff; + else + c = '>'; + } + buf_printf(&out, "%c", c); + } + buf_printf (&out, "] " time_format ":" packet_id_format, (time_type)p->time, (packet_id_print_type)p->id); + if (pin) + buf_printf (&out, " " time_format ":" packet_id_format, (time_type)pin->time, (packet_id_print_type)pin->id); + + buf_printf (&out, " t=" time_format "[%d]", + (time_type)prev_now, + (int)(prev_now - tv.tv_sec)); + + buf_printf (&out, " r=[%d,%d,%d,%d,%d]", + (int)(p->last_reap - tv.tv_sec), + p->seq_backtrack, + p->time_backtrack, + p->max_backtrack_stat, + (int)p->initialized); + if (sl != NULL) + { + buf_printf (&out, " sl=[%d,%d,%d,%d]", + sl->x_head, + sl->x_size, + sl->x_cap, + sl->x_sizeof); + } + + + msg (msglevel, "%s", BSTR(&out)); + gc_free (&gc); +} + +#endif + #ifdef PID_TEST void @@ -483,4 +603,4 @@ packet_id_interactive_test () } #endif -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ diff --git a/packet_id.h b/src/openvpn/packet_id.h index 12c1df3..3ddaab6 100644 --- a/packet_id.h +++ b/src/openvpn/packet_id.h @@ -28,7 +28,7 @@ * attempts to replay them back later. */ -#ifdef USE_CRYPTO +#ifdef ENABLE_CRYPTO #ifndef PACKET_ID_H #define PACKET_ID_H @@ -138,8 +138,11 @@ struct packet_id_rec packet_id_type id; /* highest sequence number received */ int seq_backtrack; /* set from --replay-window */ int time_backtrack; /* set from --replay-window */ + int max_backtrack_stat; /* maximum backtrack seen so far */ bool initialized; /* true if packet_id_init was called */ struct seq_list *seq_list; /* packet-id "memory" */ + const char *name; + int unit; }; /* @@ -207,11 +210,11 @@ struct packet_id struct packet_id_rec rec; }; -void packet_id_init (struct packet_id *p, int seq_backtrack, int time_backtrack); +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_free (struct packet_id *p); /* should we accept an incoming packet id ? */ -bool packet_id_test (const struct packet_id_rec *p, +bool packet_id_test (struct packet_id_rec *p, const struct packet_id_net *pin); /* change our current state to reflect an accepted packet id */ @@ -332,4 +335,4 @@ packet_id_reap_test (struct packet_id_rec *p) } #endif /* PACKET_ID_H */ -#endif /* USE_CRYPTO */ +#endif /* ENABLE_CRYPTO */ diff --git a/perf.c b/src/openvpn/perf.c index d9dbafc..910d171 100644 --- a/perf.c +++ b/src/openvpn/perf.c @@ -22,6 +22,12 @@ * 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" #include "perf.h" diff --git a/perf.h b/src/openvpn/perf.h index c531d9c..c531d9c 100644 --- a/perf.h +++ b/src/openvpn/perf.h diff --git a/pf-inline.h b/src/openvpn/pf-inline.h index 6b5dcb2..6b5dcb2 100644 --- a/pf-inline.h +++ b/src/openvpn/pf-inline.h @@ -24,6 +24,12 @@ /* packet filter functions */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #if defined(ENABLE_PF) @@ -119,7 +125,7 @@ add_subnet (const char *line, const char *prefix, const int line_num, struct pf_ { /* match special "unknown" tag for addresses unrecognized by mroute */ network.s_addr = htonl(0); - netmask = ~0; + netmask = IPV4_NETMASK_HOST; } { @@ -498,8 +504,8 @@ pf_check_reload (struct context *c) && c->c2.pf.filename && event_timeout_trigger (&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT)) { - struct stat s; - if (!stat (c->c2.pf.filename, &s)) + platform_stat_t s; + if (!platform_stat (c->c2.pf.filename, &s)) { if (s.st_mtime > c->c2.pf.file_last_mod) { @@ -566,7 +572,7 @@ pf_init_context (struct context *c) if (plugin_call (c->plugins, OPENVPN_PLUGIN_ENABLE_PF, NULL, NULL, c->c2.es) == OPENVPN_PLUGIN_FUNC_SUCCESS) { event_timeout_init (&c->c2.pf.reload, 1, now); - c->c2.pf.filename = string_alloc (pf_file, NULL); + c->c2.pf.filename = string_alloc (pf_file, &c->c2.gc); c->c2.pf.enabled = true; #ifdef ENABLE_DEBUG if (check_debug_level (D_PF_DEBUG)) @@ -599,7 +605,7 @@ pf_destroy_context (struct pf_context *pfc) #ifdef PLUGIN_PF if (pfc->filename) { - delete_file (pfc->filename); + platform_unlink (pfc->filename); free (pfc->filename); } #endif diff --git a/ping-inline.h b/src/openvpn/ping-inline.h index c724970..c724970 100644 --- a/ping-inline.h +++ b/src/openvpn/ping-inline.h diff --git a/ping.c b/src/openvpn/ping.c index 191ad74..6dc0b4e 100644 --- a/ping.c +++ b/src/openvpn/ping.c @@ -22,6 +22,12 @@ * 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" #include "ping.h" diff --git a/ping.h b/src/openvpn/ping.h index 88f5f3a..88f5f3a 100644 --- a/ping.h +++ b/src/openvpn/ping.h diff --git a/pkcs11.c b/src/openvpn/pkcs11.c index 9cf18e5..645f1f4 100644 --- a/pkcs11.c +++ b/src/openvpn/pkcs11.c @@ -22,12 +22,17 @@ * 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_PKCS11) #include <pkcs11-helper-1.0/pkcs11h-certificate.h> -#include <pkcs11-helper-1.0/pkcs11h-openssl.h> #include "basic.h" #include "error.h" #include "manage.h" @@ -35,6 +40,8 @@ #include "pkcs11.h" #include "misc.h" #include "otime.h" +#include "console.h" +#include "pkcs11_backend.h" static time_t @@ -561,7 +568,7 @@ pkcs11_management_id_get ( goto cleanup; } - if (base64_encode (certificate_blob, certificate_blob_size, &internal_base64) == -1) { + if (openvpn_base64_encode (certificate_blob, certificate_blob_size, &internal_base64) == -1) { msg (M_WARN, "PKCS#11: Cannot encode certificate"); goto cleanup; } @@ -605,16 +612,13 @@ cleanup: } int -SSL_CTX_use_pkcs11 ( - SSL_CTX * const ssl_ctx, +tls_ctx_use_pkcs11 ( + struct tls_root_ctx * const ssl_ctx, bool pkcs11_id_management, const char * const pkcs11_id ) { - X509 *x509 = NULL; - RSA *rsa = NULL; pkcs11h_certificate_id_t certificate_id = NULL; pkcs11h_certificate_t certificate = NULL; - pkcs11h_openssl_session_t openssl_session = NULL; CK_RV rv = CKR_OK; bool ok = false; @@ -624,7 +628,7 @@ SSL_CTX_use_pkcs11 ( dmsg ( D_PKCS11_DEBUG, - "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'", + "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'", (void *)ssl_ctx, pkcs11_id_management ? 1 : 0, pkcs11_id @@ -689,54 +693,22 @@ SSL_CTX_use_pkcs11 ( goto cleanup; } - if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL ) { - msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); + if ( + (pkcs11_init_tls_session ( + certificate, + ssl_ctx + )) + ) { + /* Handled by SSL context free */ + certificate = NULL; goto cleanup; } - /* - * Will be released by openssl_session - */ + /* Handled by SSL context free */ certificate = NULL; - - if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) { - msg (M_WARN, "PKCS#11: Unable get rsa object"); - goto cleanup; - } - - if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { - msg (M_WARN, "PKCS#11: Unable get certificate object"); - goto cleanup; - } - - if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) { - msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); - goto cleanup; - } - - if (!SSL_CTX_use_certificate (ssl_ctx, x509)) { - msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); - goto cleanup; - } - ok = true; cleanup: - /* - * openssl objects have reference - * count, so release them - */ - - if (x509 != NULL) { - X509_free (x509); - x509 = NULL; - } - - if (rsa != NULL) { - RSA_free (rsa); - rsa = NULL; - } - if (certificate != NULL) { pkcs11h_certificate_freeCertificate (certificate); certificate = NULL; @@ -746,15 +718,10 @@ cleanup: pkcs11h_certificate_freeCertificateId (certificate_id); certificate_id = NULL; } - - if (openssl_session != NULL) { - pkcs11h_openssl_freeSession (openssl_session); - openssl_session = NULL; - } dmsg ( D_PKCS11_DEBUG, - "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld", + "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv ); @@ -763,7 +730,7 @@ cleanup: } static -bool +PKCS11H_BOOL _pkcs11_openvpn_show_pkcs11_ids_pin_prompt ( void * const global_data, void * const user_data, @@ -802,6 +769,7 @@ show_pkcs11_ids ( const char * const provider, bool cert_private ) { + struct gc_arena gc = gc_new(); pkcs11h_certificate_id_list_t user_certificates = NULL; pkcs11h_certificate_id_list_t current = NULL; CK_RV rv = CKR_FUNCTION_FAILED; @@ -867,13 +835,10 @@ show_pkcs11_ids ( ); for (current = user_certificates;current != NULL; current = current->next) { pkcs11h_certificate_t certificate = NULL; - X509 *x509 = NULL; - BIO *bio = NULL; - char dn[1024] = {0}; + char *dn = NULL; char serial[1024] = {0}; char *ser = NULL; size_t ser_len = 0; - int n; if ( (rv = pkcs11h_certificate_serializeCertificateId ( @@ -918,31 +883,25 @@ show_pkcs11_ids ( goto cleanup1; } - if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) { - msg (M_FATAL, "PKCS#11: Cannot get X509"); + if ( + (dn = pkcs11_certificate_dn ( + certificate, + &gc + )) + ) { goto cleanup1; } - X509_NAME_oneline ( - X509_get_subject_name (x509), - dn, - sizeof (dn) - ); - - if ((bio = BIO_new (BIO_s_mem ())) == NULL) { - msg (M_FATAL, "PKCS#11: Cannot create BIO"); + if ( + (pkcs11_certificate_serial ( + certificate, + serial, + sizeof(serial) + )) + ) { goto cleanup1; } - i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509)); - n = BIO_read (bio, serial, sizeof (serial)-1); - if (n<0) { - serial[0] = '\x0'; - } - else { - serial[n] = 0; - } - msg ( M_INFO|M_NOPREFIX|M_NOLF, ( @@ -958,10 +917,6 @@ show_pkcs11_ids ( ); cleanup1: - if (x509 != NULL) { - X509_free (x509); - x509 = NULL; - } if (certificate != NULL) { pkcs11h_certificate_freeCertificate (certificate); @@ -981,6 +936,7 @@ cleanup: } pkcs11h_terminate (); + gc_free (&gc); } #else diff --git a/pkcs11.h b/src/openvpn/pkcs11.h index abe03b9..4261871 100644 --- a/pkcs11.h +++ b/src/openvpn/pkcs11.h @@ -27,7 +27,7 @@ #if defined(ENABLE_PKCS11) -#include <openssl/ssl.h> +#include "ssl_common.h" bool pkcs11_initialize ( @@ -63,8 +63,8 @@ pkcs11_management_id_get ( ); int -SSL_CTX_use_pkcs11 ( - SSL_CTX * const ssl_ctx, +tls_ctx_use_pkcs11 ( + struct tls_root_ctx * const ssl_ctx, bool pkcs11_id_management, const char * const pkcs11_id ); diff --git a/src/openvpn/pkcs11_backend.h b/src/openvpn/pkcs11_backend.h new file mode 100644 index 0000000..7b7ec45 --- /dev/null +++ b/src/openvpn/pkcs11_backend.h @@ -0,0 +1,75 @@ +/* + * 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 PKCS #11 SSL library-specific backend + */ + +#ifndef PKCS11_BACKEND_H_ +#define PKCS11_BACKEND_H_ + +#include "syshead.h" + +#if defined(ENABLE_PKCS11) + +#include "ssl_common.h" + +#include <pkcs11-helper-1.0/pkcs11h-certificate.h> + +/** + * Retrieve PKCS #11 Certificate's DN in a printable format. + * + * @param certificate The PKCS #11 helper certificate object + * @param gc Garbage collection pool to allocate memory in + * + * @return Certificate's DN on success, NULL on failure + */ +char * pkcs11_certificate_dn (pkcs11h_certificate_t certificate, struct gc_arena *gc); + +/** + * Retrieve PKCS #11 Certificate's serial number in a printable format. + * + * @param certificate The PKCS #11 helper certificate object + * @param serial Buffer that the certificate's serial will be placed in. + * @param serial_len Size of said buffer. + * + * @return 1 on failure, 0 on success + */ +int pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial, + size_t serial_len); + +/** + * Load PKCS #11 Certificate's information into the given TLS context + * + * @param certificate The PKCS #11 helper certificate object + * @param ssl_ctx TLS context to use. + * + * @return 1 on failure, 0 on success + */ +int pkcs11_init_tls_session(pkcs11h_certificate_t certificate, + struct tls_root_ctx * const ssl_ctx); + +#endif /* defined(ENABLE_PKCS11) */ +#endif /* PKCS11_BACKEND_H_ */ diff --git a/src/openvpn/pkcs11_openssl.c b/src/openvpn/pkcs11_openssl.c new file mode 100644 index 0000000..af843b7 --- /dev/null +++ b/src/openvpn/pkcs11_openssl.c @@ -0,0 +1,192 @@ +/* + * 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 PKCS #11 OpenSSL backend + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_OPENSSL) + +#include "errlevel.h" +#include "pkcs11_backend.h" +#include "ssl_verify.h" +#include <pkcs11-helper-1.0/pkcs11h-openssl.h> + +int +pkcs11_init_tls_session(pkcs11h_certificate_t certificate, + struct tls_root_ctx * const ssl_ctx) +{ + int ret = 1; + + X509 *x509 = NULL; + RSA *rsa = NULL; + pkcs11h_openssl_session_t openssl_session = NULL; + + if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL) + { + msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); + goto cleanup; + } + + /* + * Will be released by openssl_session + */ + certificate = NULL; + + if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) + { + msg (M_WARN, "PKCS#11: Unable get rsa object"); + goto cleanup; + } + + if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) + { + msg (M_WARN, "PKCS#11: Unable get certificate object"); + goto cleanup; + } + + if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa)) + { + msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); + goto cleanup; + } + + if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509)) + { + msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); + goto cleanup; + } + ret = 0; + +cleanup: + /* + * Certificate freeing is usually handled by openssl_session. + * If something went wrong, creating the session we have to do it manually. + */ + if (certificate != NULL) { + pkcs11h_certificate_freeCertificate (certificate); + certificate = NULL; + } + + /* + * openssl objects have reference + * count, so release them + */ + if (x509 != NULL) + { + X509_free (x509); + x509 = NULL; + } + + if (rsa != NULL) + { + RSA_free (rsa); + rsa = NULL; + } + + if (openssl_session != NULL) + { + pkcs11h_openssl_freeSession (openssl_session); + openssl_session = NULL; + } + return ret; +} + +char * +pkcs11_certificate_dn (pkcs11h_certificate_t certificate, struct gc_arena *gc) +{ + X509 *x509 = NULL; + + char *dn = NULL; + + if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) + { + msg (M_FATAL, "PKCS#11: Cannot get X509"); + goto cleanup; + } + + dn = x509_get_subject (x509, gc); + +cleanup: + if (x509 != NULL) + { + X509_free (x509); + x509 = NULL; + } + + return dn; +} + +int +pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial, + size_t serial_len) +{ + X509 *x509 = NULL; + BIO *bio = NULL; + int ret = 1; + int n; + + if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) + { + msg (M_FATAL, "PKCS#11: Cannot get X509"); + goto cleanup; + } + + if ((bio = BIO_new (BIO_s_mem ())) == NULL) + { + msg (M_FATAL, "PKCS#11: Cannot create BIO"); + goto cleanup; + } + + i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509)); + n = BIO_read (bio, serial, serial_len-1); + + if (n<0) { + serial[0] = '\x0'; + } + else { + serial[n] = 0; + } + + ret = 0; + +cleanup: + + if (x509 != NULL) + { + X509_free (x509); + x509 = NULL; + } + return ret; +} +#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_OPENSSL) */ diff --git a/src/openvpn/pkcs11_polarssl.c b/src/openvpn/pkcs11_polarssl.c new file mode 100644 index 0000000..03b2bab --- /dev/null +++ b/src/openvpn/pkcs11_polarssl.c @@ -0,0 +1,126 @@ +/* + * 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 PKCS #11 PolarSSL backend + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL) + +#include "errlevel.h" +#include "pkcs11_backend.h" +#include <polarssl/pkcs11.h> + +int +pkcs11_init_tls_session(pkcs11h_certificate_t certificate, + struct tls_root_ctx * const ssl_ctx) +{ + int ret = 1; + + ASSERT (NULL != ssl_ctx); + + if (pkcs11_x509_cert_init(ssl_ctx->crt_chain, certificate)) { + msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object"); + goto cleanup; + } + + ssl_ctx->priv_key_pkcs11 = malloc(sizeof(pkcs11_context)); + + if (ssl_ctx->priv_key_pkcs11 == NULL) { + msg (M_FATAL, "PKCS#11: Cannot allocate PolarSSL private key object"); + goto cleanup; + } + + if (pkcs11_priv_key_init(ssl_ctx->priv_key_pkcs11, certificate)) { + msg (M_FATAL, "PKCS#11: Cannot initialize PolarSSL private key object"); + goto cleanup; + } + + ret = 0; + +cleanup: + return ret; +} + +char * +pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc) +{ + char *ret = NULL; + char dn[1024] = {0}; + + x509_cert polar_cert = {0}; + + if (pkcs11_x509_cert_init(&polar_cert, cert)) { + msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object"); + goto cleanup; + } + + if (-1 == x509parse_dn_gets (dn, sizeof(dn), &polar_cert.subject)) { + msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject"); + goto cleanup; + } + + ret = string_alloc(dn, gc); + +cleanup: + x509_free(&polar_cert); + + return ret; +} + +int +pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial, + size_t serial_len) +{ + int ret = 1; + + x509_cert polar_cert = {0}; + + if (pkcs11_x509_cert_init(&polar_cert, cert)) { + msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object"); + goto cleanup; + } + + if (-1 == x509parse_serial_gets (serial, serial_len, &polar_cert.serial)) { + msg (M_FATAL, "PKCS#11: PolarSSL cannot parse serial"); + goto cleanup; + } + + ret = 0; + +cleanup: + x509_free(&polar_cert); + + return ret; +} +#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c new file mode 100644 index 0000000..e79de7a --- /dev/null +++ b/src/openvpn/platform.c @@ -0,0 +1,344 @@ +/* + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#include "buffer.h" +#include "error.h" +#include "win32.h" + +#include "memdbg.h" + +#include "platform.h" + +/* Redefine the top level directory of the filesystem + to restrict access to files for security */ +void +platform_chroot (const char *path) +{ + if (path) + { +#ifdef HAVE_CHROOT + const char *top = "/"; + if (chroot (path)) + msg (M_ERR, "chroot to '%s' failed", path); + if (platform_chdir (top)) + msg (M_ERR, "cd to '%s' failed", top); + msg (M_INFO, "chroot to '%s' and cd to '%s' succeeded", path, top); +#else + msg (M_FATAL, "Sorry but I can't chroot to '%s' because this operating system doesn't appear to support the chroot() system call", path); +#endif + } +} + +/* Get/Set UID of process */ + +bool +platform_user_get (const char *username, struct platform_state_user *state) +{ + bool ret = false; + CLEAR (*state); + if (username) + { +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) + state->pw = getpwnam (username); + if (!state->pw) + msg (M_ERR, "failed to find UID for user %s", username); + state->username = username; + ret = true; +#else + msg (M_FATAL, "cannot get UID for user %s -- platform lacks getpwname() or setuid() system calls", username); +#endif + } + return ret; +} + +void +platform_user_set (const struct platform_state_user *state) +{ +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) + if (state->username && state->pw) + { + if (setuid (state->pw->pw_uid)) + msg (M_ERR, "setuid('%s') failed", state->username); + msg (M_INFO, "UID set to %s", state->username); + } +#endif +} + +/* Get/Set GID of process */ + +bool +platform_group_get (const char *groupname, struct platform_state_group *state) +{ + bool ret = false; + CLEAR (*state); + if (groupname) + { +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) + state->gr = getgrnam (groupname); + if (!state->gr) + msg (M_ERR, "failed to find GID for group %s", groupname); + state->groupname = groupname; + ret = true; +#else + msg (M_FATAL, "cannot get GID for group %s -- platform lacks getgrnam() or setgid() system calls", groupname); +#endif + } + return ret; +} + +void +platform_group_set (const struct platform_state_group *state) +{ +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) + if (state->groupname && state->gr) + { + if (setgid (state->gr->gr_gid)) + msg (M_ERR, "setgid('%s') failed", state->groupname); + msg (M_INFO, "GID set to %s", state->groupname); +#ifdef HAVE_SETGROUPS + { + gid_t gr_list[1]; + gr_list[0] = state->gr->gr_gid; + if (setgroups (1, gr_list)) + msg (M_ERR, "setgroups('%s') failed", state->groupname); + } +#endif + } +#endif +} + +/* Change process priority */ +void +platform_nice (int niceval) +{ + if (niceval) + { +#ifdef HAVE_NICE + errno = 0; + if (nice (niceval) < 0 && errno != 0) + msg (M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, strerror(errno)); + else + msg (M_INFO, "nice %d succeeded", niceval); +#else + msg (M_WARN, "WARNING: nice %d failed (function not implemented)", niceval); +#endif + } +} + +/* Get current PID */ +unsigned int +platform_getpid () +{ +#ifdef WIN32 + return (unsigned int) GetCurrentProcessId (); +#else +#ifdef HAVE_GETPID + return (unsigned int) getpid (); +#else + return 0; +#endif +#endif +} + +/* Disable paging */ +void +platform_mlockall(bool print_msg) +{ +#ifdef HAVE_MLOCKALL + if (mlockall (MCL_CURRENT | MCL_FUTURE)) + msg (M_WARN | M_ERRNO, "WARNING: mlockall call failed"); + else if (print_msg) + msg (M_INFO, "mlockall call succeeded"); +#else + msg (M_WARN, "WARNING: mlockall call failed (function not implemented)"); +#endif +} + +/* + * Wrapper for chdir library function + */ +int +platform_chdir (const char* dir) +{ +#ifdef HAVE_CHDIR +#ifdef WIN32 + int res; + struct gc_arena gc = gc_new (); + res = _wchdir (wide_string (dir, &gc)); + gc_free (&gc); + return res; +#else + return chdir (dir); +#endif +#else + return -1; +#endif +} + +/* + * convert execve() return into a success/failure value + */ +bool +platform_system_ok (int stat) +{ +#ifdef WIN32 + return stat == 0; +#else + return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0; +#endif +} + +int +platform_access (const char *path, int mode) +{ +#ifdef WIN32 + struct gc_arena gc = gc_new (); + int ret = _waccess (wide_string (path, &gc), mode & ~X_OK); + gc_free (&gc); + return ret; +#else + return access (path, mode); +#endif +} + +/* + * Go to sleep for n milliseconds. + */ +void +platform_sleep_milliseconds (unsigned int n) +{ +#ifdef WIN32 + Sleep (n); +#else + struct timeval tv; + tv.tv_sec = n / 1000; + tv.tv_usec = (n % 1000) * 1000; + select (0, NULL, NULL, NULL, &tv); +#endif +} + +/* + * Go to sleep indefinitely. + */ +void +platform_sleep_until_signal (void) +{ +#ifdef WIN32 + ASSERT (0); +#else + select (0, NULL, NULL, NULL, NULL); +#endif +} + +/* delete a file, return true if succeeded */ +bool +platform_unlink (const char *filename) +{ +#if defined(WIN32) + struct gc_arena gc = gc_new (); + BOOL ret = DeleteFileW (wide_string (filename, &gc)); + gc_free (&gc); + return (ret != 0); +#elif defined(HAVE_UNLINK) + return (unlink (filename) == 0); +#else + return false; +#endif +} + +int platform_putenv(char *string) +{ + int status; +#if defined(WIN32) + struct gc_arena gc = gc_new (); + char *s = string_alloc(string, &gc); + char *value = strchr(s, '='); + if (value!=NULL) + { + *value = '\0'; + value++; + if (*value == '\0') + value = NULL; + } + + status = SetEnvironmentVariableW (wide_string (s, &gc), + wide_string (value, &gc)) ? 1: 0; + gc_free (&gc); +#elif defined(HAVE_PUTENV) + void manage_env (char *str); /* TODO: Resolve properly */ + status = putenv (string); + if (!status) + manage_env (string); +#endif + + return status; +} + +FILE * +platform_fopen (const char *path, const char *mode) +{ +#ifdef WIN32 + struct gc_arena gc = gc_new (); + FILE *f = _wfopen (wide_string (path, &gc), wide_string (mode, &gc)); + gc_free (&gc); + return f; +#else + return fopen(path, mode); +#endif +} + +int +platform_open (const char *path, int flags, int mode) +{ +#ifdef WIN32 + struct gc_arena gc = gc_new (); + int fd = _wopen (wide_string (path, &gc), flags, mode); + gc_free (&gc); + return fd; +#else + return open(path, flags, mode); +#endif +} + +int +platform_stat (const char *path, platform_stat_t *buf) +{ +#ifdef WIN32 + struct gc_arena gc = gc_new (); + int res = _wstat (wide_string (path, &gc), buf); + gc_free (&gc); + return res; +#else + return stat(path, buf); +#endif +} + diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h new file mode 100644 index 0000000..7c0a4d7 --- /dev/null +++ b/src/openvpn/platform.h @@ -0,0 +1,140 @@ +/* + * 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 PLATFORM_H +#define PLATFORM_H + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + +#ifdef HAVE_GRP_H +#include <grp.h> +#endif + +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif + +#include "basic.h" + +/* Get/Set UID of process */ + +struct platform_state_user { +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) + const char *username; + struct passwd *pw; +#else + int dummy; +#endif +}; + +/* Get/Set GID of process */ + +struct platform_state_group { +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) + const char *groupname; + struct group *gr; +#else + int dummy; +#endif +}; + +bool platform_user_get (const char *username, struct platform_state_user *state); +void platform_user_set (const struct platform_state_user *state); + +bool platform_group_get (const char *groupname, struct platform_state_group *state); +void platform_group_set (const struct platform_state_group *state); + +/* + * Extract UID or GID + */ + +static inline int +platform_state_user_uid (const struct platform_state_user *s) +{ +#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) + if (s->pw) + return s->pw->pw_uid; +#endif + return -1; +} + +static inline int +platform_state_group_gid (const struct platform_state_group *s) +{ +#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) + if (s->gr) + return s->gr->gr_gid; +#endif + return -1; +} + +void platform_chroot (const char *path); + +void platform_nice (int niceval); + +unsigned int platform_getpid (void); + +void platform_mlockall (bool print_msg); /* Disable paging */ + +int platform_chdir (const char* dir); + +/* interpret the status code returned by execve() */ +bool platform_system_ok (int stat); + +int platform_access (const char *path, int mode); + +void platform_sleep_milliseconds (unsigned int n); + +void platform_sleep_until_signal (void); + +/* delete a file, return true if succeeded */ +bool platform_unlink (const char *filename); + +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 +typedef struct _stat platform_stat_t; +#else +typedef struct stat platform_stat_t; +#endif +int platform_stat (const char *path, platform_stat_t *buf); + +#endif diff --git a/plugin.c b/src/openvpn/plugin.c index 0d66611..83f79e4 100644 --- a/plugin.c +++ b/src/openvpn/plugin.c @@ -22,14 +22,25 @@ * 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_PLUGIN +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#endif + #include "buffer.h" #include "error.h" #include "misc.h" #include "plugin.h" +#include "win32.h" #include "memdbg.h" @@ -87,7 +98,9 @@ plugin_type_name (const int type) case OPENVPN_PLUGIN_TLS_FINAL: return "PLUGIN_TLS_FINAL"; case OPENVPN_PLUGIN_ENABLE_PF: - return "OPENVPN_PLUGIN_ENABLE_PF"; + return "PLUGIN_ENABLE_PF"; + case OPENVPN_PLUGIN_ROUTE_PREDOWN: + return "PLUGIN_ROUTE_PREDOWN"; default: return "PLUGIN_???"; } @@ -159,7 +172,7 @@ plugin_option_list_print (const struct plugin_option_list *list, int msglevel) } #endif -#if defined(USE_LIBDL) +#ifndef WIN32 static void libdl_resolve_symbol (void *handle, void **dest, const char *symbol, const char *plugin_name, const unsigned int flags) @@ -169,7 +182,7 @@ libdl_resolve_symbol (void *handle, void **dest, const char *symbol, const char msg (M_FATAL, "PLUGIN: could not find required symbol '%s' in plugin shared object %s: %s", symbol, plugin_name, dlerror()); } -#elif defined(USE_LOAD_LIBRARY) +#else static void dll_resolve_symbol (HMODULE module, void **dest, const char *symbol, const char *plugin_name, const unsigned int flags) @@ -190,7 +203,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 (); -#if defined(USE_LIBDL) +#ifndef WIN32 p->handle = NULL; #if defined(PLUGIN_LIBDIR) @@ -219,10 +232,10 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o) # define PLUGIN_SYM(var, name, flags) libdl_resolve_symbol (p->handle, (void*)&p->var, name, p->so_pathname, flags) -#elif defined(USE_LOAD_LIBRARY) +#else rel = !absolute_pathname (p->so_pathname); - p->module = LoadLibrary (p->so_pathname); + p->module = LoadLibraryW (wide_string (p->so_pathname, &gc)); if (!p->module) msg (M_ERR, "PLUGIN_INIT: could not load plugin DLL: %s", p->so_pathname); @@ -232,8 +245,10 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o) PLUGIN_SYM (open1, "openvpn_plugin_open_v1", 0); PLUGIN_SYM (open2, "openvpn_plugin_open_v2", 0); + PLUGIN_SYM (open3, "openvpn_plugin_open_v3", 0); PLUGIN_SYM (func1, "openvpn_plugin_func_v1", 0); PLUGIN_SYM (func2, "openvpn_plugin_func_v2", 0); + PLUGIN_SYM (func3, "openvpn_plugin_func_v3", 0); PLUGIN_SYM (close, "openvpn_plugin_close_v1", PLUGIN_SYMBOL_REQUIRED); PLUGIN_SYM (abort, "openvpn_plugin_abort_v1", 0); PLUGIN_SYM (client_constructor, "openvpn_plugin_client_constructor_v1", 0); @@ -241,10 +256,10 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o) PLUGIN_SYM (min_version_required, "openvpn_plugin_min_version_required_v1", 0); PLUGIN_SYM (initialization_point, "openvpn_plugin_select_initialization_point_v1", 0); - if (!p->open1 && !p->open2) + if (!p->open1 && !p->open2 && !p->open3) msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_open_vX is undefined in plugin: %s", p->so_pathname); - if (!p->func1 && !p->func2) + if (!p->func1 && !p->func2 && !p->func3) msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_func_vX is undefined in plugin: %s", p->so_pathname); /* @@ -274,6 +289,65 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o) } static void +plugin_vlog (openvpn_plugin_log_flags_t flags, const char *name, const char *format, va_list arglist) +{ + unsigned int msg_flags; + + if (!format) + return; + + if (!name || name[0] == '\0') + { + msg (D_PLUGIN_DEBUG, "PLUGIN: suppressed log message from plugin with unknown name"); + return; + } + + if (flags & PLOG_ERR) + msg_flags = M_INFO | M_NONFATAL; + else if (flags & PLOG_WARN) + msg_flags = M_INFO | M_WARN; + else if (flags & PLOG_NOTE) + msg_flags = M_INFO; + else if (flags & PLOG_DEBUG) + msg_flags = D_PLUGIN_DEBUG; + + if (flags & PLOG_ERRNO) + msg_flags |= M_ERRNO; + if (flags & PLOG_NOMUTE) + msg_flags |= M_NOMUTE; + + if (MSG_TEST (msg_flags)) + { + struct gc_arena gc; + char* msg_fmt; + + /* Never add instance prefix; not thread safe */ + msg_flags |= M_NOIPREFIX; + + gc_init (&gc); + msg_fmt = gc_malloc (ERR_BUF_SIZE, false, &gc); + openvpn_snprintf (msg_fmt, ERR_BUF_SIZE, "PLUGIN %s: %s", name, format); + x_msg_va (msg_flags, msg_fmt, arglist); + + gc_free (&gc); + } +} + +static void +plugin_log (openvpn_plugin_log_flags_t flags, const char *name, const char *format, ...) +{ + va_list arglist; + va_start (arglist, format); + plugin_vlog (flags, name, format, arglist); + va_end (arglist); +} + +static struct openvpn_plugin_callbacks callbacks = { + plugin_log, + plugin_vlog +}; + +static void plugin_open_item (struct plugin *p, const struct plugin_option *o, struct openvpn_plugin_string_list **retlist, @@ -296,7 +370,22 @@ plugin_open_item (struct plugin *p, /* * Call the plugin initialization */ - if (p->open2) + if (p->open3) { + struct openvpn_plugin_args_open_in args = { p->plugin_type_mask, + (const char ** const) o->argv, + (const char ** const) envp, + &callbacks }; + struct openvpn_plugin_args_open_return retargs; + + CLEAR(retargs); + retargs.return_list = retlist; + if ((*p->open3)(OPENVPN_PLUGINv3_STRUCTVER, &args, &retargs) == OPENVPN_PLUGIN_FUNC_SUCCESS) { + p->plugin_type_mask = retargs.type_mask; + p->plugin_handle = retargs.handle; + } else { + p->plugin_handle = NULL; + } + } else if (p->open2) p->plugin_handle = (*p->open2)(&p->plugin_type_mask, o->argv, envp, retlist); else if (p->open1) p->plugin_handle = (*p->open1)(&p->plugin_type_mask, o->argv, envp); @@ -329,7 +418,12 @@ plugin_call_item (const struct plugin *p, const int type, const struct argv *av, struct openvpn_plugin_string_list **retlist, - const char **envp) + const char **envp +#ifdef ENABLE_SSL + , int certdepth, + openvpn_x509_cert_t *current_cert +#endif + ) { int status = OPENVPN_PLUGIN_FUNC_SUCCESS; @@ -348,7 +442,27 @@ plugin_call_item (const struct plugin *p, /* * Call the plugin work function */ - if (p->func2) + if (p->func3) { + struct openvpn_plugin_args_func_in args = { type, + (const char ** const) a.argv, + (const char ** const) envp, + p->plugin_handle, + per_client_context, +#ifdef ENABLE_SSL + (current_cert ? certdepth : -1), + current_cert +#else + -1, + NULL +#endif + }; + + struct openvpn_plugin_args_func_return retargs; + + CLEAR(retargs); + retargs.return_list = retlist; + status = (*p->func3)(OPENVPN_PLUGINv3_STRUCTVER, &args, &retargs); + } else if (p->func2) status = (*p->func2)(p->plugin_handle, type, (const char **)a.argv, envp, per_client_context, retlist); else if (p->func1) status = (*p->func1)(p->plugin_handle, type, (const char **)a.argv, envp); @@ -385,10 +499,10 @@ plugin_close_item (struct plugin *p) if (p->plugin_handle) (*p->close)(p->plugin_handle); -#if defined(USE_LIBDL) +#ifndef WIN32 if (dlclose (p->handle)) msg (M_WARN, "PLUGIN_CLOSE: dlclose() failed on plugin: %s", p->so_pathname); -#elif defined(USE_LOAD_LIBRARY) +#elif defined(WIN32) if (!FreeLibrary (p->module)) msg (M_WARN, "PLUGIN_CLOSE: FreeLibrary() failed on plugin: %s", p->so_pathname); #endif @@ -539,11 +653,16 @@ plugin_list_open (struct plugin_list *pl, } int -plugin_call (const struct plugin_list *pl, +plugin_call_ssl (const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, - struct env_set *es) + struct env_set *es +#ifdef ENABLE_SSL + , int certdepth, + openvpn_x509_cert_t *current_cert +#endif + ) { if (pr) plugin_return_init (pr); @@ -568,7 +687,12 @@ plugin_call (const struct plugin_list *pl, type, av, pr ? &pr->list[i] : NULL, - envp); + envp +#ifdef ENABLE_SSL + ,certdepth, + current_cert +#endif + ); switch (status) { case OPENVPN_PLUGIN_FUNC_SUCCESS: diff --git a/plugin.h b/src/openvpn/plugin.h index 969d451..4ba150d 100644 --- a/plugin.h +++ b/src/openvpn/plugin.h @@ -29,6 +29,12 @@ #ifndef OPENVPN_PLUGIN_H #define OPENVPN_PLUGIN_H +#ifdef ENABLE_CRYPTO_OPENSSL +#include "ssl_verify_openssl.h" +#endif +#ifdef ENABLE_CRYPTO_POLARSSL +#include "ssl_verify_polarssl.h" +#endif #include "openvpn-plugin.h" #ifdef ENABLE_PLUGIN @@ -53,16 +59,18 @@ struct plugin { unsigned int plugin_type_mask; int requested_initialization_point; -#if defined(USE_LIBDL) +#ifndef WIN32 void *handle; -#elif defined(USE_LOAD_LIBRARY) +#else HMODULE module; #endif openvpn_plugin_open_v1 open1; openvpn_plugin_open_v2 open2; + openvpn_plugin_open_v3 open3; openvpn_plugin_func_v1 func1; openvpn_plugin_func_v2 func2; + openvpn_plugin_func_v3 func3; openvpn_plugin_close_v1 close; openvpn_plugin_abort_v1 abort; openvpn_plugin_client_constructor_v1 client_constructor; @@ -114,11 +122,16 @@ void plugin_list_open (struct plugin_list *pl, struct plugin_list *plugin_list_inherit (const struct plugin_list *src); -int plugin_call (const struct plugin_list *pl, +int plugin_call_ssl (const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, - struct env_set *es); + struct env_set *es +#ifdef ENABLE_SSL + , int current_cert_depth, + openvpn_x509_cert_t *current_cert +#endif + ); void plugin_list_close (struct plugin_list *pl); bool plugin_defined (const struct plugin_list *pl, const int type); @@ -155,7 +168,6 @@ plugin_return_init (struct plugin_return *pr) } #else - struct plugin_list { int dummy; }; struct plugin_return { int dummy; }; @@ -166,15 +178,34 @@ plugin_defined (const struct plugin_list *pl, const int type) } static inline int -plugin_call (const struct plugin_list *pl, +plugin_call_ssl (const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, - struct env_set *es) + struct env_set *es +#ifdef ENABLE_SSL + , int current_cert_depth, + openvpn_x509_cert_t *current_cert +#endif + ) { return 0; } #endif /* ENABLE_PLUGIN */ +static inline int +plugin_call(const struct plugin_list *pl, + const int type, + const struct argv *av, + struct plugin_return *pr, + struct env_set *es) +{ + return plugin_call_ssl(pl, type, av, pr, es +#ifdef ENABLE_SSL + , -1, NULL +#endif + ); +} + #endif /* OPENVPN_PLUGIN_H */ diff --git a/pool.c b/src/openvpn/pool.c index 84333df..28c26b4 100644 --- a/pool.c +++ b/src/openvpn/pool.c @@ -22,6 +22,12 @@ * 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" #include "pool.h" @@ -132,7 +138,10 @@ ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_ } struct ifconfig_pool * -ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn) +ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, + const bool duplicate_cn, + const bool ipv6_pool, const struct in6_addr ipv6_base, + const int ipv6_netbits ) { struct gc_arena gc = gc_new (); struct ifconfig_pool *pool = NULL; @@ -157,11 +166,31 @@ ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplica ASSERT (0); } + /* IPv6 pools are always "INDIV" type */ + pool->ipv6 = ipv6_pool; + + if ( pool->ipv6 ) + { + pool->base_ipv6 = ipv6_base; + pool->size_ipv6 = ipv6_netbits>96? ( 1<<(128-ipv6_netbits) ) + : IFCONFIG_POOL_MAX; + + msg( D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: (IPv4) size=%d, size_ipv6=%d, netbits=%d, base_ipv6=%s", + pool->size, pool->size_ipv6, ipv6_netbits, + print_in6_addr( pool->base_ipv6, 0, &gc )); + + /* the current code is very simple and assumes that the IPv6 + * pool is at least as big as the IPv4 pool, and we don't need + * to do separate math etc. for IPv6 + */ + ASSERT( pool->size < pool->size_ipv6 ); + } + ALLOC_ARRAY_CLEAR (pool->list, struct ifconfig_pool_entry, pool->size); - msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d", + msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d, ipv6=%d", print_in_addr_t (pool->base, 0, &gc), - pool->size); + pool->size, pool->ipv6 ); gc_free (&gc); return pool; @@ -181,7 +210,7 @@ ifconfig_pool_free (struct ifconfig_pool *pool) } ifconfig_pool_handle -ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name) +ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name) { int i; @@ -214,6 +243,12 @@ ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t * default: ASSERT (0); } + + /* IPv6 pools are always INDIV (--linear) */ + if ( pool->ipv6 && remote_ipv6 ) + { + *remote_ipv6 = add_in6_addr( pool->base_ipv6, i ); + } } return i; } @@ -288,6 +323,19 @@ ifconfig_pool_handle_to_ip_base (const struct ifconfig_pool* pool, ifconfig_pool return ret; } +static struct in6_addr +ifconfig_pool_handle_to_ipv6_base (const struct ifconfig_pool* pool, ifconfig_pool_handle hand) +{ + struct in6_addr ret = in6addr_any; + + /* IPv6 pools are always INDIV (--linear) */ + if (hand >= 0 && hand < pool->size_ipv6 ) + { + ret = add_in6_addr( pool->base_ipv6, hand ); + } + return ret; +} + static void ifconfig_pool_set (struct ifconfig_pool* pool, const char *cn, const in_addr_t addr, const bool fixed) { @@ -317,9 +365,20 @@ ifconfig_pool_list (const struct ifconfig_pool* pool, struct status_output *out) if (e->common_name) { const in_addr_t ip = ifconfig_pool_handle_to_ip_base (pool, i); - status_printf (out, "%s,%s", - e->common_name, - print_in_addr_t (ip, 0, &gc)); + if ( pool->ipv6 ) + { + struct in6_addr ip6 = ifconfig_pool_handle_to_ipv6_base (pool, i); + status_printf (out, "%s,%s,%s", + e->common_name, + print_in_addr_t (ip, 0, &gc), + print_in6_addr (ip6, 0, &gc)); + } + else + { + status_printf (out, "%s,%s", + e->common_name, + print_in_addr_t (ip, 0, &gc)); + } } } gc_free (&gc); @@ -409,6 +468,9 @@ ifconfig_pool_read (struct ifconfig_pool_persist *persist, struct ifconfig_pool int c = *BSTR(&in); if (c == '#' || c == ';') continue; + msg( M_INFO, "ifconfig_pool_read(), in='%s', TODO: IPv6", + BSTR(&in) ); + if (buf_parse (&in, ',', cn_buf, buf_size) && buf_parse (&in, ',', ip_buf, buf_size)) { @@ -416,6 +478,7 @@ ifconfig_pool_read (struct ifconfig_pool_persist *persist, struct ifconfig_pool const in_addr_t addr = getaddr (GETADDR_HOST_ORDER, ip_buf, 0, &succeeded, NULL); if (succeeded) { + msg( M_INFO, "succeeded -> ifconfig_pool_set()"); ifconfig_pool_set (pool, cn_buf, addr, persist->fixed); } } @@ -471,7 +534,7 @@ ifconfig_pool_test (in_addr_t start, in_addr_t end) #else cn = buf; #endif - h = ifconfig_pool_acquire (p, &local, &remote, cn); + h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn); if (h < 0) break; msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s", @@ -506,7 +569,7 @@ ifconfig_pool_test (in_addr_t start, in_addr_t end) #else cn = buf; #endif - h = ifconfig_pool_acquire (p, &local, &remote, cn); + h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn); if (h < 0) break; msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s", diff --git a/pool.h b/src/openvpn/pool.h index 81264a9..fc9d6ab 100644 --- a/pool.h +++ b/src/openvpn/pool.h @@ -52,6 +52,9 @@ struct ifconfig_pool int size; int type; bool duplicate_cn; + bool ipv6; + struct in6_addr base_ipv6; + unsigned int size_ipv6; struct ifconfig_pool_entry *list; }; @@ -63,13 +66,13 @@ struct ifconfig_pool_persist typedef int ifconfig_pool_handle; -struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn); +struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits ); void ifconfig_pool_free (struct ifconfig_pool *pool); bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end); -ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name); +ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name); bool ifconfig_pool_release (struct ifconfig_pool* pool, ifconfig_pool_handle hand, const bool hard); diff --git a/proto.c b/src/openvpn/proto.c index 65a6b67..2cf8314 100644 --- a/proto.c +++ b/src/openvpn/proto.c @@ -22,6 +22,12 @@ * 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" #include "proto.h" diff --git a/proto.h b/src/openvpn/proto.h index 55f0832..8cd4ede 100644 --- a/proto.h +++ b/src/openvpn/proto.h @@ -108,6 +108,21 @@ struct openvpn_iphdr { }; /* + * IPv6 header + */ +struct openvpn_ipv6hdr { + uint8_t version_prio; + uint8_t flow_lbl[3]; + uint16_t payload_len; + uint8_t nexthdr; + uint8_t hop_limit; + + struct in6_addr saddr; + struct in6_addr daddr; +}; + + +/* * UDP header */ struct openvpn_udphdr { @@ -149,6 +164,14 @@ struct openvpn_tcphdr { #define OPENVPN_TCPOPT_MAXSEG 2 #define OPENVPN_TCPOLEN_MAXSEG 4 +struct ip_tcp_udp_hdr { + struct openvpn_iphdr ip; + union { + struct openvpn_tcphdr tcp; + struct openvpn_udphdr udp; + } u; +}; + #pragma pack() /* @@ -160,19 +183,30 @@ struct openvpn_tcphdr { * is the checksum value to be updated. */ #define ADJUST_CHECKSUM(acc, cksum) { \ - (acc) += (cksum); \ - if ((acc) < 0) { \ - (acc) = -(acc); \ - (acc) = ((acc) >> 16) + ((acc) & 0xffff); \ - (acc) += (acc) >> 16; \ - (cksum) = (uint16_t) ~(acc); \ + int _acc = acc; \ + _acc += (cksum); \ + if (_acc < 0) { \ + _acc = -_acc; \ + _acc = (_acc >> 16) + (_acc & 0xffff); \ + _acc += _acc >> 16; \ + (cksum) = (uint16_t) ~_acc; \ } else { \ - (acc) = ((acc) >> 16) + ((acc) & 0xffff); \ - (acc) += (acc) >> 16; \ - (cksum) = (uint16_t) (acc); \ + _acc = (_acc >> 16) + (_acc & 0xffff); \ + _acc += _acc >> 16; \ + (cksum) = (uint16_t) _acc; \ } \ } +#define ADD_CHECKSUM_32(acc, u32) { \ + acc += (u32) & 0xffff; \ + acc += (u32) >> 16; \ +} + +#define SUB_CHECKSUM_32(acc, u32) { \ + acc -= (u32) & 0xffff; \ + acc -= (u32) >> 16; \ +} + /* * We are in a "liberal" position with respect to MSS, * i.e. we assume that MSS can be calculated from MTU diff --git a/proxy.c b/src/openvpn/proxy.c index fce64a1..363d8a7 100644 --- a/proxy.c +++ b/src/openvpn/proxy.c @@ -22,6 +22,12 @@ * 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" #include "common.h" @@ -34,17 +40,27 @@ #include "base64.h" #include "httpdigest.h" #include "ntlm.h" - -#ifdef WIN32 -#include "ieproxy.h" -#endif - #include "memdbg.h" #ifdef ENABLE_HTTP_PROXY #define UP_TYPE_PROXY "HTTP Proxy" +struct http_proxy_options * +init_http_proxy_options_once (struct http_proxy_options **hpo, + struct gc_arena *gc) +{ + if (!*hpo) + { + ALLOC_OBJ_CLEAR_GC (*hpo, struct http_proxy_options, gc); + /* http proxy defaults */ + (*hpo)->timeout = 5; + (*hpo)->http_version = "1.0"; + } + return *hpo; +} + + /* cached proxy username/password */ static struct user_pass static_proxy_user_pass; @@ -92,7 +108,7 @@ recv_line (socket_descriptor_t sd, if (status == 0) { if (verbose) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read timeout expired"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read timeout expired"); goto error; } @@ -100,7 +116,7 @@ recv_line (socket_descriptor_t sd, if (status < 0) { if (verbose) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read failed on select()"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on select()"); goto error; } @@ -111,7 +127,7 @@ recv_line (socket_descriptor_t sd, if (size != 1) { if (verbose) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read failed on recv()"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on recv()"); goto error; } @@ -136,7 +152,7 @@ recv_line (socket_descriptor_t sd, if (!isprint(c) && !isspace(c)) /* not ascii? */ { if (verbose) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: Non-ASCII character (%d) read on recv()", (int)c); + msg (D_LINK_ERRORS | M_ERRNO, "recv_line: Non-ASCII character (%d) read on recv()", (int)c); *lookahead = la; return false; } @@ -166,7 +182,7 @@ send_line (socket_descriptor_t sd, const ssize_t size = send (sd, buf, strlen (buf), MSG_NOSIGNAL); if (size != (ssize_t) strlen (buf)) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "send_line: TCP port write failed on send()"); + msg (D_LINK_ERRORS | M_ERRNO, "send_line: TCP port write failed on send()"); return false; } return true; @@ -197,7 +213,7 @@ make_base64_string2 (const uint8_t *str, int src_len, struct gc_arena *gc) { uint8_t *ret = NULL; char *b64out = NULL; - ASSERT (base64_encode ((const void *)str, src_len, &b64out) >= 0); + ASSERT (openvpn_base64_encode ((const void *)str, src_len, &b64out) >= 0); ret = (uint8_t *) string_alloc (b64out, gc); free (b64out); return ret; @@ -420,47 +436,11 @@ get_pa_var (const char *key, const char *pa, struct gc_arena *gc) } struct http_proxy_info * -http_proxy_new (const struct http_proxy_options *o, - struct auto_proxy_info *auto_proxy_info) +http_proxy_new (const struct http_proxy_options *o) { struct http_proxy_info *p; struct http_proxy_options opt; - if (auto_proxy_info) - { - if (o && o->server) - { - /* if --http-proxy explicitly given, disable auto-proxy */ - auto_proxy_info = NULL; - } - else - { - /* if no --http-proxy explicitly given and no auto settings, fail */ - if (!auto_proxy_info->http.server) - return NULL; - - if (o) - { - opt = *o; - } - else - { - CLEAR (opt); - - /* These settings are only used for --auto-proxy */ - opt.timeout = 5; - opt.http_version = "1.0"; - } - - opt.server = auto_proxy_info->http.server; - opt.port = auto_proxy_info->http.port; - if (!opt.auth_retry) - opt.auth_retry = PAR_ALL; - - o = &opt; - } - } - if (!o || !o->server) msg (M_FATAL, "HTTP_PROXY: server not specified"); @@ -526,7 +506,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p, bool ret = false; bool processed = false; - /* get user/pass if not previously given or if --auto-proxy is being used */ + /* get user/pass if not previously given */ if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_DIGEST || p->auth_method == HTTP_AUTH_NTLM) @@ -745,7 +725,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p, const char *opaque = get_pa_var("opaque", pa, &gc); /* generate a client nonce */ - ASSERT(RAND_bytes(cnonce_raw, sizeof(cnonce_raw))); + ASSERT(rand_bytes(cnonce_raw, sizeof(cnonce_raw))); cnonce = make_base64_string2(cnonce_raw, sizeof(cnonce_raw), &gc); @@ -925,205 +905,3 @@ establish_http_proxy_passthru (struct http_proxy_info *p, static void dummy(void) {} #endif /* ENABLE_HTTP_PROXY */ -#ifdef GENERAL_PROXY_SUPPORT - -#ifdef WIN32 - -#if 0 -char * -get_windows_internet_string (const DWORD dwOption, struct gc_arena *gc) -{ - DWORD size = 0; - char *ret = NULL; - - /* Initially, get size of return buffer */ - InternetQueryOption (NULL, dwOption, NULL, &size); - if (size) - { - /* Now get actual info */ - ret = (INTERNET_PROXY_INFO *) gc_malloc (size, false, gc); - if (!InternetQueryOption (NULL, dwOption, (LPVOID) ret, &size)) - ret = NULL; - } - return ret; -} -#endif - -static INTERNET_PROXY_INFO * -get_windows_proxy_settings (struct gc_arena *gc) -{ - DWORD size = 0; - INTERNET_PROXY_INFO *ret = NULL; - - /* Initially, get size of return buffer */ - InternetQueryOption (NULL, INTERNET_OPTION_PROXY, NULL, &size); - if (size) - { - /* Now get actual info */ - ret = (INTERNET_PROXY_INFO *) gc_malloc (size, false, gc); - if (!InternetQueryOption (NULL, INTERNET_OPTION_PROXY, (LPVOID) ret, &size)) - ret = NULL; - } - return ret; -} - -static const char * -parse_windows_proxy_setting (const char *str, struct auto_proxy_info_entry *e, struct gc_arena *gc) -{ - char buf[128]; - const char *ret = NULL; - struct buffer in; - - CLEAR (*e); - - buf_set_read (&in, (const uint8_t *)str, strlen (str)); - - if (strchr (str, '=') != NULL) - { - if (buf_parse (&in, '=', buf, sizeof (buf))) - ret = string_alloc (buf, gc); - } - - if (buf_parse (&in, ':', buf, sizeof (buf))) - e->server = string_alloc (buf, gc); - - if (e->server && buf_parse (&in, '\0', buf, sizeof (buf))) - e->port = atoi (buf); - - return ret; -} - -static void -parse_windows_proxy_setting_list (const char *str, const char *type, struct auto_proxy_info_entry *e, struct gc_arena *gc) -{ - struct gc_arena gc_local = gc_new (); - struct auto_proxy_info_entry el; - - CLEAR (*e); - if (type) - { - char buf[128]; - struct buffer in; - - buf_set_read (&in, (const uint8_t *)str, strlen (str)); - if (strchr (str, '=') != NULL) - { - while (buf_parse (&in, ' ', buf, sizeof (buf))) - { - const char *t = parse_windows_proxy_setting (buf, &el, &gc_local); - if (t && !strcmp (t, type)) - goto found; - } - } - } - else - { - if (!parse_windows_proxy_setting (str, &el, &gc_local)) - goto found; - } - goto done; - - found: - if (el.server && el.port > 0) - { - e->server = string_alloc (el.server, gc); - e->port = el.port; - } - - done: - gc_free (&gc_local); -} - -static const char * -win_proxy_access_type (const DWORD dwAccessType) -{ - switch (dwAccessType) - { - case INTERNET_OPEN_TYPE_DIRECT: - return "INTERNET_OPEN_TYPE_DIRECT"; - case INTERNET_OPEN_TYPE_PROXY: - return "INTERNET_OPEN_TYPE_PROXY"; - default: - return "[UNKNOWN]"; - } -} - -void -show_win_proxy_settings (const int msglevel) -{ - INTERNET_PROXY_INFO *info; - struct gc_arena gc = gc_new (); - - info = get_windows_proxy_settings (&gc); - msg (msglevel, "PROXY INFO: %s %s", - win_proxy_access_type (info->dwAccessType), - info->lpszProxy ? info->lpszProxy : "[NULL]"); - - gc_free (&gc); -} - -struct auto_proxy_info * -get_proxy_settings (char **err, struct gc_arena *gc) -{ - struct gc_arena gc_local = gc_new (); - INTERNET_PROXY_INFO *info; - struct auto_proxy_info *pi; - - ALLOC_OBJ_CLEAR_GC (pi, struct auto_proxy_info, gc); - - if (err) - *err = NULL; - - info = get_windows_proxy_settings (&gc_local); - - if (!info) - { - if (err) - *err = "PROXY: failed to obtain windows proxy info"; - goto done; - } - - switch (info->dwAccessType) - { - case INTERNET_OPEN_TYPE_DIRECT: - break; - case INTERNET_OPEN_TYPE_PROXY: - if (!info->lpszProxy) - break; - parse_windows_proxy_setting_list (info->lpszProxy, NULL, &pi->http, gc); - if (!pi->http.server) - parse_windows_proxy_setting_list (info->lpszProxy, "http", &pi->http, gc); - parse_windows_proxy_setting_list (info->lpszProxy, "socks", &pi->socks, gc); - break; - default: - if (err) - *err = "PROXY: unknown proxy type"; - break; - } - - done: - gc_free (&gc_local); - return pi; -} - -#else - -struct auto_proxy_info * -get_proxy_settings (char **err, struct gc_arena *gc) -{ -#if 1 - if (err) - *err = string_alloc ("PROXY: automatic detection not supported on this OS", gc); - return NULL; -#else /* test --auto-proxy feature */ - struct auto_proxy_info *pi; - ALLOC_OBJ_CLEAR_GC (pi, struct auto_proxy_info, gc); - pi->http.server = "10.10.0.2"; - pi->http.port = 4000; - return pi; -#endif -} - -#endif - -#endif /* GENERAL_PROXY_SUPPORT */ diff --git a/proxy.h b/src/openvpn/proxy.h index d89aa4a..5e476f1 100644 --- a/proxy.h +++ b/src/openvpn/proxy.h @@ -28,30 +28,6 @@ #include "buffer.h" #include "misc.h" -#ifdef GENERAL_PROXY_SUPPORT - -/* - * Return value for get_proxy_settings to automatically - * determine proxy information. - */ -struct auto_proxy_info_entry { - char *server; - int port; -}; - -struct auto_proxy_info { - struct auto_proxy_info_entry http; - struct auto_proxy_info_entry socks; -}; - -struct auto_proxy_info *get_proxy_settings (char **err, struct gc_arena *gc); - -#ifdef WIN32 -void show_win_proxy_settings (const int msglevel); -#endif /* WIN32 */ - -#endif /* GENERAL_PROXY_SUPPORT */ - #ifdef ENABLE_HTTP_PROXY /* HTTP CONNECT authentication methods */ @@ -94,8 +70,10 @@ struct http_proxy_info { bool queried_creds; }; -struct http_proxy_info *http_proxy_new (const struct http_proxy_options *o, - struct auto_proxy_info *auto_proxy_info); +struct http_proxy_options *init_http_proxy_options_once (struct http_proxy_options **hpo, + struct gc_arena *gc); + +struct http_proxy_info *http_proxy_new (const struct http_proxy_options *o); void http_proxy_close (struct http_proxy_info *hp); @@ -22,6 +22,12 @@ * 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 PORT_SHARE @@ -69,6 +75,7 @@ struct proxy_connection { bool buffer_initial; int rwflags; int sd; + char *jfn; }; #if 0 @@ -226,7 +233,9 @@ port_share_sendmsg (const socket_descriptor_t sd, status = sendmsg (sd, &mesg, MSG_NOSIGNAL); if (status == -1) - msg (M_WARN, "PORT SHARE: sendmsg failed (unable to communicate with background process)"); + msg (M_WARN|M_ERRNO, "PORT SHARE: sendmsg failed -- unable to communicate with background process (%d,%d,%d,%d)", + sd, sd_send, sd_null[0], sd_null[1] + ); close_socket_if_defined (sd_null[0]); close_socket_if_defined (sd_null[1]); @@ -261,6 +270,12 @@ proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es) pc->buffer_initial = false; pc->rwflags = 0; pc->defined = false; + if (pc->jfn) + { + unlink (pc->jfn); + free (pc->jfn); + pc->jfn = NULL; + } if (cp && cp->defined && cp->counterpart == pc) proxy_entry_mark_for_close (cp, es); } @@ -297,6 +312,48 @@ proxy_list_housekeeping (struct proxy_connection **list) } /* + * Record IP/port of client in filesystem, so that server receiving + * the proxy can determine true client origin. + */ +static void +journal_add (const char *journal_dir, struct proxy_connection *pc, struct proxy_connection *cp) +{ + struct gc_arena gc = gc_new (); + struct openvpn_sockaddr from, to; + socklen_t slen, dlen; + int fnlen; + char *jfn; + int fd; + + slen = sizeof(from.addr.sa); + dlen = sizeof(to.addr.sa); + 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); + fnlen = strlen(journal_dir) + strlen(t) + 2; + jfn = (char *) malloc(fnlen); + check_malloc_return (jfn); + openvpn_snprintf (jfn, fnlen, "%s/%s", journal_dir, t); + dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", jfn, f); + fd = platform_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP); + if (fd != -1) + { + write(fd, f, strlen(f)); + close (fd); + cp->jfn = jfn; + } + else + { + msg (M_WARN|M_ERRNO, "PORT SHARE: unable to write journal file in %s", jfn); + free (jfn); + } + } + gc_free (&gc); +} + +/* * Cleanup function, on proxy process exit. */ static void @@ -320,9 +377,9 @@ sock_addr_set (struct openvpn_sockaddr *osaddr, const int port) { CLEAR (*osaddr); - osaddr->sa.sin_family = AF_INET; - osaddr->sa.sin_addr.s_addr = htonl (addr); - osaddr->sa.sin_port = htons (port); + 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 @@ -349,7 +406,8 @@ proxy_entry_new (struct proxy_connection **list, const in_addr_t server_addr, const int server_port, const socket_descriptor_t sd_client, - struct buffer *initial_data) + struct buffer *initial_data, + const char *journal_dir) { struct openvpn_sockaddr osaddr; socket_descriptor_t sd_server; @@ -359,7 +417,11 @@ proxy_entry_new (struct proxy_connection **list, /* connect to port share server */ sock_addr_set (&osaddr, server_addr, server_port); - sd_server = create_socket_tcp (); + 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); if (status) { @@ -396,6 +458,10 @@ proxy_entry_new (struct proxy_connection **list, /* add to list */ *list = pc; + + /* add journal entry */ + if (journal_dir) + journal_add (journal_dir, pc, cp); dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: NEW CONNECTION [c=%d s=%d]", (int)sd_client, (int)sd_server); @@ -417,9 +483,14 @@ 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 int server_port, + const int max_initial_buf, + const char *journal_dir) { - struct buffer buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE); + /* this buffer needs to be large enough to handle the largest buffer + that might be returned by the link_socket_read call in read_incoming_link. */ + struct buffer buf = alloc_buf (max_initial_buf); + struct msghdr mesg; struct cmsghdr* h; struct iovec iov[2]; @@ -455,7 +526,7 @@ control_message_from_parent (const socket_descriptor_t sd_control, || h->cmsg_level != SOL_SOCKET || h->cmsg_type != SCM_RIGHTS ) { - ret = false; + msg (M_WARN, "PORT SHARE PROXY: received unknown message"); } else { @@ -470,7 +541,8 @@ control_message_from_parent (const socket_descriptor_t sd_control, server_addr, server_port, received_fd, - &buf)) + &buf, + journal_dir)) { CLEAR (buf); /* we gave the buffer to proxy_entry_new */ } @@ -505,6 +577,7 @@ proxy_connection_io_recv (struct proxy_connection *pc) { if (!status) return IOSTAT_READ_ERROR; + dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: read[%d] %d", (int)pc->sd, status); pc->buf.len = status; } return IOSTAT_GOOD; @@ -532,7 +605,7 @@ proxy_connection_io_send (struct proxy_connection *pc, int *bytes_sent) } else { - /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: wrote[%d] %d", (int)sd, status);*/ + dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: wrote[%d] %d", (int)sd, status); pc->buf.len = 0; pc->buf.offset = 0; } @@ -615,6 +688,8 @@ proxy_connection_io_dispatch (struct proxy_connection *pc, int rwflags_pc = pc->rwflags; int rwflags_cp = cp->rwflags; + ASSERT(pc->defined && cp->defined && cp->counterpart == pc); + if (rwflags & EVENT_READ) { const int status = proxy_connection_io_xfer (pc, max_transfer_per_iteration); @@ -641,7 +716,11 @@ 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, const socket_descriptor_t sd_control) +port_share_proxy (const in_addr_t hostaddr, + const int port, + const socket_descriptor_t sd_control, + const int max_initial_buf, + const char *journal_dir) { if (send_control (sd_control, RESPONSE_INIT_SUCCEEDED) >= 0) { @@ -675,7 +754,7 @@ port_share_proxy (const in_addr_t hostaddr, const int port, const socket_descrip 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)) + if (!control_message_from_parent (sd_control, &list, es, hostaddr, port, max_initial_buf, journal_dir)) goto done; } else @@ -701,7 +780,7 @@ port_share_proxy (const in_addr_t hostaddr, const int port, const socket_descrip proxy_list_close (&list); event_free (es); } - msg (D_PS_PROXY, "PORT SHARE PROXY: proxy exiting"); + msg (M_INFO, "PORT SHARE PROXY: proxy exiting"); } /* @@ -709,7 +788,10 @@ port_share_proxy (const in_addr_t hostaddr, const int port, const socket_descrip * share proxy. */ struct port_share * -port_share_open (const char *host, const int port) +port_share_open (const char *host, + const int port, + const int max_initial_buf, + const char *journal_dir) { pid_t pid; socket_descriptor_t fd[2]; @@ -717,6 +799,8 @@ port_share_open (const char *host, const int port) struct port_share *ps; ALLOC_OBJ_CLEAR (ps, struct port_share); + ps->foreground_fd = -1; + ps->background_pid = -1; /* * Get host's IP address @@ -758,9 +842,17 @@ port_share_open (const char *host, const int port) status = recv_control (fd[0]); if (status == RESPONSE_INIT_SUCCEEDED) { + /* note that this will cause possible EAGAIN when writing to + control socket if proxy process is backlogged */ + set_nonblock (fd[0]); + ps->foreground_fd = fd[0]; return ps; } + else + { + msg (M_ERR, "PORT SHARE: unexpected init recv_control status=%d", status); + } } else { @@ -789,7 +881,7 @@ port_share_open (const char *host, const int port) prng_init (NULL, 0); /* execute the event loop */ - port_share_proxy (hostaddr, port, fd[1]); + port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir); openvpn_close_socket (fd[1]); @@ -874,7 +966,9 @@ void port_share_redirect (struct port_share *ps, const struct buffer *head, socket_descriptor_t sd) { if (ps) - port_share_sendmsg (ps->foreground_fd, COMMAND_REDIRECT, head, sd); + { + port_share_sendmsg (ps->foreground_fd, COMMAND_REDIRECT, head, sd); + } } #endif @@ -44,7 +44,9 @@ struct port_share { extern struct port_share *port_share; struct port_share *port_share_open (const char *host, - const int port); + const int port, + const int max_initial_buf, + const char *journal_dir); void port_share_close (struct port_share *ps); void port_share_abort (struct port_share *ps); diff --git a/push.c b/src/openvpn/push.c index 08c7f99..05a38e0 100644 --- a/push.c +++ b/src/openvpn/push.c @@ -22,6 +22,12 @@ * 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" #include "push.h" @@ -42,7 +48,7 @@ void receive_auth_failed (struct context *c, const struct buffer *buffer) { - msg (M_VERB0, "AUTH: Received AUTH_FAILED control message"); + msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer)); connection_list_set_no_advance(&c->options); if (c->options.pull) { @@ -52,7 +58,7 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */ break; case AR_INTERACT: - ssl_purge_auth (); + ssl_purge_auth (false); case AR_NOINTERACT: c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */ break; @@ -87,13 +93,48 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) * Act on received restart message from server */ void -server_pushed_restart (struct context *c, const struct buffer *buffer) +server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv) { if (c->options.pull) { - msg (D_STREAM_ERRORS, "Connection reset command was pushed by server"); - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ - c->sig->signal_text = "server-pushed-connection-reset"; + struct buffer buf = *buffer; + const char *m = ""; + if (buf_advance (&buf, adv) && buf_read_u8 (&buf) == ',' && BLEN (&buf)) + m = BSTR (&buf); + + /* preserve cached passwords? */ + { + bool purge = true; + + if (m[0] == '[') + { + int i; + for (i = 1; m[i] != '\0' && m[i] != ']'; ++i) + { + if (m[i] == 'P') + purge = false; + } + } + if (purge) + ssl_purge_auth (true); + } + + if (restart) + { + msg (D_STREAM_ERRORS, "Connection reset command was pushed by server ('%s')", m); + c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ + c->sig->signal_text = "server-pushed-connection-reset"; + } + else + { + msg (D_STREAM_ERRORS, "Halt command was pushed by server ('%s')", m); + c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- server-pushed halt */ + c->sig->signal_text = "server-pushed-halt"; + } +#ifdef ENABLE_MANAGEMENT + if (management) + management_notify (management, "info", c->sig->signal_text, m); +#endif } } @@ -130,10 +171,10 @@ send_auth_failed (struct context *c, const char *client_reason) * Send restart message from server to client. */ void -send_restart (struct context *c) +send_restart (struct context *c, const char *kill_msg) { schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); - send_control_channel_string (c, "RESTART", D_PUSH); + send_control_channel_string (c, kill_msg ? kill_msg : "RESTART", D_PUSH); } #endif @@ -149,7 +190,7 @@ incoming_push_message (struct context *c, const struct buffer *buffer) unsigned int option_types_found = 0; int status; - msg (D_PUSH, "PUSH: Received control message: '%s'", BSTR (buffer)); + msg (D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc)); status = process_incoming_push_msg (c, buffer, @@ -158,7 +199,7 @@ incoming_push_message (struct context *c, const struct buffer *buffer) &option_types_found); if (status == PUSH_MSG_ERROR) - msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", BSTR (buffer)); + msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc)); else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION) { if (status == PUSH_MSG_REPLY) @@ -172,7 +213,18 @@ incoming_push_message (struct context *c, const struct buffer *buffer) bool send_push_request (struct context *c) { - return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH); + const int max_push_requests = c->options.handshake_window / PUSH_REQUEST_INTERVAL; + if (++c->c2.n_sent_push_requests <= max_push_requests) + { + return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH); + } + else + { + msg (D_STREAM_ERRORS, "No reply from server after sending %d push requests", max_push_requests); + c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ + c->sig->signal_text = "no-push-reply"; + return false; + } } #if P2MP_SERVER @@ -185,12 +237,28 @@ send_push_reply (struct context *c) struct push_entry *e = c->options.push_list.head; bool multi_push = false; static char cmd[] = "PUSH_REPLY"; - const int extra = 64; /* extra space for possible trailing ifconfig and push-continuation */ + const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */ const int safe_cap = BCAP (&buf) - extra; bool push_sent = false; + msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap ); + buf_printf (&buf, "%s", cmd); + if ( c->c2.push_ifconfig_ipv6_defined ) + { + /* 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) + { + msg (M_WARN, "--push ifconfig-ipv6 option is too long"); + goto fail; + } + } + while (e) { if (e->enable) @@ -220,9 +288,16 @@ send_push_reply (struct context *c) } if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask) - buf_printf (&buf, ",ifconfig %s %s", - print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc), - print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc)); + { + 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"); @@ -341,8 +416,21 @@ process_incoming_push_msg (struct context *c, } else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED) { - if (send_push_reply (c)) - ret = PUSH_MSG_REQUEST; + time_t now; + + openvpn_time(&now); + if (c->c2.sent_push_reply_expiry > now) + { + ret = PUSH_MSG_ALREADY_REPLIED; + } + else + { + if (send_push_reply (c)) + { + ret = PUSH_MSG_REQUEST; + c->c2.sent_push_reply_expiry = now + 30; + } + } } else { diff --git a/push.h b/src/openvpn/push.h index 089cf45..8c3f157 100644 --- a/push.h +++ b/src/openvpn/push.h @@ -35,6 +35,7 @@ #define PUSH_MSG_REQUEST_DEFERRED 3 #define PUSH_MSG_AUTH_FAILURE 4 #define PUSH_MSG_CONTINUATION 5 +#define PUSH_MSG_ALREADY_REPLIED 6 void incoming_push_message (struct context *c, const struct buffer *buffer); @@ -49,7 +50,7 @@ bool send_push_request (struct context *c); void receive_auth_failed (struct context *c, const struct buffer *buffer); -void server_pushed_restart (struct context *c, const struct buffer *buffer); +void server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv); #if P2MP_SERVER @@ -66,7 +67,7 @@ void remove_iroutes_from_push_route_list (struct options *o); void send_auth_failed (struct context *c, const char *client_reason); -void send_restart (struct context *c); +void send_restart (struct context *c, const char *kill_msg); #endif #endif diff --git a/pushlist.h b/src/openvpn/pushlist.h index b252676..b252676 100644 --- a/pushlist.h +++ b/src/openvpn/pushlist.h diff --git a/reliable.c b/src/openvpn/reliable.c index 1f238cc..763169e 100644 --- a/reliable.c +++ b/src/openvpn/reliable.c @@ -27,9 +27,15 @@ * so that SSL/TLS can be run over UDP. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) #include "buffer.h" #include "error.h" @@ -748,4 +754,4 @@ reliable_debug_print (const struct reliable *rel, char *desc) #else static void dummy(void) {} -#endif /* USE_CRYPTO && USE_SSL*/ +#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ diff --git a/src/openvpn/reliable.h b/src/openvpn/reliable.h new file mode 100644 index 0000000..594ab82 --- /dev/null +++ b/src/openvpn/reliable.h @@ -0,0 +1,480 @@ +/* + * 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-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 + */ + + +/** + * @file + * Reliability Layer module header file. + */ + + +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) + +#ifndef RELIABLE_H +#define RELIABLE_H + +#include "basic.h" +#include "buffer.h" +#include "packet_id.h" +#include "session_id.h" +#include "mtu.h" + +/** @addtogroup reliable + * @{ */ + + +#define EXPONENTIAL_BACKOFF + +#define RELIABLE_ACK_SIZE 8 /**< The maximum number of packet IDs + * waiting to be acknowledged which can + * be stored in one \c reliable_ack + * structure. */ + +#define RELIABLE_CAPACITY 8 /**< The maximum number of packets that + * the reliability layer for one VPN + * tunnel in one direction can store. */ + +/** + * The acknowledgment structure in which packet IDs are stored for later + * acknowledgment. + */ +struct reliable_ack +{ + int len; + packet_id_type packet_id[RELIABLE_ACK_SIZE]; +}; + +/** + * The structure in which the reliability layer stores a single incoming + * or outgoing packet. + */ +struct reliable_entry +{ + bool active; + interval_t timeout; + time_t next_try; + packet_id_type packet_id; + int opcode; + struct buffer buf; +}; + +/** + * The reliability layer storage structure for one VPN tunnel's control + * channel in one direction. + */ +struct reliable +{ + int size; + interval_t initial_timeout; + packet_id_type packet_id; + int offset; + bool hold; /* don't xmit until reliable_schedule_now is called */ + struct reliable_entry array[RELIABLE_CAPACITY]; +}; + + +/**************************************************************************/ +/** @name Functions for processing incoming acknowledgments + * @{ */ + +/** + * Read an acknowledgment record from a received packet. + * + * This function reads the packet ID acknowledgment record from the packet + * contained in \a buf. If the record contains acknowledgments, these are + * stored in \a ack. This function also compares the packet's session ID + * with the expected session ID \a sid, which should be equal. + * + * @param ack The acknowledgment structure in which received + * acknowledgments are to be stored. + * @param buf The buffer containing the packet. + * @param sid The expected session ID to compare to the session ID in + * the packet. + * + * @return + * @li True, if processing was successful. + * @li False, if an error occurs during processing. + */ +bool reliable_ack_read (struct reliable_ack *ack, + struct buffer *buf, const struct session_id *sid); + +/** + * Remove acknowledged packets from a reliable structure. + * + * @param rel The reliable structure storing sent packets. + * @param ack The acknowledgment structure containing received + * acknowledgments. + */ +void reliable_send_purge (struct reliable *rel, struct reliable_ack *ack); + +/** @} name Functions for processing incoming acknowledgments */ + + +/**************************************************************************/ +/** @name Functions for processing outgoing acknowledgments + * @{ */ + +/** + * Check whether an acknowledgment structure contains any + * packet IDs to be acknowledged. + * + * @param ack The acknowledgment structure to check. + * + * @return + * @li True, if the acknowledgment structure is empty. + * @li False, if there are packet IDs to be acknowledged. + */ +static inline bool +reliable_ack_empty (struct reliable_ack *ack) +{ + return !ack->len; +} + +/** + * Write a packet ID acknowledgment record to a buffer. + * + * @param ack The acknowledgment structure containing packet IDs to be + * acknowledged. + * @param buf The buffer into which the acknowledgment record will be + * written. + * @param sid The session ID of the VPN tunnel associated with the + * packet IDs to be acknowledged. + * @param max The maximum number of acknowledgments to be written in + * the record. + * @param prepend If true, prepend the acknowledgment record in the + * buffer; if false, write into the buffer's current position. + * + * @return + * @li True, if processing was successful. + * @li False, if an error occurs during processing. + */ +bool reliable_ack_write (struct reliable_ack *ack, + struct buffer *buf, + const struct session_id *sid, int max, bool prepend); + +/** @} name Functions for processing outgoing acknowledgments */ + + +/**************************************************************************/ +/** @name Functions for initialization and cleanup + * @{ */ + +/** + * Initialize a reliable structure. + * + * @param rel The reliable structure to initialize. + * @param buf_size The size of the buffers in which packets will be + * stored. + * @param offset The size of reserved space at the beginning of the + * buffers to allow efficient header prepending. + * @param array_size The number of packets that this reliable + * structure can store simultaneously. + * @param hold description + */ +void reliable_init (struct reliable *rel, int buf_size, int offset, int array_size, bool hold); + +/** + * Free allocated memory associated with a reliable structure. + * + * @param rel The reliable structured to clean up. + */ +void reliable_free (struct reliable *rel); + +/* add to extra_frame the maximum number of bytes we will need for reliable_ack_write */ +void reliable_ack_adjust_frame_parameters (struct frame* frame, int max); + +/** @} name Functions for initialization and cleanup */ + + +/**************************************************************************/ +/** @name Functions for inserting incoming packets + * @{ */ + +/** + * Check whether a reliable structure has any free buffers + * available for use. + * + * @param rel The reliable structure to check. + * + * @return + * @li True, if at least one buffer is available for use. + * @li False, if all the buffers are active. + */ +bool reliable_can_get (const struct reliable *rel); + +/** + * Check that a received packet's ID is not a replay. + * + * @param rel The reliable structure for handling this VPN tunnel's + * received packets. + * @param id The packet ID of the received packet. + * + * @return + * @li True, if the packet ID is not a replay. + * @li False, if the packet ID is a replay. + */ +bool reliable_not_replay (const struct reliable *rel, packet_id_type id); + +/** + * Check that a received packet's ID can safely be stored in + * the reliable structure's processing window. + * + * This function checks the difference between the received packet's ID + * and the lowest non-acknowledged packet ID in the given reliable + * structure. If that difference is larger than the total number of + * packets which can be stored, then this packet cannot be stored safely, + * because the reliable structure could possibly fill up without leaving + * room for all intervening packets. In that case, this received packet + * could break the reliable structure's sequentiality, and must therefore + * be discarded. + * + * @param rel The reliable structure for handling this VPN tunnel's + * received packets. + * @param id The packet ID of the received packet. + * + * @return + * @li True, if the packet can safely be stored. + * @li False, if the packet does not fit safely in the reliable + * structure's processing window. + */ +bool reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id); + +/** + * Read the packet ID of a received packet. + * + * @param buf The buffer containing the received packet. + * @param pid A pointer where the packet's packet ID will be written. + * + * @return + * @li True, if processing was successful. + * @li False, if an error occurs during processing. + */ +bool reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid); + +/** + * Get the buffer of a free %reliable entry in which to store a + * packet. + * + * @param rel The reliable structure in which to search for a free + * entry. + * + * @return A pointer to a buffer of a free entry in the \a rel + * reliable structure. If there are no free entries available, this + * function returns NULL. + */ +struct buffer *reliable_get_buf (struct reliable *rel); + +/** + * Mark the %reliable entry associated with the given buffer as active + * incoming. + * + * @param rel The reliable structure associated with this packet. + * @param buf The buffer into which the packet has been copied. + * @param pid The packet's packet ID. + * @param opcode The packet's opcode. + */ +void reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf, + packet_id_type pid, int opcode); + +/** + * Record a packet ID for later acknowledgment. + * + * @param ack The acknowledgment structure which stores this VPN + * tunnel's packet IDs for later acknowledgment. + * @param pid The packet ID of the received packet which should be + * acknowledged. + * + * @return + * @li True, if the packet ID was added to \a ack. + * @li False, if the packet ID was already present in \a ack or \a ack + * has no free space to store any more packet IDs. + */ +bool reliable_ack_acknowledge_packet_id (struct reliable_ack *ack, packet_id_type pid); + +/** @} name Functions for inserting incoming packets */ + + +/**************************************************************************/ +/** @name Functions for extracting incoming packets + * @{ */ + +/** + * Get the buffer of the next sequential and active entry. + * + * @param rel The reliable structure from which to retrieve the + * buffer. + * + * @return A pointer to the buffer of the entry with the next + * sequential key ID. If no such entry is present, this function + * returns NULL. + */ +struct buffer *reliable_get_buf_sequenced (struct reliable *rel); + +/** + * Remove an entry from a reliable structure. + * + * @param rel The reliable structure associated with the given buffer. + * @param buf The buffer of the reliable entry which is to be removed. + * @param inc_pid If true, the reliable structure's packet ID counter + * will be incremented. + */ +void reliable_mark_deleted (struct reliable *rel, struct buffer *buf, bool inc_pid); + +/** @} name Functions for extracting incoming packets */ + + +/**************************************************************************/ +/** @name Functions for inserting outgoing packets + * @{ */ + +/** + * Get the buffer of free reliable entry and check whether the + * outgoing acknowledgment sequence is still okay. + * + * @param rel The reliable structure in which to search for a free + * entry. + * + * @return A pointer to a buffer of a free entry in the \a rel + * reliable structure. If there are no free entries available, this + * function returns NULL. If the outgoing acknowledgment sequence is + * broken, this function also returns NULL. + */ +struct buffer *reliable_get_buf_output_sequenced (struct reliable *rel); + +/** + * Mark the reliable entry associated with the given buffer as + * active outgoing. + * + * @param rel The reliable structure for handling this VPN tunnel's + * outgoing packets. + * @param buf The buffer previously returned by \c + * reliable_get_buf_output_sequenced() into which the packet has been + * copied. + * @param opcode The packet's opcode. + */ +void reliable_mark_active_outgoing (struct reliable *rel, struct buffer *buf, int opcode); + +/** @} name Functions for inserting outgoing packets */ + + +/**************************************************************************/ +/** @name Functions for extracting outgoing packets + * @{ */ + +/** + * Check whether a reliable structure has any active entries + * ready to be (re)sent. + * + * @param rel The reliable structure to check. + * + * @return + * @li True, if there are active entries ready to be (re)sent + * president. + * @li False, if there are no active entries, or the active entries + * are not yet ready for resending. + */ +bool reliable_can_send (const struct reliable *rel); + +/** + * Get the next packet to send to the remote peer. + * + * This function looks for the active entry ready for (re)sending with the + * lowest packet ID, and returns the buffer associated with it. This + * function also resets the timeout after which that entry will become + * ready for resending again. + * + * @param rel The reliable structure to check. + * @param opcode A pointer to an integer in which this function will + * store the opcode of the next packet to be sent. + * + * @return A pointer to the buffer of the next entry to be sent, or + * NULL if there are no entries ready for (re)sending present in the + * reliable structure. If a valid pointer is returned, then \a opcode + * will point to the opcode of that packet. + */ +struct buffer *reliable_send (struct reliable *rel, int *opcode); + +/** @} name Functions for extracting outgoing packets */ + + +/**************************************************************************/ +/** @name Miscellaneous functions + * @{ */ + +/** + * Check whether a reliable structure is empty. + * + * @param rel The reliable structure to check. + * + * @return + * @li True, if there are no active entries in the given reliable + * structure. + * @li False, if there is at least one active entry present. + */ +bool reliable_empty (const struct reliable *rel); + +/** + * Determined how many seconds until the earliest resend should + * be attempted. + * + * @param rel The reliable structured to check. + * + * @return The interval in seconds until the earliest resend attempt + * of the outgoing packets stored in the \a rel reliable structure. If + * the next time for attempting resending of one or more packets has + * already passed, this function will return 0. + */ +interval_t reliable_send_timeout (const struct reliable *rel); + +/** + * Reschedule all entries of a reliable structure to be ready + * for (re)sending immediately. + * + * @param rel The reliable structure of which the entries should be + * modified. + */ +void reliable_schedule_now (struct reliable *rel); + +void reliable_debug_print (const struct reliable *rel, char *desc); + +/* set sending timeout (after this time we send again until ACK) */ +static inline void +reliable_set_timeout (struct reliable *rel, interval_t timeout) +{ + rel->initial_timeout = timeout; +} + +/* print a reliable ACK record coming off the wire */ +const char *reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc); + +void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc); + +/** @} name Miscellaneous functions */ + + +/** @} addtogroup reliable */ + + +#endif /* RELIABLE_H */ +#endif /* ENABLE_CRYPTO && ENABLE_SSL */ diff --git a/route.c b/src/openvpn/route.c index b5092fe..8c3d0dc 100644 --- a/route.c +++ b/src/openvpn/route.c @@ -26,6 +26,12 @@ * Support routines for adding/deleting network routes. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #include "common.h" @@ -35,10 +41,16 @@ #include "socket.h" #include "manage.h" #include "win32.h" +#include "options.h" #include "memdbg.h" -static void delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); +#ifdef WIN32 +#define METRIC_NOT_USED ((DWORD)-1) +#endif + +static void delete_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es); + static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags); #ifdef ENABLE_DEBUG @@ -59,6 +71,26 @@ print_bypass_addresses (const struct route_bypass *rb) #endif +static bool +add_bypass_address (struct route_bypass *rb, const in_addr_t a) +{ + int i; + for (i = 0; i < rb->n_bypass; ++i) + { + if (a == rb->bypass[i]) /* avoid duplicates */ + return true; + } + if (rb->n_bypass < N_ROUTE_BYPASS) + { + rb->bypass[rb->n_bypass++] = a; + return true; + } + else + { + return false; + } +} + struct route_option_list * new_route_option_list (const int max_routes, struct gc_arena *a) { @@ -68,6 +100,15 @@ new_route_option_list (const int max_routes, struct gc_arena *a) return ret; } +struct route_ipv6_option_list * +new_route_ipv6_option_list (const int max_routes, 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; + return ret; +} + struct route_option_list * clone_route_option_list (const struct route_option_list *src, struct gc_arena *a) { @@ -77,12 +118,31 @@ clone_route_option_list (const struct route_option_list *src, struct gc_arena *a 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); + return ret; +} + void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src) { const size_t src_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list)); - if (src->n > 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->n, dest->capacity); + 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); +} + +void +copy_route_ipv6_option_list (struct route_ipv6_option_list *dest, + const struct route_ipv6_option_list *src) +{ + 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); } @@ -95,6 +155,15 @@ new_route_list (const int max_routes, struct gc_arena *a) 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; +} + static const char * route_string (const struct route *r, struct gc_arena *gc) { @@ -104,7 +173,7 @@ route_string (const struct route *r, struct gc_arena *gc) print_in_addr_t (r->netmask, 0, gc), print_in_addr_t (r->gateway, 0, gc) ); - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) buf_printf (&out, " metric %d", r->metric); return BSTR (&out); } @@ -133,7 +202,7 @@ setenv_route_addr (struct env_set *es, const char *key, const in_addr_t addr, in } static bool -get_special_addr (const struct route_special_addr *spec, +get_special_addr (const struct route_list *rl, const char *string, in_addr_t *out, bool *status) @@ -142,10 +211,10 @@ get_special_addr (const struct route_special_addr *spec, *status = true; if (!strcmp (string, "vpn_gateway")) { - if (spec) + if (rl) { - if (spec->remote_endpoint_defined) - *out = spec->remote_endpoint; + if (rl->spec.flags & RTSA_REMOTE_ENDPOINT) + *out = rl->spec.remote_endpoint; else { msg (M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined"); @@ -157,10 +226,10 @@ get_special_addr (const struct route_special_addr *spec, } else if (!strcmp (string, "net_gateway")) { - if (spec) + if (rl) { - if (spec->net_gateway_defined) - *out = spec->net_gateway; + if (rl->rgi.flags & RGI_ADDR_DEFINED) + *out = rl->rgi.gateway.addr; else { msg (M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system"); @@ -172,10 +241,10 @@ get_special_addr (const struct route_special_addr *spec, } else if (!strcmp (string, "remote_host")) { - if (spec) + if (rl) { - if (spec->remote_host_defined) - *out = spec->remote_host; + if (rl->spec.flags & RTSA_REMOTE_HOST) + *out = rl->spec.remote_host; else { msg (M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined"); @@ -199,15 +268,17 @@ is_special_addr (const char *addr_str) static bool init_route (struct route *r, - struct resolve_list *network_list, + struct addrinfo **network_list, const struct route_option *ro, - const struct route_special_addr *spec) + const struct route_list *rl) { - const in_addr_t default_netmask = ~0; + const in_addr_t default_netmask = IPV4_NETMASK_HOST; bool status; + int ret; + struct in_addr special; + CLEAR (*r); r->option = ro; - r->defined = false; /* network */ @@ -215,19 +286,22 @@ init_route (struct route *r, { goto fail; } - - if (!get_special_addr (spec, ro->network, &r->network, &status)) + + + /* 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)) { - r->network = getaddr_multi ( - GETADDR_RESOLVE - | GETADDR_HOST_ORDER - | GETADDR_WARN_ON_SIGNAL, - ro->network, - 0, - &status, - NULL, - network_list); + special.s_addr = htonl(special.s_addr); + ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL, + AF_INET, network_list); } + else + ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL, + ro->network, 0, NULL, AF_INET, network_list); + + status = (ret == 0); if (!status) goto fail; @@ -253,7 +327,7 @@ init_route (struct route *r, if (is_route_parm_defined (ro->gateway)) { - if (!get_special_addr (spec, ro->gateway, &r->gateway, &status)) + if (!get_special_addr (rl, ro->gateway, &r->gateway, &status)) { r->gateway = getaddr ( GETADDR_RESOLVE @@ -269,8 +343,8 @@ init_route (struct route *r, } else { - if (spec->remote_endpoint_defined) - r->gateway = spec->remote_endpoint; + if (rl->spec.flags & RTSA_REMOTE_ENDPOINT) + r->gateway = rl->spec.remote_endpoint; else { msg (M_WARN, PACKAGE_NAME " ROUTE: " PACKAGE_NAME " needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options"); @@ -280,7 +354,6 @@ init_route (struct route *r, /* metric */ - r->metric_defined = false; r->metric = 0; if (is_route_parm_defined (ro->metric)) { @@ -292,22 +365,82 @@ init_route (struct route *r, ro->metric); goto fail; } - r->metric_defined = true; + r->flags |= RT_METRIC_DEFINED; } - else if (spec->default_metric_defined) + else if (rl->spec.flags & RTSA_DEFAULT_METRIC) { - r->metric = spec->default_metric; - r->metric_defined = true; + r->metric = rl->spec.default_metric; + r->flags |= RT_METRIC_DEFINED; } - r->defined = true; + r->flags |= RT_DEFINED; return true; fail: msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s", ro->network); - r->defined = false; + return false; +} + +static bool +init_route_ipv6 (struct route_ipv6 *r6, + const struct route_ipv6_option *r6o, + const struct route_ipv6_list *rl6 ) +{ + r6->defined = false; + + if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN )) + goto fail; + + /* gateway */ + if (is_route_parm_defined (r6o->gateway)) + { + if ( inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1 ) + { + msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway ); + } + } + else if (rl6->remote_endpoint_defined) + { + r6->gateway = rl6->remote_endpoint_ipv6; + } + else + { + msg (M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options"); + goto fail; + } + + /* metric */ + + r6->metric_defined = false; + r6->metric = -1; + if (is_route_parm_defined (r6o->metric)) + { + r6->metric = atoi (r6o->metric); + if (r6->metric < 0) + { + msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0", + r6o->prefix, + r6o->metric); + goto fail; + } + r6->metric_defined = true; + } + else if (rl6->default_metric_defined) + { + r6->metric = rl6->default_metric; + r6->metric_defined = true; + } + + r6->defined = true; + + 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; } @@ -331,6 +464,23 @@ add_route_to_option_list (struct route_option_list *l, } void +add_route_ipv6_to_option_list (struct route_ipv6_option_list *l, + const char *prefix, + const char *gateway, + 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]; + ro->prefix = prefix; + ro->gateway = gateway; + ro->metric = metric; + ++l->n; +} + +void clear_route_list (struct route_list *rl) { const int capacity = rl->capacity; @@ -340,15 +490,79 @@ clear_route_list (struct route_list *rl) } void -route_list_add_default_gateway (struct route_list *rl, - struct env_set *es, - const in_addr_t addr) +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; +} + +void +route_list_add_vpn_gateway (struct route_list *rl, + struct env_set *es, + const in_addr_t addr) { rl->spec.remote_endpoint = addr; - rl->spec.remote_endpoint_defined = true; + rl->spec.flags |= RTSA_REMOTE_ENDPOINT; setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1); } +static void +add_block_local_item (struct route_list *rl, + const struct route_gateway_address *gateway, + in_addr_t target) +{ + 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) + { + struct route r; + unsigned int l2; + + /* 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; + } +} + +static void +add_block_local (struct route_list *rl) +{ + const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); + if ((rl->flags & RG_BLOCK_LOCAL) + && (rl->rgi.flags & rgi_needed) == rgi_needed + && (rl->spec.flags & RTSA_REMOTE_ENDPOINT) + && rl->spec.remote_host_local != TLA_LOCAL) + { + size_t i; + + /* add bypass for gateway addr */ + add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr); + + /* block access to local subnet */ + add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint); + + /* process additional subnets on gateway interface */ + for (i = 0; i < rl->rgi.n_addrs; ++i) + { + const struct route_gateway_address *gwa = &rl->rgi.addrs[i]; + /* omit the add/subnet in &rl->rgi which we processed above */ + if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask) + && rl->rgi.gateway.netmask == gwa->netmask)) + add_block_local_item (rl, gwa, rl->spec.remote_endpoint); + } + } +} + bool init_route_list (struct route_list *rl, const struct route_option_list *opt, @@ -367,48 +581,47 @@ init_route_list (struct route_list *rl, if (remote_host) { rl->spec.remote_host = remote_host; - rl->spec.remote_host_defined = true; + rl->spec.flags |= RTSA_REMOTE_HOST; } if (default_metric) { rl->spec.default_metric = default_metric; - rl->spec.default_metric_defined = true; + rl->spec.flags |= RTSA_DEFAULT_METRIC; } - rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway, NULL); - if (rl->spec.net_gateway_defined) + get_default_gateway (&rl->rgi); + if (rl->rgi.flags & RGI_ADDR_DEFINED) { - setenv_route_addr (es, "net_gateway", rl->spec.net_gateway, -1); - dmsg (D_ROUTE, "ROUTE default_gateway=%s", print_in_addr_t (rl->spec.net_gateway, 0, &gc)); + setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1); +#ifdef ENABLE_DEBUG + print_default_gateway (D_ROUTE, &rl->rgi); +#endif } else { dmsg (D_ROUTE, "ROUTE: default_gateway=UNDEF"); } - if (rl->flags & RG_ENABLE) - { - get_bypass_addresses (&rl->spec.bypass, rl->flags); -#ifdef ENABLE_DEBUG - print_bypass_addresses (&rl->spec.bypass); -#endif - } + if (rl->spec.flags & RTSA_REMOTE_HOST) + rl->spec.remote_host_local = test_local_addr (remote_host, &rl->rgi); if (is_route_parm_defined (remote_endpoint)) { + bool defined = false; rl->spec.remote_endpoint = getaddr ( GETADDR_RESOLVE | GETADDR_HOST_ORDER | GETADDR_WARN_ON_SIGNAL, remote_endpoint, 0, - &rl->spec.remote_endpoint_defined, + &defined, NULL); - if (rl->spec.remote_endpoint_defined) + if (defined) { setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1); + rl->spec.flags |= RTSA_REMOTE_ENDPOINT; } else { @@ -417,38 +630,39 @@ init_route_list (struct route_list *rl, ret = false; } } - else - rl->spec.remote_endpoint_defined = false; + + if (rl->flags & RG_ENABLE) + { + add_block_local (rl); + get_bypass_addresses (&rl->spec.bypass, rl->flags); +#ifdef ENABLE_DEBUG + print_bypass_addresses (&rl->spec.bypass); +#endif + } /* parse the routes from opt to rl */ { - int i, j = 0; + int i = 0; + int j = rl->n; bool warned = false; for (i = 0; i < opt->n; ++i) { - struct resolve_list netlist; + struct addrinfo* netlist; struct route r; - int k; - - CLEAR(netlist); /* init_route() will not always init this */ if (!init_route (&r, &netlist, &opt->routes[i], - &rl->spec)) + rl)) ret = false; else { - if (!netlist.len) - { - netlist.data[0] = r.network; - netlist.len = 1; - } - for (k = 0; k < netlist.len; ++k) + struct addrinfo* curele; + for (curele = netlist; curele; curele = curele->ai_next) { if (j < rl->capacity) { - r.network = netlist.data[k]; + r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr); rl->routes[j++] = r; } else @@ -460,6 +674,7 @@ init_route_list (struct route_list *rl, } } } + freeaddrinfo(netlist); } } rl->n = j; @@ -469,21 +684,88 @@ init_route_list (struct route_list *rl, return ret; } +bool +init_route_ipv6_list (struct route_ipv6_list *rl6, + const struct route_ipv6_option_list *opt6, + const char *remote_endpoint, + int default_metric, + struct env_set *es) +{ + struct gc_arena gc = gc_new (); + bool ret = true; + + clear_route_ipv6_list (rl6); + + rl6->flags = opt6->flags; + + if (default_metric >= 0 ) + { + rl6->default_metric = default_metric; + rl6->default_metric_defined = true; + } + + /* "default_gateway" is stuff for "redirect-gateway", which we don't + * do for IPv6 yet -> TODO + */ + { + dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF"); + } + + if ( is_route_parm_defined( remote_endpoint )) + { + if ( inet_pton( AF_INET6, remote_endpoint, + &rl6->remote_endpoint_ipv6) == 1 ) + { + rl6->remote_endpoint_defined = true; + } + else + { + msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint); + ret = false; + } + } + else + rl6->remote_endpoint_defined = 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) + { + if (!init_route_ipv6 (&rl6->routes_ipv6[j], + &opt6->routes_ipv6[i], + rl6 )) + ret = false; + else + ++j; + } + rl6->n = j; + } + + gc_free (&gc); + return ret; +} + static void add_route3 (in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es) { struct route r; CLEAR (r); - r.defined = true; + r.flags = RT_DEFINED; r.network = network; r.netmask = netmask; r.gateway = gateway; - add_route (&r, tt, flags, es); + add_route (&r, tt, flags, rgi, es); } static void @@ -492,15 +774,16 @@ del_route3 (in_addr_t network, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es) { struct route r; CLEAR (r); - r.defined = true; + r.flags = RT_DEFINED|RT_ADDED; r.network = network; r.netmask = netmask; r.gateway = gateway; - delete_route (&r, tt, flags, es); + delete_route (&r, tt, flags, rgi, es); } static void @@ -508,17 +791,19 @@ add_bypass_routes (struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es) { int i; for (i = 0; i < rb->n_bypass; ++i) { - if (rb->bypass[i] != gateway) + if (rb->bypass[i]) add_route3 (rb->bypass[i], - ~0, + IPV4_NETMASK_HOST, gateway, tt, - flags, + flags | ROUTE_REF_GW, + rgi, es); } } @@ -528,17 +813,19 @@ del_bypass_routes (struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, + const struct route_gateway_info *rgi, const struct env_set *es) { int i; for (i = 0; i < rb->n_bypass; ++i) { - if (rb->bypass[i] != gateway) + if (rb->bypass[i]) del_route3 (rb->bypass[i], - ~0, + IPV4_NETMASK_HOST, gateway, tt, - flags, + flags | ROUTE_REF_GW, + rgi, es); } } @@ -548,17 +835,17 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u { const char err[] = "NOTE: unable to redirect default gateway --"; - if (rl->flags & RG_ENABLE) + if ( rl && rl->flags & RG_ENABLE ) { - if (!rl->spec.remote_endpoint_defined) + if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT)) { msg (M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err); } - else if (!rl->spec.net_gateway_defined) + else if (!(rl->rgi.flags & RGI_ADDR_DEFINED)) { msg (M_WARN, "%s Cannot read current default gateway from system", err); } - else if (!rl->spec.remote_host_defined) + else if (!(rl->spec.flags & RTSA_REMOTE_HOST)) { msg (M_WARN, "%s Cannot obtain current remote host address", err); } @@ -566,7 +853,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u { bool local = BOOL_CAST(rl->flags & RG_LOCAL); if (rl->flags & RG_AUTO_LOCAL) { - const int tla = test_local_addr (rl->spec.remote_host); + const int tla = rl->spec.remote_host_local; if (tla == TLA_NONLOCAL) { dmsg (D_ROUTE, "ROUTE remote_host is NOT LOCAL"); @@ -581,17 +868,24 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u if (!local) { /* route remote host to original default gateway */ - add_route3 (rl->spec.remote_host, - ~0, - rl->spec.net_gateway, - tt, - flags, - es); - rl->did_local = true; + /* if remote_host is not ipv4 (ie: ipv6), just skip + * adding this special /32 route */ + if (rl->spec.remote_host != IPV4_INVALID_ADDR) { + add_route3 (rl->spec.remote_host, + IPV4_NETMASK_HOST, + rl->rgi.gateway.addr, + tt, + flags | ROUTE_REF_GW, + &rl->rgi, + es); + rl->iflags |= RL_DID_LOCAL; + } else { + dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled"); + } } /* route DHCP/DNS server traffic through original default gateway */ - add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); + add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es); if (rl->flags & RG_REROUTE_GW) { @@ -603,6 +897,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); /* add new default route (2nd component) */ @@ -611,6 +906,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); } else @@ -618,9 +914,10 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u /* delete default route */ del_route3 (0, 0, - rl->spec.net_gateway, + rl->rgi.gateway.addr, tt, - flags, + flags | ROUTE_REF_GW, + &rl->rgi, es); /* add new default route */ @@ -629,12 +926,13 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); } } /* set a flag so we can undo later */ - rl->did_redirect_default_gateway = true; + rl->iflags |= RL_DID_REDIRECT_DEFAULT_GATEWAY; } } } @@ -642,22 +940,23 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u static void undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es) { - if (rl->did_redirect_default_gateway) + if ( rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY ) { /* delete remote host route */ - if (rl->did_local) + if (rl->iflags & RL_DID_LOCAL) { del_route3 (rl->spec.remote_host, - ~0, - rl->spec.net_gateway, + IPV4_NETMASK_HOST, + rl->rgi.gateway.addr, tt, - flags, + flags | ROUTE_REF_GW, + &rl->rgi, es); - rl->did_local = false; + rl->iflags &= ~RL_DID_LOCAL; } /* delete special DHCP/DNS bypass route */ - del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); + del_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es); if (rl->flags & RG_REROUTE_GW) { @@ -669,6 +968,7 @@ undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap * rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); /* delete default route (2nd component) */ @@ -677,6 +977,7 @@ undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap * rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); } else @@ -687,27 +988,29 @@ undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap * rl->spec.remote_endpoint, tt, flags, + &rl->rgi, es); /* restore original default route */ add_route3 (0, 0, - rl->spec.net_gateway, + rl->rgi.gateway.addr, tt, - flags, + flags | ROUTE_REF_GW, + &rl->rgi, es); } } - rl->did_redirect_default_gateway = false; + rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY; } } void -add_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es) +add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es) { redirect_default_route_to_vpn (rl, tt, flags, es); - if (!rl->routes_added) + if ( rl && !(rl->iflags & RL_ROUTES_ADDED) ) { int i; @@ -727,29 +1030,63 @@ add_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, struct route *r = &rl->routes[i]; check_subnet_conflict (r->network, r->netmask, "route"); if (flags & ROUTE_DELETE_FIRST) - delete_route (r, tt, flags, es); - add_route (r, tt, flags, es); + delete_route (r, tt, flags, &rl->rgi, es); + add_route (r, tt, flags, &rl->rgi, es); } - rl->routes_added = true; + rl->iflags |= RL_ROUTES_ADDED; + } + if (rl6 && !rl6->routes_added) + { + int i; + + for (i = 0; i < rl6->n; ++i) + { + 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; } } void -delete_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es) +delete_routes (struct route_list *rl, struct route_ipv6_list *rl6, + const struct tuntap *tt, unsigned int flags, const struct env_set *es) { - if (rl->routes_added) + if ( rl && rl->iflags & RL_ROUTES_ADDED ) { int i; for (i = rl->n - 1; i >= 0; --i) { - const struct route *r = &rl->routes[i]; - delete_route (r, tt, flags, es); + struct route * r = &rl->routes[i]; + delete_route (r, tt, flags, &rl->rgi, es); } - rl->routes_added = false; + rl->iflags &= ~RL_ROUTES_ADDED; } - undo_redirect_default_route_to_vpn (rl, tt, flags, es); - clear_route_list (rl); + undo_redirect_default_route_to_vpn (rl, tt, flags, es); + + if ( rl ) + { + clear_route_list (rl); + } + + if ( rl6 && rl6->routes_added ) + { + int i; + for (i = rl6->n - 1; i >= 0; --i) + { + const struct route_ipv6 *r6 = &rl6->routes_ipv6[i]; + delete_route_ipv6 (r6, tt, flags, es); + } + rl6->routes_added = false; + } + + if ( rl6 ) + { + clear_route_ipv6_list (rl6); + } } #ifdef ENABLE_DEBUG @@ -785,13 +1122,41 @@ print_route_options (const struct route_option_list *rol, print_route_option (&rol->routes[i], level); } +void +print_default_gateway(const int msglevel, const struct route_gateway_info *rgi) +{ + struct gc_arena gc = gc_new (); + if (rgi->flags & RGI_ADDR_DEFINED) + { + struct buffer out = alloc_buf_gc (256, &gc); + buf_printf (&out, "ROUTE_GATEWAY"); + if (rgi->flags & RGI_ON_LINK) + buf_printf (&out, " ON_LINK"); + else + 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 + if (rgi->flags & RGI_IFACE_DEFINED) + buf_printf (&out, " I=%u", (unsigned int)rgi->adapter_index); +#else + if (rgi->flags & RGI_IFACE_DEFINED) + buf_printf (&out, " IFACE=%s", rgi->iface); +#endif + if (rgi->flags & RGI_HWADDR_DEFINED) + buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi->hwaddr, 6, 0, 1, ":", &gc)); + msg (msglevel, "%s", BSTR (&out)); + } + gc_free (&gc); +} + #endif static void print_route (const struct route *r, int level) { struct gc_arena gc = gc_new (); - if (r->defined) + if (r->flags & RT_DEFINED) msg (level, "%s", route_string (r, &gc)); gc_free (&gc); } @@ -808,13 +1173,13 @@ static void setenv_route (struct env_set *es, const struct route *r, int i) { struct gc_arena gc = gc_new (); - if (r->defined) + if (r->flags & RT_DEFINED) { setenv_route_addr (es, "network", r->network, i); setenv_route_addr (es, "netmask", r->netmask, i); setenv_route_addr (es, "gateway", r->gateway, i); - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) { struct buffer name = alloc_buf_gc (256, &gc); buf_printf (&name, "route_metric_%d", i); @@ -832,8 +1197,101 @@ setenv_routes (struct env_set *es, const struct route_list *rl) setenv_route (es, &rl->routes[i], i + 1); } +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) + { + struct buffer name1 = alloc_buf_gc( 256, &gc ); + struct buffer val = alloc_buf_gc( 256, &gc ); + struct buffer name2 = alloc_buf_gc( 256, &gc ); + + buf_printf( &name1, "route_ipv6_network_%d", i ); + buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ), + r6->netbits ); + setenv_str( es, BSTR(&name1), BSTR(&val) ); + + buf_printf( &name2, "route_ipv6_gateway_%d", i ); + setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc )); + } + gc_free (&gc); +} +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); +} + +/* + * local_route() determines whether the gateway of a provided host + * route is on the same interface that owns the default gateway. + * It uses the data structure + * returned by get_default_gateway() (struct route_gateway_info) + * to determine this. If the route is local, LR_MATCH is returned. + * When adding routes into the kernel, if LR_MATCH is defined for + * a given route, the route should explicitly reference the default + * gateway interface as the route destination. For example, here + * is an example on Linux that uses LR_MATCH: + * + * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0 + * + * This capability is needed by the "default-gateway block-local" + * directive, to allow client access to the local subnet to be + * blocked but still allow access to the local default gateway. + */ + +/* local_route() return values */ +#define LR_NOMATCH 0 /* route is not local */ +#define LR_MATCH 1 /* route is local */ +#define LR_ERROR 2 /* caller should abort adding route */ + +static int +local_route (in_addr_t network, + in_addr_t netmask, + in_addr_t gateway, + const struct route_gateway_info *rgi) +{ + /* set LR_MATCH on local host routes */ + const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED|RGI_IFACE_DEFINED); + if (rgi + && (rgi->flags & rgi_needed) == rgi_needed + && gateway == rgi->gateway.addr + && netmask == 0xFFFFFFFF) + { + if (((network ^ rgi->gateway.addr) & rgi->gateway.netmask) == 0) + return LR_MATCH; + else + { + /* examine additional subnets on gateway interface */ + size_t i; + for (i = 0; i < rgi->n_addrs; ++i) + { + const struct route_gateway_address *gwa = &rgi->addrs[i]; + if (((network ^ gwa->addr) & gwa->netmask) == 0) + return LR_MATCH; + } + } + } + return LR_NOMATCH; +} + +/* Return true if the "on-link" form of the route should be used. This is when the gateway for a + a route is specified as an interface rather than an address. */ +static inline bool +is_on_link (const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi) +{ + return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK))); +} + void -add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es) +add_route (struct route *r, + const struct tuntap *tt, + unsigned int flags, + const struct route_gateway_info *rgi, /* may be NULL */ + const struct env_set *es) { struct gc_arena gc; struct argv argv; @@ -841,8 +1299,9 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s const char *netmask; const char *gateway; bool status = false; + int is_local_route; - if (!r->defined) + if (!(r->flags & RT_DEFINED)) return; gc_init (&gc); @@ -852,78 +1311,84 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s netmask = print_in_addr_t (r->netmask, 0, &gc); gateway = print_in_addr_t (r->gateway, 0, &gc); - /* - * Filter out routes which are essentially no-ops - */ - if (r->network == r->gateway && r->netmask == 0xFFFFFFFF) - { - msg (M_INFO, PACKAGE_NAME " ROUTE: omitted no-op route: %s/%s -> %s", - network, netmask, gateway); - goto done; - } + is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); + if (is_local_route == LR_ERROR) + goto done; #if defined(TARGET_LINUX) -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE + /* FIXME -- add on-link support for ENABLE_IPROUTE */ argv_printf (&argv, "%s route add %s/%d via %s", iproute_path, network, count_netmask_bits(netmask), gateway); - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "metric %d", r->metric); #else - argv_printf (&argv, "%s add -net %s netmask %s gw %s", - ROUTE_PATH, - network, - netmask, - gateway); - if (r->metric_defined) + argv_printf (&argv, "%s add -net %s netmask %s", + ROUTE_PATH, + network, + netmask); + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "metric %d", r->metric); -#endif /*CONFIG_FEATURE_IPROUTE*/ + if (is_on_link (is_local_route, flags, rgi)) + argv_printf_cat (&argv, "dev %s", rgi->iface); + else + argv_printf_cat (&argv, "gw %s", gateway); + +#endif /*ENABLE_IPROUTE*/ argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed"); #elif defined (WIN32) + { + DWORD ai = TUN_ADAPTER_INDEX_INVALID; + argv_printf (&argv, "%s%sc ADD %s MASK %s %s", + get_win_sys_path(), + WIN_ROUTE_PATH_SUFFIX, + network, + netmask, + gateway); + if (r->flags & RT_METRIC_DEFINED) + argv_printf_cat (&argv, "METRIC %d", r->metric); + if (is_on_link (is_local_route, flags, rgi)) + { + ai = rgi->adapter_index; + argv_printf_cat (&argv, "IF %u", (unsigned int)ai); + } - argv_printf (&argv, "%s%sc ADD %s MASK %s %s", - get_win_sys_path(), - WIN_ROUTE_PATH_SUFFIX, - network, - netmask, - gateway); - if (r->metric_defined) - argv_printf_cat (&argv, "METRIC %d", r->metric); - - argv_msg (D_ROUTE, &argv); + argv_msg (D_ROUTE, &argv); - if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI) - { - status = add_route_ipapi (r, tt); - msg (D_ROUTE, "Route addition via IPAPI %s", status ? "succeeded" : "failed"); - } - else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE) - { - netcmd_semaphore_lock (); - status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed"); - netcmd_semaphore_release (); - } - else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE) - { - status = add_route_ipapi (r, tt); - msg (D_ROUTE, "Route addition via IPAPI %s [adaptive]", status ? "succeeded" : "failed"); - if (!status) - { - msg (D_ROUTE, "Route addition fallback to route.exe"); - netcmd_semaphore_lock (); - status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed [adaptive]"); - netcmd_semaphore_release (); - } - } - else - { - ASSERT (0); - } + 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"); + } + else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE) + { + netcmd_semaphore_lock (); + status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed"); + netcmd_semaphore_release (); + } + else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE) + { + status = add_route_ipapi (r, tt, ai); + msg (D_ROUTE, "Route addition via IPAPI %s [adaptive]", status ? "succeeded" : "failed"); + if (!status) + { + msg (D_ROUTE, "Route addition fallback to route.exe"); + netcmd_semaphore_lock (); + status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed [adaptive]"); + netcmd_semaphore_release (); + } + } + else + { + ASSERT (0); + } + } #elif defined (TARGET_SOLARIS) @@ -932,13 +1397,17 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s argv_printf (&argv, "%s add", ROUTE_PATH); +#if 0 + if (r->flags & RT_METRIC_DEFINED) + argv_printf_cat (&argv, "-rtt %d", r->metric); +#endif + argv_printf_cat (&argv, "%s -netmask %s %s", network, netmask, gateway); - if (r->metric_defined) - argv_printf_cat (&argv, "%d", r->metric); + /* FIXME -- add on-link support for Solaris */ argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed"); @@ -949,7 +1418,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s ROUTE_PATH); #if 0 - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "-rtt %d", r->metric); #endif @@ -958,6 +1427,8 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s gateway, netmask); + /* FIXME -- add on-link support for FreeBSD */ + argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route add command failed"); @@ -967,7 +1438,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s ROUTE_PATH); #if 0 - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "-rtt %d", r->metric); #endif @@ -976,6 +1447,8 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s gateway, netmask); + /* FIXME -- add on-link support for Dragonfly */ + argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route add command failed"); @@ -985,14 +1458,26 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s ROUTE_PATH); #if 0 - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "-rtt %d", r->metric); #endif - argv_printf_cat (&argv, "-net %s %s %s", - network, - gateway, - netmask); + if (is_on_link (is_local_route, flags, rgi)) + { + /* Mac OS X route syntax for ON_LINK: + route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */ + argv_printf_cat (&argv, "-cloning -net %s -netmask %s -interface %s", + network, + netmask, + rgi->iface); + } + else + { + argv_printf_cat (&argv, "-net %s %s %s", + network, + gateway, + netmask); + } argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: OS X route add command failed"); @@ -1003,7 +1488,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s ROUTE_PATH); #if 0 - if (r->metric_defined) + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "-rtt %d", r->metric); #endif @@ -1012,6 +1497,8 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s gateway, netmask); + /* FIXME -- add on-link support for OpenBSD/NetBSD */ + argv_msg (D_ROUTE, &argv); status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed"); @@ -1020,21 +1507,237 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s #endif done: - r->defined = status; + if (status) + r->flags |= RT_ADDED; + else + r->flags &= ~RT_ADDED; + argv_reset (&argv); + gc_free (&gc); +} + + +static const char * +print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits, + struct gc_arena * gc) +{ + /* 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; + + while( byte >= 0 && bits_to_clear > 0 ) + { + if ( bits_to_clear >= 8 ) + { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; } + else + { network_copy.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; + + const char *network; + const char *gateway; + bool status = false; + const char *device = tt->actual_name; + + bool gateway_needed = false; + + if (!r6->defined) + return; + + gc_init (&gc); + argv_init (&argv); + + network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc); + gateway = print_in6_addr( r6->gateway, 0, &gc); + + if ( !tt->ipv6 ) + { + msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s", + network, r6->netbits, device ); + return; + } + + msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s", + network, r6->netbits, gateway, r6->metric, device ); + + /* + * Filter out routes which are essentially no-ops + * (not currently done for IPv6) + */ + + /* On "tun" interface, we never set a gateway if the operating system + * can do "route to interface" - it does not add value, as the target + * dev already fully qualifies the route destination on point-to-point + * interfaces. OTOH, on "tap" interface, we must always set the + * gateway unless the route is to be an on-link network + */ + if ( tt->type == DEV_TYPE_TAP && + !(r6->metric_defined && r6->metric == 0 ) ) + { + gateway_needed = true; + } + +#if defined(TARGET_LINUX) +#ifdef ENABLE_IPROUTE + argv_printf (&argv, "%s -6 route add %s/%d dev %s", + iproute_path, + network, + r6->netbits, + device); + if (gateway_needed) + argv_printf_cat (&argv, "via %s", gateway); + if (r6->metric_defined && r6->metric > 0 ) + argv_printf_cat (&argv, " metric %d", r6->metric); + +#else + argv_printf (&argv, "%s -A inet6 add %s/%d dev %s", + ROUTE_PATH, + network, + r6->netbits, + device); + if (gateway_needed) + argv_printf_cat (&argv, "gw %s", gateway); + if (r6->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) + + /* 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 ); + +#if 0 + if (r->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" ); + + 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 (); + +#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 + * "metric 0" - otherwise, the routes will be nicely installed, but + * packets will just disappear somewhere. So we use "0" now... + */ + + argv_printf (&argv, "%s add -inet6 %s/%d %s 0", + ROUTE_PATH, + network, + r6->netbits, + gateway ); + + argv_msg (D_ROUTE, &argv); + status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed"); + +#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) + + argv_printf (&argv, "%s add -inet6 %s/%d", + ROUTE_PATH, + network, + r6->netbits); + + if (gateway_needed) + argv_printf_cat (&argv, "%s", gateway); + else + argv_printf_cat (&argv, "-iface %s", device); + + argv_msg (D_ROUTE, &argv); + status = openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route add -inet6 command failed"); + +#elif defined(TARGET_DARWIN) + + argv_printf (&argv, "%s add -inet6 %s -prefixlen %d", + ROUTE_PATH, + network, r6->netbits ); + + if (gateway_needed) + argv_printf_cat (&argv, "%s", gateway); + else + argv_printf_cat (&argv, "-iface %s", device); + + argv_msg (D_ROUTE, &argv); + status = openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed"); + +#elif defined(TARGET_OPENBSD) + + argv_printf (&argv, "%s add -inet6 %s -prefixlen %d %s", + ROUTE_PATH, + network, r6->netbits, gateway ); + + argv_msg (D_ROUTE, &argv); + status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed"); + +#elif defined(TARGET_NETBSD) + + 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: NetBSD route add -inet6 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; argv_reset (&argv); gc_free (&gc); } static void -delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es) +delete_route (struct route *r, + const struct tuntap *tt, + unsigned int flags, + const struct route_gateway_info *rgi, + const struct env_set *es) { struct gc_arena gc; struct argv argv; const char *network; const char *netmask; const char *gateway; + int is_local_route; - if (!r->defined) + if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED)) return; gc_init (&gc); @@ -1044,20 +1747,23 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags netmask = print_in_addr_t (r->netmask, 0, &gc); gateway = print_in_addr_t (r->gateway, 0, &gc); + is_local_route = local_route(r->network, r->netmask, r->gateway, rgi); + if (is_local_route == LR_ERROR) + goto done; + #if defined(TARGET_LINUX) -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE argv_printf (&argv, "%s route del %s/%d", iproute_path, network, count_netmask_bits(netmask)); #else - argv_printf (&argv, "%s del -net %s netmask %s", - ROUTE_PATH, - network, - netmask); -#endif /*CONFIG_FEATURE_IPROUTE*/ - if (r->metric_defined) + ROUTE_PATH, + network, + netmask); +#endif /*ENABLE_IPROUTE*/ + if (r->flags & RT_METRIC_DEFINED) argv_printf_cat (&argv, "metric %d", r->metric); argv_msg (D_ROUTE, &argv); openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed"); @@ -1136,11 +1842,22 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags #elif defined(TARGET_DARWIN) - argv_printf (&argv, "%s delete -net %s %s %s", - ROUTE_PATH, - network, - gateway, - netmask); + if (is_on_link (is_local_route, flags, rgi)) + { + argv_printf (&argv, "%s delete -cloning -net %s -netmask %s -interface %s", + ROUTE_PATH, + network, + netmask, + rgi->iface); + } + else + { + argv_printf (&argv, "%s delete -net %s %s %s", + ROUTE_PATH, + network, + gateway, + netmask); + } argv_msg (D_ROUTE, &argv); openvpn_execve_check (&argv, es, 0, "ERROR: OS X route delete command failed"); @@ -1160,6 +1877,170 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags 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 + done: + r->flags &= ~RT_ADDED; + argv_reset (&argv); + gc_free (&gc); +} + +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; + const char *network; + const char *gateway; + const char *device = tt->actual_name; + bool gateway_needed = false; + + if (!r6->defined) + return; + + gc_init (&gc); + argv_init (&argv); + + network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc); + gateway = print_in6_addr( r6->gateway, 0, &gc); + + if ( !tt->ipv6 ) + { + msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s", + network, r6->netbits, device ); + return; + } + + msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits ); + + /* if we used a gateway on "add route", we also need to specify it on + * delete, otherwise some OSes will refuse to delete the route + */ + if ( tt->type == DEV_TYPE_TAP && + !(r6->metric_defined && r6->metric == 0 ) ) + { + gateway_needed = true; + } + + +#if defined(TARGET_LINUX) +#ifdef ENABLE_IPROUTE + argv_printf (&argv, "%s -6 route del %s/%d dev %s", + iproute_path, + network, + r6->netbits, + device); + if (gateway_needed) + argv_printf_cat (&argv, "via %s", gateway); +#else + argv_printf (&argv, "%s -A inet6 del %s/%d dev %s", + ROUTE_PATH, + network, + r6->netbits, + device); + if (gateway_needed) + argv_printf_cat (&argv, "gw %s", gateway); + if (r6->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) + + /* 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 ); + +#if 0 + if (r->metric_defined) + argv_printf_cat (&argv, "METRIC %d", r->metric); +#endif + + argv_msg (D_ROUTE, &argv); + + netcmd_semaphore_lock (); + openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add 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, + network, + r6->netbits, + gateway ); + + argv_msg (D_ROUTE, &argv); + openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed"); + +#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) + + argv_printf (&argv, "%s delete -inet6 %s/%d", + ROUTE_PATH, + network, + r6->netbits ); + + if (gateway_needed) + argv_printf_cat (&argv, "%s", gateway); + else + argv_printf_cat (&argv, "-iface %s", device); + + argv_msg (D_ROUTE, &argv); + openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed"); + +#elif defined(TARGET_DARWIN) + + argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d", + ROUTE_PATH, + network, r6->netbits ); + + if (gateway_needed) + argv_printf_cat (&argv, "%s", gateway); + else + argv_printf_cat (&argv, "-iface %s", device); + + argv_msg (D_ROUTE, &argv); + openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed"); + +#elif defined(TARGET_OPENBSD) + + argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d %s", + ROUTE_PATH, + network, r6->netbits, gateway ); + + argv_msg (D_ROUTE, &argv); + openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed"); + +#elif defined(TARGET_NETBSD) + + 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: NetBSD route delete -inet6 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 + argv_reset (&argv); gc_free (&gc); } @@ -1251,7 +2132,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt) for (i = 0; i < rl->n; ++i) test_route_helper (&ret, &count, &good, &ambig, adapters, rl->routes[i].gateway); - if ((rl->flags & RG_ENABLE) && rl->spec.remote_endpoint_defined) + if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT)) test_route_helper (&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint); } } @@ -1272,7 +2153,7 @@ static const MIB_IPFORWARDROW * get_default_gateway_row (const MIB_IPFORWARDTABLE *routes) { struct gc_arena gc = gc_new (); - DWORD lowest_metric = ~0; + DWORD lowest_metric = MAXDWORD; const MIB_IPFORWARDROW *ret = NULL; int i; int best = -1; @@ -1309,36 +2190,48 @@ get_default_gateway_row (const MIB_IPFORWARDTABLE *routes) return ret; } -bool -get_default_gateway (in_addr_t *gw, in_addr_t *netmask) +void +get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); - bool ret_bool = false; const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc); const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc); const MIB_IPFORWARDROW *row = get_default_gateway_row (routes); + DWORD a_index; + const IP_ADAPTER_INFO *ai; + + CLEAR(*rgi); if (row) { - *gw = ntohl (row->dwForwardNextHop); - if (netmask) + rgi->gateway.addr = ntohl (row->dwForwardNextHop); + if (rgi->gateway.addr) { - if (adapter_index_of_ip (adapters, *gw, NULL, netmask) == ~0) - *netmask = ~0; + rgi->flags |= RGI_ADDR_DEFINED; + a_index = adapter_index_of_ip (adapters, rgi->gateway.addr, NULL, &rgi->gateway.netmask); + if (a_index != TUN_ADAPTER_INDEX_INVALID) + { + rgi->adapter_index = a_index; + rgi->flags |= (RGI_IFACE_DEFINED|RGI_NETMASK_DEFINED); + ai = get_adapter (adapters, a_index); + if (ai) + { + memcpy (rgi->hwaddr, ai->Address, 6); + rgi->flags |= RGI_HWADDR_DEFINED; + } + } } - ret_bool = true; } gc_free (&gc); - return ret_bool; } static DWORD windows_route_find_if_index (const struct route *r, const struct tuntap *tt) { struct gc_arena gc = gc_new (); - DWORD ret = ~0; + DWORD ret = TUN_ADAPTER_INDEX_INVALID; int count = 0; const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc); const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter (tt, adapters); @@ -1360,14 +2253,14 @@ windows_route_find_if_index (const struct route *r, const struct tuntap *tt) { msg (M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s", print_in_addr_t (r->gateway, 0, &gc)); - ret = ~0; + ret = TUN_ADAPTER_INDEX_INVALID; } else if (count > 1) { msg (M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)", print_in_addr_t (r->gateway, 0, &gc), count); - ret = ~0; + ret = TUN_ADAPTER_INDEX_INVALID; } dmsg (D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d", @@ -1380,14 +2273,14 @@ windows_route_find_if_index (const struct route *r, const struct tuntap *tt) } bool -add_route_ipapi (const struct route *r, const struct tuntap *tt) +add_route_ipapi (const struct route *r, const struct tuntap *tt, DWORD adapter_index) { struct gc_arena gc = gc_new (); bool ret = false; DWORD status; - const DWORD if_index = windows_route_find_if_index (r, tt); + const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID) ? windows_route_find_if_index (r, tt) : adapter_index; - if (if_index != ~0) + if (if_index != TUN_ADAPTER_INDEX_INVALID) { MIB_IPFORWARDROW fr; CLEAR (fr); @@ -1400,11 +2293,11 @@ add_route_ipapi (const struct route *r, const struct tuntap *tt) fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */ fr.dwForwardAge = 0; fr.dwForwardNextHopAS = 0; - fr.dwForwardMetric1 = r->metric_defined ? r->metric : 1; - fr.dwForwardMetric2 = ~0; - fr.dwForwardMetric3 = ~0; - fr.dwForwardMetric4 = ~0; - fr.dwForwardMetric5 = ~0; + fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1; + fr.dwForwardMetric2 = METRIC_NOT_USED; + fr.dwForwardMetric3 = METRIC_NOT_USED; + fr.dwForwardMetric4 = METRIC_NOT_USED; + fr.dwForwardMetric5 = METRIC_NOT_USED; if ((r->network & r->netmask) != r->network) msg (M_WARN, "Warning: address %s is not a network address in relation to netmask %s", @@ -1461,7 +2354,7 @@ del_route_ipapi (const struct route *r, const struct tuntap *tt) DWORD status; const DWORD if_index = windows_route_find_if_index (r, tt); - if (if_index != ~0) + if (if_index != TUN_ADAPTER_INDEX_INVALID) { MIB_IPFORWARDROW fr; CLEAR (fr); @@ -1531,75 +2424,168 @@ show_routes (int msglev) #elif defined(TARGET_LINUX) -bool -get_default_gateway (in_addr_t *gateway, in_addr_t *netmask) +void +get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); - bool ret = false; - FILE *fp = fopen ("/proc/net/route", "r"); - if (fp) - { - char line[256]; - int count = 0; - int best_count = 0; - unsigned int lowest_metric = ~0; - in_addr_t best_gw = 0; - while (fgets (line, sizeof (line), fp) != NULL) + int sd = -1; + char best_name[16]; + best_name[0] = 0; + + CLEAR(*rgi); + + /* get default gateway IP addr */ + { + FILE *fp = fopen ("/proc/net/route", "r"); + if (fp) + { + char line[256]; + int count = 0; + unsigned int lowest_metric = UINT_MAX; + in_addr_t best_gw = 0; + bool found = false; + while (fgets (line, sizeof (line), fp) != NULL) + { + if (count) + { + unsigned int net_x = 0; + unsigned int mask_x = 0; + unsigned int gw_x = 0; + unsigned int metric = 0; + unsigned int flags = 0; + char name[16]; + name[0] = 0; + const int np = sscanf (line, "%15s\t%x\t%x\t%x\t%*s\t%*s\t%d\t%x", + name, + &net_x, + &gw_x, + &flags, + &metric, + &mask_x); + if (np == 6 && (flags & IFF_UP)) + { + const in_addr_t net = ntohl (net_x); + const in_addr_t mask = ntohl (mask_x); + const in_addr_t gw = ntohl (gw_x); + + if (!net && !mask && metric < lowest_metric) + { + found = true; + best_gw = gw; + strcpy (best_name, name); + lowest_metric = metric; + } + } + } + ++count; + } + fclose (fp); + + if (found) + { + rgi->gateway.addr = best_gw; + rgi->flags |= RGI_ADDR_DEFINED; + if (!rgi->gateway.addr && best_name[0]) + rgi->flags |= RGI_ON_LINK; + } + } + } + + /* scan adapter list */ + if (rgi->flags & RGI_ADDR_DEFINED) + { + struct ifreq *ifr, *ifend; + in_addr_t addr, netmask; + struct ifreq ifreq; + struct ifconf ifc; + struct ifreq ifs[20]; /* Maximum number of interfaces to scan */ + + if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + msg (M_WARN, "GDG: socket() failed"); + goto done; + } + ifc.ifc_len = sizeof (ifs); + ifc.ifc_req = ifs; + if (ioctl (sd, SIOCGIFCONF, &ifc) < 0) { - if (count) + msg (M_WARN, "GDG: ioctl(SIOCGIFCONF) failed"); + goto done; + } + + /* scan through interface list */ + ifend = ifs + (ifc.ifc_len / sizeof (struct ifreq)); + for (ifr = ifc.ifc_req; ifr < ifend; ifr++) + { + if (ifr->ifr_addr.sa_family == AF_INET) { - unsigned int net_x = 0; - unsigned int mask_x = 0; - unsigned int gw_x = 0; - unsigned int metric = 0; - const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x", - &net_x, - &gw_x, - &metric, - &mask_x); - if (np == 4) + /* get interface addr */ + addr = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr); + + /* get interface name */ + strncpynt (ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); + + /* check that the interface is up */ + if (ioctl (sd, SIOCGIFFLAGS, &ifreq) < 0) + continue; + if (!(ifreq.ifr_flags & IFF_UP)) + continue; + + if (rgi->flags & RGI_ON_LINK) { - const in_addr_t net = ntohl (net_x); - const in_addr_t mask = ntohl (mask_x); - const in_addr_t gw = ntohl (gw_x); - - dmsg (D_ROUTE_DEBUG, "GDG: route[%d] %s/%s/%s m=%u", - count, - print_in_addr_t ((in_addr_t) net, 0, &gc), - print_in_addr_t ((in_addr_t) mask, 0, &gc), - print_in_addr_t ((in_addr_t) gw, 0, &gc), - metric); - - if (!net && !mask && metric < lowest_metric) + /* check that interface name of current interface + matches interface name of best default route */ + if (strcmp(ifreq.ifr_name, best_name)) + continue; +#if 0 + /* if point-to-point link, use remote addr as route gateway */ + if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl (sd, SIOCGIFDSTADDR, &ifreq) >= 0) { - best_gw = gw; - lowest_metric = metric; - best_count = count; + rgi->gateway.addr = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr); + if (rgi->gateway.addr) + rgi->flags &= ~RGI_ON_LINK; } +#endif + } + else + { + /* get interface netmask */ + if (ioctl (sd, SIOCGIFNETMASK, &ifreq) < 0) + continue; + netmask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr); + + /* check that interface matches default route */ + if (((rgi->gateway.addr ^ addr) & netmask) != 0) + continue; + + /* save netmask */ + rgi->gateway.netmask = netmask; + rgi->flags |= RGI_NETMASK_DEFINED; } - } - ++count; - } - fclose (fp); - if (best_gw) - { - *gateway = best_gw; - if (netmask) - { - *netmask = 0xFFFFFF00; /* FIXME -- get the real netmask of the adapter containing the default gateway */ + /* save iface name */ + strncpynt (rgi->iface, ifreq.ifr_name, sizeof(rgi->iface)); + rgi->flags |= RGI_IFACE_DEFINED; + + /* now get the hardware address. */ + memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); + if (ioctl (sd, SIOCGIFHWADDR, &ifreq) < 0) + { + msg (M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name); + goto done; + } + memcpy (rgi->hwaddr, &ifreq.ifr_hwaddr.sa_data, 6); + rgi->flags |= RGI_HWADDR_DEFINED; + + break; } - ret = true; } - - dmsg (D_ROUTE_DEBUG, "GDG: best=%s[%d] lm=%u", - print_in_addr_t ((in_addr_t) best_gw, 0, &gc), - best_count, - (unsigned int)lowest_metric); } + done: + if (sd >= 0) + close (sd); gc_free (&gc); - return ret; } #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY) @@ -1663,8 +2649,11 @@ struct { #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -bool -get_default_gateway (in_addr_t *ret, in_addr_t *netmask) +/* + * FIXME -- add support for netmask, hwaddr, and iface + */ +void +get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); int s, seq, l, pid, rtm_addrs, i; @@ -1682,6 +2671,8 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) #define rtm m_rtmsg.m_rtm + CLEAR(*rgi); + pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; @@ -1713,7 +2704,7 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) warn("writing to routing socket"); gc_free (&gc); close(s); - return false; + return; } do { @@ -1737,30 +2728,20 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) else { gc_free (&gc); - return false; + return; } if (gate != NULL ) { - *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); -#if 0 - msg (M_INFO, "gw %s", - print_in_addr_t ((in_addr_t) *ret, 0, &gc)); -#endif - - if (netmask) - { - *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway - } + rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); + rgi->flags |= RGI_ADDR_DEFINED; gc_free (&gc); - return true; } else { gc_free (&gc); - return false; } } @@ -1769,71 +2750,16 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <net/route.h> +#include <net/if_dl.h> -/* all of this is taken from <net/route.h> in Darwin */ -#define RTA_DST 0x1 -#define RTA_GATEWAY 0x2 -#define RTA_NETMASK 0x4 - -#define RTM_GET 0x4 -#define RTM_VERSION 5 - -#define RTF_UP 0x1 -#define RTF_GATEWAY 0x2 - -/* - * These numbers are used by reliable protocols for determining - * retransmission behavior and are included in the routing structure. - */ -struct rt_metrics { - u_long rmx_locks; /* Kernel must leave these values alone */ - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_hopcount; /* max hops expected */ - u_long rmx_expire; /* lifetime for route, e.g. redirect */ - u_long rmx_recvpipe; /* inbound delay-bandwidth product */ - u_long rmx_sendpipe; /* outbound delay-bandwidth product */ - u_long rmx_ssthresh; /* outbound gateway buffer limit */ - u_long rmx_rtt; /* estimated round trip time */ - u_long rmx_rttvar; /* estimated rtt variance */ - u_long rmx_pksent; /* packets sent using this route */ - u_long rmx_filler[4]; /* will be used for T/TCP later */ -}; - -/* - * Structures for routing messages. - */ -struct rt_msghdr { - u_short rtm_msglen; /* to skip over non-understood messages */ - u_char rtm_version; /* future binary compatibility */ - u_char rtm_type; /* message type */ - u_short rtm_index; /* index for associated ifp */ - int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ - int rtm_addrs; /* bitmask identifying sockaddrs in msg */ - pid_t rtm_pid; /* identify sender */ - int rtm_seq; /* for sender to identify action */ - int rtm_errno; /* why failed */ - int rtm_use; /* from rtentry */ - u_long rtm_inits; /* which metrics we are initializing */ - struct rt_metrics rtm_rmx; /* metrics themselves */ -}; - -struct { +struct rtmsg { struct rt_msghdr m_rtm; char m_space[512]; -} m_rtmsg; +}; #define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - -bool -get_default_gateway (in_addr_t *ret, in_addr_t *netmask) -{ - struct gc_arena gc = gc_new (); - int s, seq, l, pid, rtm_addrs, i; - struct sockaddr so_dst, so_mask; - char *cp = m_rtmsg.m_space; - struct sockaddr *gate = NULL, *sa; - struct rt_msghdr *rtm_aux; + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t)) #define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ @@ -1842,12 +2768,30 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) -#define rtm m_rtmsg.m_rtm +#define max(a,b) ((a) > (b) ? (a) : (b)) + +void +get_default_gateway (struct route_gateway_info *rgi) +{ + struct gc_arena gc = gc_new (); + struct rtmsg m_rtmsg; + int sockfd = -1; + int seq, l, pid, rtm_addrs, i; + struct sockaddr so_dst, so_mask; + char *cp = m_rtmsg.m_space; + struct sockaddr *gate = NULL, *ifp = NULL, *sa; + struct rt_msghdr *rtm_aux; + +# define rtm m_rtmsg.m_rtm + CLEAR(*rgi); + + /* setup data to send to routing socket */ pid = getpid(); seq = 0; - rtm_addrs = RTA_DST | RTA_NETMASK; + rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP; + bzero(&m_rtmsg, sizeof(m_rtmsg)); bzero(&so_dst, sizeof(so_dst)); bzero(&so_mask, sizeof(so_mask)); bzero(&rtm, sizeof(struct rt_msghdr)); @@ -1868,64 +2812,148 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - s = socket(PF_ROUTE, SOCK_RAW, 0); - - 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, "ROUTE: problem writing to routing socket"); - gc_free (&gc); - close(s); - return false; + msg (M_WARN, "GDG: socket #1 failed"); + goto done; + } + if (write(sockfd, (char *)&m_rtmsg, l) < 0) + { + msg (M_WARN, "GDG: problem writing to routing socket"); + goto done; } - do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); + l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - - close(s); + close(sockfd); + sockfd = -1; + /* extract return data from routing socket */ 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 (rtm_aux->rtm_addrs) { - gc_free (&gc); - return false; + 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 + goto done; - + /* get gateway addr and interface name */ if (gate != NULL ) { - *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); -#if 0 - msg (M_INFO, "gw %s", - print_in_addr_t ((in_addr_t) *ret, 0, &gc)); -#endif + /* get default gateway addr */ + rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); + if (rgi->gateway.addr) + rgi->flags |= RGI_ADDR_DEFINED; - if (netmask) + if (ifp) { - *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway + /* 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); + rgi->iface[adl->sdl_nlen] = '\0'; + rgi->flags |= RGI_IFACE_DEFINED; + } } - - gc_free (&gc); - return true; } - else + + /* get netmask of interface that owns default gateway */ + if (rgi->flags & RGI_IFACE_DEFINED) { + struct ifreq ifr; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + { + msg (M_WARN, "GDG: socket #2 failed"); + goto done; + } + + CLEAR(ifr); + ifr.ifr_addr.sa_family = AF_INET; + strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ); + + if (ioctl(sockfd, SIOCGIFNETMASK, (char *)&ifr) < 0) + { + msg (M_WARN, "GDG: ioctl #1 failed"); + goto done; + } + close(sockfd); + sockfd = -1; + + rgi->gateway.netmask = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr); + rgi->flags |= RGI_NETMASK_DEFINED; + } + + /* try to read MAC addr associated with interface that owns default gateway */ + if (rgi->flags & RGI_IFACE_DEFINED) { - gc_free (&gc); - return false; + struct ifconf ifc; + struct ifreq *ifr; + const int bufsize = 4096; + char *buffer; + + buffer = (char *) gc_malloc (bufsize, true, &gc); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + { + msg (M_WARN, "GDG: socket #3 failed"); + goto done; + } + + ifc.ifc_len = bufsize; + ifc.ifc_buf = buffer; + + if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0) + { + msg (M_WARN, "GDG: ioctl #2 failed"); + goto done; + } + close(sockfd); + sockfd = -1; + + for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); ) + { + ifr = (struct ifreq *)cp; + const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len); + if (!ifr->ifr_addr.sa_family) + break; + if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ)) + { + if (ifr->ifr_addr.sa_family == AF_LINK) + { + struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr; + memcpy(rgi->hwaddr, LLADDR(sdl), 6); + rgi->flags |= RGI_HWADDR_DEFINED; + } + } + cp += len; + } } + + done: + if (sockfd >= 0) + close(sockfd); + gc_free (&gc); } +#undef max + #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) #include <sys/types.h> @@ -1986,8 +3014,11 @@ struct { #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -bool -get_default_gateway (in_addr_t *ret, in_addr_t *netmask) +/* + * FIXME -- add support for netmask, hwaddr, and iface + */ +void +get_default_gateway (struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); int s, seq, l, rtm_addrs, i; @@ -2006,6 +3037,8 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) #define rtm m_rtmsg.m_rtm + CLEAR(*rgi); + pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; @@ -2037,7 +3070,7 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) warn("writing to routing socket"); gc_free (&gc); close(s); - return false; + return; } do { @@ -2061,39 +3094,53 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask) else { gc_free (&gc); - return false; + return; } if (gate != NULL ) { - *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); -#if 0 - msg (M_INFO, "gw %s", - print_in_addr_t ((in_addr_t) *ret, 0, &gc)); -#endif - - if (netmask) - { - *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway - } + rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); + rgi->flags |= RGI_ADDR_DEFINED; gc_free (&gc); - return true; } else { gc_free (&gc); - return false; } } #else -bool -get_default_gateway (in_addr_t *ret, in_addr_t *netmask) /* PLATFORM-SPECIFIC */ +/* + * This is a platform-specific method that returns data about + * the current default gateway. Return data is placed into + * a struct route_gateway_info object provided by caller. The + * implementation should CLEAR the structure before adding + * data to it. + * + * Data returned includes: + * 1. default gateway address (rgi->gateway.addr) + * 2. netmask of interface that owns default gateway + * (rgi->gateway.netmask) + * 3. hardware address (i.e. MAC address) of interface that owns + * default gateway (rgi->hwaddr) + * 4. interface name (or adapter index on Windows) that owns default + * gateway (rgi->iface or rgi->adapter_index) + * 5. an array of additional address/netmask pairs defined by + * interface that owns default gateway (rgi->addrs with length + * given in rgi->n_addrs) + * + * The flags RGI_x_DEFINED may be used to indicate which of the data + * members were successfully returned (set in rgi->flags). All of + * the data members are optional, however certain OpenVPN functionality + * may be disabled by missing items. + */ +void +get_default_gateway (struct route_gateway_info *rgi) { - return false; + CLEAR(*rgi); } #endif @@ -2133,18 +3180,8 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi static void add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr) { - if (test_local_addr(addr) == TLA_NONLOCAL && addr != 0 && addr != ~0) { - int i; - for (i = 0; i < rb->n_bypass; ++i) - { - if (addr == rb->bypass[i]) /* avoid duplicates */ - return; - } - if (rb->n_bypass < N_ROUTE_BYPASS) - { - rb->bypass[rb->n_bypass++] = addr; - } - } + if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST) + add_bypass_address (rb, addr); } static void @@ -2203,155 +3240,6 @@ get_bypass_addresses (struct route_bypass *rb, const unsigned int flags) /* PLA #endif -#if AUTO_USERID || defined(ENABLE_PUSH_PEER_INFO) - -#if defined(TARGET_LINUX) - -bool -get_default_gateway_mac_addr (unsigned char *macaddr) -{ - struct ifreq *ifr, *ifend; - in_addr_t ina, mask; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[20]; // Maximum number of interfaces to scan - int sd = -1; - in_addr_t gwip = 0; - bool ret = false; - - if (!get_default_gateway (&gwip, NULL)) - { - msg (M_WARN, "GDGMA: get_default_gateway failed"); - goto err; - } - - if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) - { - msg (M_WARN, "GDGMA: socket() failed"); - goto err; - } - - ifc.ifc_len = sizeof (ifs); - ifc.ifc_req = ifs; - if (ioctl (sd, SIOCGIFCONF, &ifc) < 0) - { - msg (M_WARN, "GDGMA: ioctl(SIOCGIFCONF) failed"); - goto err; - } - - /* scan through interface list */ - ifend = ifs + (ifc.ifc_len / sizeof (struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) - { - if (ifr->ifr_addr.sa_family == AF_INET) - { - ina = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr); - strncpynt (ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); - - dmsg (D_AUTO_USERID, "GDGMA: %s", ifreq.ifr_name); - - /* check that the interface is up, and not point-to-point or loopback */ - if (ioctl (sd, SIOCGIFFLAGS, &ifreq) < 0) - { - dmsg (D_AUTO_USERID, "GDGMA: SIOCGIFFLAGS(%s) failed", ifreq.ifr_name); - continue; - } - - if ((ifreq.ifr_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP) - { - dmsg (D_AUTO_USERID, "GDGMA: interface %s is down or loopback", ifreq.ifr_name); - continue; - } - - /* get interface netmask and check for correct subnet */ - if (ioctl (sd, SIOCGIFNETMASK, &ifreq) < 0) - { - dmsg (D_AUTO_USERID, "GDGMA: SIOCGIFNETMASK(%s) failed", ifreq.ifr_name); - continue; - } - - mask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr); - if (((gwip ^ ina) & mask) != 0) - { - dmsg (D_AUTO_USERID, "GDGMA: gwip=0x%08x ina=0x%08x mask=0x%08x", - (unsigned int)gwip, - (unsigned int)ina, - (unsigned int)mask); - continue; - } - break; - } - } - if (ifr >= ifend) - { - msg (M_WARN, "GDGMA: couldn't find gw interface"); - goto err; - } - - /* now get the hardware address. */ - memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); - if (ioctl (sd, SIOCGIFHWADDR, &ifreq) < 0) - { - msg (M_WARN, "GDGMA: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name); - goto err; - } - - memcpy (macaddr, &ifreq.ifr_hwaddr.sa_data, 6); - ret = true; - - err: - if (sd >= 0) - close (sd); - return ret; -} - -#elif defined(WIN32) - -bool -get_default_gateway_mac_addr (unsigned char *macaddr) -{ - struct gc_arena gc = gc_new (); - const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc); - in_addr_t gwip = 0; - DWORD a_index; - const IP_ADAPTER_INFO *ai; - - if (!get_default_gateway (&gwip, NULL)) - { - msg (M_WARN, "GDGMA: get_default_gateway failed"); - goto err; - } - - a_index = adapter_index_of_ip (adapters, gwip, NULL, NULL); - ai = get_adapter (adapters, a_index); - - if (!ai) - { - msg (M_WARN, "GDGMA: couldn't find gw interface"); - goto err; - } - - memcpy (macaddr, ai->Address, 6); - - gc_free (&gc); - return true; - - err: - gc_free (&gc); - return false; -} - -#else - -bool -get_default_gateway_mac_addr (unsigned char *macaddr) /* PLATFORM-SPECIFIC */ -{ - return false; -} - -#endif -#endif /* AUTO_USERID */ - /* * Test if addr is reachable via a local interface (return ILA_LOCAL), * or if it needs to be routed via the default gateway (return @@ -2364,7 +3252,7 @@ get_default_gateway_mac_addr (unsigned char *macaddr) /* PLATFORM-SPECIFIC */ #if defined(WIN32) int -test_local_addr (const in_addr_t addr) +test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi) { struct gc_arena gc = gc_new (); const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */ @@ -2394,10 +3282,16 @@ test_local_addr (const in_addr_t addr) #else - int -test_local_addr (const in_addr_t addr) /* PLATFORM-SPECIFIC */ +test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */ { + if (rgi) + { + if (local_route (addr, 0xFFFFFFFF, rgi->gateway.addr, rgi)) + return TLA_LOCAL; + else + return TLA_NONLOCAL; + } return TLA_NOT_IMPLEMENTED; } diff --git a/route.h b/src/openvpn/route.h index c5cbb7c..e63db59 100644 --- a/route.h +++ b/src/openvpn/route.h @@ -29,6 +29,7 @@ #ifndef ROUTE_H #define ROUTE_H +#include "basic.h" #include "tun.h" #include "misc.h" @@ -45,9 +46,10 @@ #endif /* - * Route add flags (must stay clear of ROUTE_METHOD bits) + * Route add/delete flags (must stay clear of ROUTE_METHOD bits) */ -#define ROUTE_DELETE_FIRST 4 +#define ROUTE_DELETE_FIRST (1<<2) +#define ROUTE_REF_GW (1<<3) struct route_bypass { @@ -58,15 +60,17 @@ struct route_bypass struct route_special_addr { + /* bits indicating which members below are defined */ +# define RTSA_REMOTE_ENDPOINT (1<<0) +# define RTSA_REMOTE_HOST (1<<1) +# define RTSA_DEFAULT_METRIC (1<<2) + unsigned int flags; + in_addr_t remote_endpoint; - bool remote_endpoint_defined; - in_addr_t net_gateway; - bool net_gateway_defined; in_addr_t remote_host; - bool remote_host_defined; + int remote_host_local; /* TLA_x value */ struct route_bypass bypass; int default_metric; - bool default_metric_defined; }; struct route_option { @@ -84,30 +88,106 @@ struct route_option { #define RG_BYPASS_DNS (1<<4) #define RG_REROUTE_GW (1<<5) #define RG_AUTO_LOCAL (1<<6) +#define RG_BLOCK_LOCAL (1<<7) struct route_option_list { - unsigned int flags; + unsigned int flags; /* RG_x flags */ int capacity; int n; struct route_option routes[EMPTY_ARRAY_SIZE]; }; +struct route_ipv6_option { + 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]; +}; + struct route { - bool defined; +# define RT_DEFINED (1<<0) +# define RT_ADDED (1<<1) +# define RT_METRIC_DEFINED (1<<2) + unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int metric; +}; + +struct route_ipv6 { + bool defined; + struct in6_addr network; + unsigned int netbits; + struct in6_addr gateway; bool metric_defined; int metric; }; -struct route_list { +struct route_ipv6_list { bool routes_added; - struct route_special_addr spec; unsigned int flags; - bool did_redirect_default_gateway; - bool did_local; + 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]; +}; + + +struct route_gateway_address { + in_addr_t addr; + in_addr_t netmask; +}; + +struct route_gateway_info { +# define RGI_ADDR_DEFINED (1<<0) /* set if gateway.addr defined */ +# define RGI_NETMASK_DEFINED (1<<1) /* set if gateway.netmask defined */ +# define RGI_HWADDR_DEFINED (1<<2) /* set if hwaddr is defined */ +# define RGI_IFACE_DEFINED (1<<3) /* set if iface is defined */ +# define RGI_OVERFLOW (1<<4) /* set if more interface addresses than will fit in addrs */ +# define RGI_ON_LINK (1<<5) + 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_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_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) +# define RL_ROUTES_ADDED (1<<2) + unsigned int iflags; + + struct route_special_addr spec; + struct route_gateway_info rgi; + unsigned int flags; /* RG_x flags */ int capacity; int n; struct route routes[EMPTY_ARRAY_SIZE]; @@ -120,15 +200,34 @@ struct iroute { int netbits; struct iroute *next; }; + +struct iroute_ipv6 { + struct in6_addr network; + unsigned int netbits; + struct iroute_ipv6 *next; +}; #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 *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_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); -void add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); +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); + +void add_route (struct route *r, + const struct tuntap *tt, + unsigned int flags, + const struct route_gateway_info *rgi, + const struct env_set *es); void add_route_to_option_list (struct route_option_list *l, const char *network, @@ -136,6 +235,11 @@ void add_route_to_option_list (struct route_option_list *l, const char *gateway, const char *metric); +void add_route_ipv6_to_option_list (struct route_ipv6_option_list *l, + const char *prefix, + const char *gateway, + const char *metric); + bool init_route_list (struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, @@ -143,25 +247,37 @@ bool init_route_list (struct route_list *rl, in_addr_t remote_host, struct env_set *es); -void route_list_add_default_gateway (struct route_list *rl, - struct env_set *es, - const in_addr_t addr); +bool init_route_ipv6_list (struct route_ipv6_list *rl6, + const struct route_ipv6_option_list *opt6, + const char *remote_endpoint, + int default_metric, + struct env_set *es); + +void route_list_add_vpn_gateway (struct route_list *rl, + struct env_set *es, + const in_addr_t addr); void add_routes (struct route_list *rl, + struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es); void delete_routes (struct route_list *rl, + struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es); void setenv_routes (struct env_set *es, const struct route_list *rl); +void setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6); + + bool is_special_addr (const char *addr_str); -bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask); +void get_default_gateway (struct route_gateway_info *rgi); +void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi); /* * Test if addr is reachable via a local interface (return ILA_LOCAL), @@ -172,11 +288,7 @@ bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask); #define TLA_NOT_IMPLEMENTED 0 #define TLA_NONLOCAL 1 #define TLA_LOCAL 2 -int test_local_addr (const in_addr_t addr); - -#if AUTO_USERID || defined(ENABLE_PUSH_PEER_INFO) -bool get_default_gateway_mac_addr (unsigned char *macaddr); -#endif +int test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi); #ifdef ENABLE_DEBUG void print_route_options (const struct route_option_list *rol, @@ -189,7 +301,7 @@ void print_routes (const struct route_list *rl, int level); void show_routes (int msglev); bool test_routes (const struct route_list *rl, const struct tuntap *tt); -bool add_route_ipapi (const struct route *r, const struct tuntap *tt); +bool add_route_ipapi (const struct route *r, const struct tuntap *tt, DWORD adapter_index); bool del_route_ipapi (const struct route *r, const struct tuntap *tt); #else @@ -204,17 +316,23 @@ netbits_to_netmask (const int netbits) const int addrlen = sizeof (in_addr_t) * 8; in_addr_t mask = 0; if (netbits > 0 && netbits <= addrlen) - mask = ~0 << (addrlen-netbits); + mask = IPV4_NETMASK_HOST << (addrlen-netbits); return mask; } static inline bool -route_list_default_gateway_needed (const struct route_list *rl) +route_list_vpn_gateway_needed (const struct route_list *rl) { if (!rl) return false; else - return !rl->spec.remote_endpoint_defined; + return !(rl->spec.flags & RTSA_REMOTE_ENDPOINT); +} + +static inline int +route_did_redirect_default_gateway(const struct route_list *rl) +{ + return rl && BOOL_CAST(rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY); } #endif diff --git a/schedule.c b/src/openvpn/schedule.c index f0482ab..471330f 100644 --- a/schedule.c +++ b/src/openvpn/schedule.c @@ -22,6 +22,12 @@ * 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 P2MP_SERVER diff --git a/schedule.h b/src/openvpn/schedule.h index 71c6d8c..71c6d8c 100644 --- a/schedule.h +++ b/src/openvpn/schedule.h diff --git a/session_id.c b/src/openvpn/session_id.c index 95fa5f7..2e07b54 100644 --- a/session_id.c +++ b/src/openvpn/session_id.c @@ -31,9 +31,15 @@ * it is called the key_id and is currently 2 bits long. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) #include "error.h" #include "common.h" @@ -58,4 +64,4 @@ session_id_print (const struct session_id *sid, struct gc_arena *gc) #else static void dummy(void) {} -#endif /* USE_CRYPTO && USE_SSL*/ +#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ diff --git a/session_id.h b/src/openvpn/session_id.h index 10f30ed..33909dd 100644 --- a/session_id.h +++ b/src/openvpn/session_id.h @@ -30,7 +30,7 @@ * negotiated). */ -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) #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 /* USE_CRYPTO && USE_SSL */ +#endif /* ENABLE_CRYPTO && ENABLE_SSL */ diff --git a/shaper.c b/src/openvpn/shaper.c index 1a89fc2..c8a7d38 100644 --- a/shaper.c +++ b/src/openvpn/shaper.c @@ -22,11 +22,17 @@ * 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" #include "shaper.h" #include "memdbg.h" -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER /* * We want to wake up in delay microseconds. If timeval is larger @@ -92,4 +98,4 @@ shaper_msg (struct shaper *s) #else static void dummy(void) {} -#endif /* HAVE_GETTIMEOFDAY */ +#endif /* ENABLE_FEATURE_SHAPER */ diff --git a/shaper.h b/src/openvpn/shaper.h index 4825011..afeb9c3 100644 --- a/shaper.h +++ b/src/openvpn/shaper.h @@ -27,7 +27,7 @@ /*#define SHAPER_DEBUG*/ -#ifdef HAVE_GETTIMEOFDAY +#ifdef ENABLE_FEATURE_SHAPER #include "basic.h" #include "integer.h" @@ -173,6 +173,6 @@ shaper_change_pct (struct shaper *s, int pct) } #endif -#endif /* HAVE_GETTIMEOFDAY */ +#endif /* ENABLE_FEATURE_SHAPER */ #endif diff --git a/sig.c b/src/openvpn/sig.c index 631a3a8..0ebde24 100644 --- a/sig.c +++ b/src/openvpn/sig.c @@ -22,6 +22,12 @@ * 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" #include "buffer.h" @@ -199,6 +205,7 @@ static int signal_mode; /* GLOBAL */ void pre_init_signal_catch (void) { +#ifndef WIN32 #ifdef HAVE_SIGNAL_H signal_mode = SM_PRE_INIT; signal (SIGINT, signal_handler); @@ -208,11 +215,13 @@ pre_init_signal_catch (void) signal (SIGUSR2, SIG_IGN); signal (SIGPIPE, SIG_IGN); #endif /* HAVE_SIGNAL_H */ +#endif /* WIN32 */ } void post_init_signal_catch (void) { +#ifndef WIN32 #ifdef HAVE_SIGNAL_H signal_mode = SM_POST_INIT; signal (SIGINT, signal_handler); @@ -222,6 +231,7 @@ post_init_signal_catch (void) signal (SIGUSR2, signal_handler); signal (SIGPIPE, SIG_IGN); #endif /* HAVE_SIGNAL_H */ +#endif } /* called after daemonization to retain signal settings */ @@ -255,7 +265,7 @@ 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 USE_LZO +#ifdef ENABLE_LZO if (lzo_defined (&c->c2.lzo_compwork)) lzo_print_stats (&c->c2.lzo_compwork, so); #endif @@ -268,7 +278,7 @@ print_status (const struct context *c, struct status_output *so) #ifdef WIN32 if (tuntap_defined (c->c1.tuntap)) status_printf (so, "TAP-WIN32 driver status,\"%s\"", - tap_win32_getinfo (c->c1.tuntap, &gc)); + tap_win_getinfo (c->c1.tuntap, &gc)); #endif status_printf (so, "END"); @@ -300,8 +310,8 @@ process_explicit_exit_notification_timer_wakeup (struct context *c) &c->c2.timeval, ETT_DEFAULT)) { - ASSERT (c->c2.explicit_exit_notification_time_wait && c->options.explicit_exit_notification); - if (now >= c->c2.explicit_exit_notification_time_wait + c->options.explicit_exit_notification) + ASSERT (c->c2.explicit_exit_notification_time_wait && c->options.ce.explicit_exit_notification); + if (now >= c->c2.explicit_exit_notification_time_wait + c->options.ce.explicit_exit_notification) { event_timeout_clear (&c->c2.explicit_exit_notification_interval); c->sig->signal_received = SIGTERM; @@ -340,7 +350,7 @@ process_sigterm (struct context *c) { bool ret = true; #ifdef ENABLE_OCC - if (c->options.explicit_exit_notification + if (c->options.ce.explicit_exit_notification && !c->c2.explicit_exit_notification_time_wait) { process_explicit_exit_notification_init (c); @@ -366,3 +376,11 @@ process_signal (struct context *c) } return ret; } + +void +register_signal (struct context *c, int sig, const char *text) +{ + if (c->sig->signal_received != SIGTERM) + c->sig->signal_received = sig; + c->sig->signal_text = text; +} diff --git a/sig.h b/src/openvpn/sig.h index be87fe4..987efef 100644 --- a/sig.h +++ b/src/openvpn/sig.h @@ -64,6 +64,8 @@ void signal_restart_status (const struct signal_info *si); bool process_signal (struct context *c); +void register_signal (struct context *c, int sig, const char *text); + #ifdef ENABLE_OCC void process_explicit_exit_notification_timer_wakeup (struct context *c); #endif diff --git a/socket.c b/src/openvpn/socket.c index 4720398..505cf3b 100644 --- a/socket.c +++ b/src/openvpn/socket.c @@ -22,6 +22,12 @@ * 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" #include "socket.h" @@ -36,10 +42,14 @@ #include "memdbg.h" const int proto_overhead[] = { /* indexed by PROTO_x */ - IPv4_UDP_HEADER_SIZE, + 0, + IPv4_UDP_HEADER_SIZE, /* IPv4 */ IPv4_TCP_HEADER_SIZE, IPv4_TCP_HEADER_SIZE, - IPv4_TCP_HEADER_SIZE + IPv6_UDP_HEADER_SIZE, /* IPv6 */ + IPv6_TCP_HEADER_SIZE, + IPv6_TCP_HEADER_SIZE, + IPv6_TCP_HEADER_SIZE, }; /* @@ -83,30 +93,56 @@ h_errno_msg(int h_errno_err) */ in_addr_t getaddr (unsigned int flags, - const char *hostname, - int resolve_retry_seconds, - bool *succeeded, - volatile int *signal_received) + const char *hostname, + int resolve_retry_seconds, + bool *succeeded, + volatile int *signal_received) { - return getaddr_multi (flags, hostname, resolve_retry_seconds, succeeded, signal_received, NULL); + struct addrinfo *ai; + int status; + status = openvpn_getaddrinfo(flags, hostname, resolve_retry_seconds, + signal_received, AF_INET, &ai); + if(status==0) { + struct in_addr ia; + if(succeeded) + *succeeded=true; + ia = ((struct sockaddr_in*)ai->ai_addr)->sin_addr; + freeaddrinfo(ai); + return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; + } else { + if(succeeded) + *succeeded =false; + return 0; + } } -in_addr_t -getaddr_multi (unsigned int flags, - const char *hostname, - int resolve_retry_seconds, - bool *succeeded, - volatile int *signal_received, - struct resolve_list *reslist) -{ - struct in_addr ia; + +/* + * Translate IPv4/IPv6 addr or hostname into struct addrinfo + * If resolve error, try again for resolve_retry_seconds seconds. + */ +int +openvpn_getaddrinfo (unsigned int flags, + const char *hostname, + int resolve_retry_seconds, + volatile int *signal_received, + int ai_family, + struct addrinfo **res) +{ + struct addrinfo hints; int status; int sigrec = 0; int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; struct gc_arena gc = gc_new (); - if (reslist) - reslist->len = 0; + ASSERT(res); + +#if defined(HAVE_RES_INIT) + res_init (); +#endif + + if (!hostname) + hostname = "::"; if (flags & GETADDR_RANDOMIZE) hostname = hostname_randomize(hostname, &gc); @@ -114,151 +150,111 @@ getaddr_multi (unsigned int flags, if (flags & GETADDR_MSG_VIRT_OUT) msglevel |= M_MSG_VIRT_OUT; - CLEAR (ia); - if (succeeded) - *succeeded = false; - if ((flags & (GETADDR_FATAL_ON_SIGNAL|GETADDR_WARN_ON_SIGNAL)) && !signal_received) signal_received = &sigrec; - status = openvpn_inet_aton (hostname, &ia); /* parse ascii IP address */ + /* try numeric ipv6 addr first */ + CLEAR(hints); + hints.ai_family = ai_family; + hints.ai_flags = AI_NUMERICHOST; + hints.ai_socktype = dnsflags_to_socktype(flags); - if (status != OIA_IP) /* parse as IP address failed? */ + status = getaddrinfo(hostname, NULL, &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); - struct hostent *h; const char *fmt; int level = 0; - CLEAR (ia); - fmt = "RESOLVE: Cannot resolve host address: %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.)"; + && !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.)"; - if (!(flags & GETADDR_RESOLVE) || status == OIA_ERROR) - { - msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname); - goto done; - } + if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL) + { + msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname); + goto done; + } #ifdef ENABLE_MANAGEMENT if (flags & GETADDR_UPDATE_MANAGEMENT_STATE) - { - if (management) - management_set_state (management, - OPENVPN_STATE_RESOLVE, - NULL, - (in_addr_t)0, - (in_addr_t)0); - } + { + if (management) + management_set_state (management, + OPENVPN_STATE_RESOLVE, + NULL, + (in_addr_t)0, + (in_addr_t)0); + } #endif /* * Resolve hostname */ while (true) - { - /* try hostname lookup */ -#if defined(HAVE_RES_INIT) - res_init (); -#endif - h = gethostbyname (hostname); - - if (signal_received) - { - get_signal (signal_received); - if (*signal_received) /* were we interrupted by a signal? */ - { - h = NULL; - if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ - { - msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); - *signal_received = 0; - } - else - goto done; - } - } - - /* success? */ - if (h) - break; - - /* resolve lookup failed, should we - continue or fail? */ - - level = msglevel; - if (resolve_retries > 0) - level = D_RESOLVE_ERRORS; - - msg (level, - fmt, - hostname, - h_errno_msg (h_errno)); - - if (--resolve_retries <= 0) - goto done; - - openvpn_sleep (fail_wait_interval); - } - - if (h->h_addrtype != AF_INET || h->h_length != 4) - { - msg (msglevel, "RESOLVE: Sorry, but we only accept IPv4 DNS names: %s", hostname); - goto done; - } - - ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); - - if (ia.s_addr) - { - if (h->h_addr_list[1]) /* more than one address returned */ - { - int n = 0; - - /* count address list */ - while (h->h_addr_list[n]) - ++n; - ASSERT (n >= 2); - - msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses", - hostname, - n); - - /* choose address randomly, for basic load-balancing capability */ - /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*/ - - /* choose first address */ - ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); - - if (reslist) - { - int i; - for (i = 0; i < n && i < SIZE(reslist->data); ++i) - { - in_addr_t a = *(in_addr_t *) (h->h_addr_list[i]); - if (flags & GETADDR_HOST_ORDER) - a = ntohl(a); - reslist->data[i] = a; - } - reslist->len = i; - } - } - } + { + /* try hostname lookup */ + hints.ai_flags = 0; + 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); + + if (signal_received) + { + get_signal (signal_received); + if (*signal_received) /* were we interrupted by a signal? */ + { + if (0 == status) { + ASSERT(res); + freeaddrinfo(*res); + res = NULL; + } + if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ + { + msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); + *signal_received = 0; + } + else + goto done; + } + } + + /* success? */ + if (0 == status) + break; + + /* resolve lookup failed, should we + continue or fail? */ + level = msglevel; + if (resolve_retries > 0) + level = D_RESOLVE_ERRORS; + + msg (level, + fmt, + hostname, + gai_strerror(status)); + + if (--resolve_retries <= 0) + goto done; + + openvpn_sleep (fail_wait_interval); + } + + ASSERT(res); /* hostname resolve succeeded */ - if (succeeded) - *succeeded = true; + + /* Do not chose an IP Addresse by random or change the order * + * of IP addresses, doing so will break RFC 3484 address selection * + */ } else { /* IP address parse succeeded */ - if (succeeded) - *succeeded = true; } done: @@ -266,14 +262,14 @@ getaddr_multi (unsigned int flags, { int level = 0; if (flags & GETADDR_FATAL_ON_SIGNAL) - level = M_FATAL; + level = M_FATAL; else if (flags & GETADDR_WARN_ON_SIGNAL) - level = M_WARN; + level = M_WARN; msg (level, "RESOLVE: signal received during DNS resolution attempt"); } gc_free (&gc); - return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; + return status; } /* @@ -342,6 +338,24 @@ ip_addr_dotted_quad_safe (const char *dotted_quad) } } +bool +ipv6_addr_safe (const char *ipv6_text_addr) +{ + /* verify non-NULL */ + if (!ipv6_text_addr) + return false; + + /* verify length is within limits */ + if (strlen (ipv6_text_addr) > INET6_ADDRSTRLEN ) + return false; + + /* verify that string will convert to IPv6 address */ + { + struct in6_addr a6; + return inet_pton( AF_INET6, ipv6_text_addr, &a6 ) == 1; + } +} + static bool dns_addr_safe (const char *addr) { @@ -410,20 +424,51 @@ update_remote (const char* host, bool *changed, const unsigned int sockflags) { - if (host && addr) + switch(addr->addr.sa.sa_family) { - const in_addr_t new_addr = getaddr ( - sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), - host, - 1, - NULL, - NULL); - if (new_addr && addr->sa.sin_addr.s_addr != new_addr) + case AF_INET: + if (host && addr) { - addr->sa.sin_addr.s_addr = new_addr; - *changed = true; + 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 @@ -532,6 +577,15 @@ socket_set_tcp_nodelay (int sd, int state) #endif } +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) + msg (M_WARN, "NOTE: setsockopt SO_MARK=%d failed", mark); +#endif +} + static bool socket_set_flags (int sd, unsigned int sockflags) { @@ -567,12 +621,12 @@ link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf) */ socket_descriptor_t -create_socket_tcp (void) +create_socket_tcp (int af) { socket_descriptor_t sd; - if ((sd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) - msg (M_SOCKERR, "Cannot create TCP socket"); + if ((sd = socket (af, SOCK_STREAM, IPPROTO_TCP)) < 0) + msg (M_ERR, "Cannot create TCP socket"); #ifndef WIN32 /* using SO_REUSEADDR on Windows will cause bind to succeed on port conflicts! */ /* set SO_REUSEADDR on socket */ @@ -580,19 +634,7 @@ create_socket_tcp (void) int on = 1; if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof (on)) < 0) - msg (M_SOCKERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP socket"); - } -#endif - -#if 0 - /* set socket linger options */ - { - struct linger linger; - linger.l_onoff = 1; - linger.l_linger = 2; - if (setsockopt (sd, SOL_SOCKET, SO_LINGER, - (void *) &linger, sizeof (linger)) < 0) - msg (M_SOCKERR, "TCP: Cannot setsockopt SO_LINGER on TCP socket"); + msg (M_ERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP socket"); } #endif @@ -605,12 +647,46 @@ create_socket_udp (const unsigned int flags) socket_descriptor_t sd; if ((sd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - msg (M_SOCKERR, "UDP: Cannot create UDP socket"); + msg (M_ERR, "UDP: Cannot create UDP socket"); #if ENABLE_IP_PKTINFO else if (flags & SF_USE_IP_PKTINFO) { int pad = 1; - setsockopt (sd, SOL_IP, IP_PKTINFO, (void*)&pad, sizeof(pad)); +#ifdef IP_PKTINFO + 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"); +#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; +#ifndef IPV6_RECVPKTINFO /* Some older Darwin platforms require this */ + 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) +#endif + msg(M_ERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO"); } #endif return sd; @@ -623,16 +699,27 @@ create_socket (struct link_socket *sock) if (sock->info.proto == PROTO_UDPv4) { sock->sd = create_socket_udp (sock->sockflags); + sock->sockflags |= SF_GETADDRINFO_DGRAM; #ifdef ENABLE_SOCKS if (sock->socks_proxy) - sock->ctrl_sd = create_socket_tcp (); + 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 (); + 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); + } + else if (sock->info.proto == PROTO_UDPv6) + { + sock->sd = create_socket_udp6 (sock->sockflags); + sock->sockflags |= SF_GETADDRINFO_DGRAM; } else { @@ -656,7 +743,7 @@ socket_do_listen (socket_descriptor_t sd, msg (M_INFO, "Listening for incoming TCP connection on %s", print_sockaddr (local, &gc)); if (listen (sd, 1)) - msg (M_SOCKERR, "TCP: listen() failed"); + msg (M_ERR, "TCP: listen() failed"); } /* set socket to non-blocking mode */ @@ -671,7 +758,12 @@ socket_do_accept (socket_descriptor_t sd, struct link_socket_actual *act, const bool nowait) { - socklen_t remote_len = sizeof (act->dest.sa); + /* af_addr_size WILL return 0 in this case if AFs other than AF_INET + * are compiled because act is empty here. + * could use getsockname() to support later remote_len check + */ + socklen_t remote_len_af = af_addr_size(act->dest.addr.sa.sa_family); + socklen_t remote_len = sizeof(act->dest.addr); socket_descriptor_t new_sd = SOCKET_UNDEFINED; CLEAR (*act); @@ -679,10 +771,10 @@ socket_do_accept (socket_descriptor_t sd, #ifdef HAVE_GETPEERNAME if (nowait) { - new_sd = getpeername (sd, (struct sockaddr *) &act->dest.sa, &remote_len); + new_sd = getpeername (sd, &act->dest.addr.sa, &remote_len); if (!socket_defined (new_sd)) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: getpeername() failed"); + msg (D_LINK_ERRORS | M_ERRNO, "TCP: getpeername() failed"); else new_sd = sd; } @@ -692,7 +784,7 @@ socket_do_accept (socket_descriptor_t sd, #endif else { - new_sd = accept (sd, (struct sockaddr *) &act->dest.sa, &remote_len); + new_sd = accept (sd, &act->dest.addr.sa, &remote_len); } #if 0 /* For debugging only, test the effect of accept() failures */ @@ -706,9 +798,10 @@ socket_do_accept (socket_descriptor_t sd, if (!socket_defined (new_sd)) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: accept(%d) failed", sd); + msg (D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", sd); } - else if (remote_len != sizeof (act->dest.sa)) + /* only valid if we have remote_len_af!=0 */ + else if (remote_len_af && remote_len != remote_len_af) { msg (D_LINK_ERRORS, "TCP: Received strange incoming connection with unknown address length=%d", remote_len); openvpn_close_socket (new_sd); @@ -765,7 +858,7 @@ socket_listen_accept (socket_descriptor_t sd, } if (status < 0) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: select() failed"); + msg (D_LINK_ERRORS | M_ERRNO, "TCP: select() failed"); if (status <= 0) { @@ -785,7 +878,7 @@ socket_listen_accept (socket_descriptor_t sd, "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_SOCKERR, "TCP: close socket failed (new_sd)"); + msg (M_ERR, "TCP: close socket failed (new_sd)"); } else break; @@ -794,7 +887,7 @@ socket_listen_accept (socket_descriptor_t sd, } if (!nowait && openvpn_close_socket (sd)) - msg (M_SOCKERR, "TCP: close socket failed (sd)"); + msg (M_ERR, "TCP: close socket failed (sd)"); tcp_connection_established (act); @@ -809,9 +902,9 @@ socket_bind (socket_descriptor_t sd, { struct gc_arena gc = gc_new (); - if (bind (sd, (struct sockaddr *) &local->sa, sizeof (local->sa))) + if (bind (sd, &local->addr.sa, af_addr_size(local->addr.sa.sa_family))) { - const int errnum = openvpn_errno_socket (); + const int errnum = openvpn_errno (); msg (M_FATAL, "%s: Socket bind failed on local address %s: %s", prefix, print_sockaddr (local, &gc), @@ -830,10 +923,16 @@ openvpn_connect (socket_descriptor_t sd, #ifdef CONNECT_NONBLOCK set_nonblock (sd); - status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); + status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); if (status) - status = openvpn_errno_socket (); - if (status == EINPROGRESS) + status = openvpn_errno (); + if ( +#ifdef WIN32 + status == WSAEWOULDBLOCK +#else + status == EINPROGRESS +#endif + ) { while (true) { @@ -858,7 +957,7 @@ openvpn_connect (socket_descriptor_t sd, } if (status < 0) { - status = openvpn_errno_socket (); + status = openvpn_errno (); break; } if (status <= 0) @@ -882,15 +981,15 @@ openvpn_connect (socket_descriptor_t sd, && len == sizeof (val)) status = val; else - status = openvpn_errno_socket (); + status = openvpn_errno (); break; } } } #else - status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); + status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); if (status) - status = openvpn_errno_socket (); + status = openvpn_errno (); #endif return status; @@ -966,7 +1065,8 @@ socket_connect (socket_descriptor_t *sd, if (*signal_received) goto done; - *sd = create_socket_tcp (); + *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); @@ -1031,15 +1131,52 @@ resolve_bind_local (struct link_socket *sock) /* resolve local address if undefined */ if (!addr_defined (&sock->info.lsa->local)) { - sock->info.lsa->local.sa.sin_family = AF_INET; - sock->info.lsa->local.sa.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.sa.sin_port = htons (sock->local_port); + /* 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; + int err; + 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(err)); + } + sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); + } + break; + } } /* bind to local address/port */ @@ -1062,20 +1199,32 @@ 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 (!addr_defined (&sock->info.lsa->remote)) { - sock->info.lsa->remote.sa.sin_family = AF_INET; - sock->info.lsa->remote.sa.sin_addr.s_addr = 0; + 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; - bool status = false; + int status = -1; if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) { @@ -1112,34 +1261,42 @@ resolve_remote (struct link_socket *sock, ASSERT (0); } - sock->info.lsa->remote.sa.sin_addr.s_addr = getaddr ( - flags, - sock->remote_host, - retry, - &status, - signal_received); - - 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); - + struct addrinfo* ai; + /* 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) { + sock->info.lsa->remote.addr.in6 = *((struct sockaddr_in6*)(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; } - if (!status) + if (status!=0) { if (signal_received) *signal_received = SIGUSR1; goto done; } } - - sock->info.lsa->remote.sa.sin_port = htons (sock->remote_port); + 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? */ @@ -1210,6 +1367,7 @@ link_socket_init_phase1 (struct link_socket *sock, int mtu_discover_type, int rcvbuf, int sndbuf, + int mark, unsigned int sockflags) { ASSERT (sock); @@ -1256,7 +1414,9 @@ link_socket_init_phase1 (struct link_socket *sock, if (mode == LS_MODE_TCP_ACCEPT_FROM) { ASSERT (accept_from); - ASSERT (sock->info.proto == PROTO_TCPv4_SERVER); + ASSERT (sock->info.proto == PROTO_TCPv4_SERVER + || sock->info.proto == PROTO_TCPv6_SERVER + ); ASSERT (!sock->inetd); sock->sd = accept_from->sd; } @@ -1313,7 +1473,8 @@ 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); + ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT + && sock->info.proto != PROTO_TCPv6_CLIENT); ASSERT (socket_defined (inetd_socket_descriptor)); sock->sd = inetd_socket_descriptor; } @@ -1324,6 +1485,9 @@ link_socket_init_phase1 (struct link_socket *sock, /* 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, mark); + resolve_bind_local (sock); resolve_remote (sock, 1, NULL, NULL); } @@ -1362,7 +1526,29 @@ 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) + 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, @@ -1372,6 +1558,7 @@ link_socket_init_phase2 (struct link_socket *sock, false, sock->inetd == INETD_NOWAIT, signal_received); + } ASSERT (!remote_changed); if (*signal_received) goto done; @@ -1384,7 +1571,8 @@ link_socket_init_phase2 (struct link_socket *sock, goto done; /* TCP client/server */ - if (sock->info.proto == PROTO_TCPv4_SERVER) + if (sock->info.proto == PROTO_TCPv4_SERVER + ||sock->info.proto == PROTO_TCPv6_SERVER) { switch (sock->mode) { @@ -1419,7 +1607,8 @@ link_socket_init_phase2 (struct link_socket *sock, ASSERT (0); } } - else if (sock->info.proto == PROTO_TCPv4_CLIENT) + else if (sock->info.proto == PROTO_TCPv4_CLIENT + ||sock->info.proto == PROTO_TCPv6_CLIENT) { #ifdef GENERAL_PROXY_SUPPORT @@ -1470,7 +1659,7 @@ link_socket_init_phase2 (struct link_socket *sock, if (proxy_retry) { openvpn_close_socket (sock->sd); - sock->sd = create_socket_tcp (); + sock->sd = create_socket_tcp (AF_INET); } } while (proxy_retry); } @@ -1506,8 +1695,8 @@ link_socket_init_phase2 (struct link_socket *sock, sock->remote_port = sock->proxy_dest_port; sock->did_resolve_remote = false; - sock->info.lsa->actual.dest.sa.sin_addr.s_addr = 0; - sock->info.lsa->remote.sa.sin_addr.s_addr = 0; + addr_zero_host(&sock->info.lsa->actual.dest); + addr_zero_host(&sock->info.lsa->remote); resolve_remote (sock, 1, NULL, signal_received); @@ -1522,7 +1711,7 @@ link_socket_init_phase2 (struct link_socket *sock, if (remote_changed) { msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment"); - sock->info.lsa->remote.sa.sin_addr.s_addr = sock->info.lsa->actual.dest.sa.sin_addr.s_addr; + addr_copy_host(&sock->info.lsa->remote, &sock->info.lsa->actual.dest); } } @@ -1550,21 +1739,25 @@ link_socket_init_phase2 (struct link_socket *sock, #endif /* print local address */ - if (sock->inetd) - msg (M_INFO, "%s link local: [inetd]", proto2ascii (sock->info.proto, true)); - else - msg (M_INFO, "%s link local%s: %s", + { + 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), - (sock->bind_local ? " (bound)" : ""), - print_sockaddr_ex (&sock->info.lsa->local, ":", sock->bind_local ? PS_SHOW_PORT : 0, &gc)); - - /* print active remote address */ - msg (M_INFO, "%s link remote: %s", - proto2ascii (sock->info.proto, true), - print_link_socket_actual_ex (&sock->info.lsa->actual, - ":", - PS_SHOW_PORT_IF_DEFINED, - &gc)); + print_link_socket_actual_ex (&sock->info.lsa->actual, + ":", + PS_SHOW_PORT_IF_DEFINED, + &gc)); + } done: if (sig_save && signal_received) @@ -1593,9 +1786,9 @@ link_socket_close (struct link_socket *sock) #endif if (!gremlin) { - msg (D_CLOSE, "TCP/UDP: Closing socket"); + msg (D_LOW, "TCP/UDP: Closing socket"); if (openvpn_close_socket (sock->sd)) - msg (M_WARN | M_ERRNO_SOCK, "TCP/UDP: Close Socket failed"); + msg (M_WARN | M_ERRNO, "TCP/UDP: Close Socket failed"); } sock->sd = SOCKET_UNDEFINED; #ifdef WIN32 @@ -1611,7 +1804,7 @@ link_socket_close (struct link_socket *sock) if (socket_defined (sock->ctrl_sd)) { if (openvpn_close_socket (sock->ctrl_sd)) - msg (M_WARN | M_ERRNO_SOCK, "TCP/UDP: Close Socket (ctrl_sd) failed"); + msg (M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd) failed"); sock->ctrl_sd = SOCKET_UNDEFINED; } #endif @@ -1708,13 +1901,18 @@ link_socket_bad_incoming_addr (struct buffer *buf, { struct gc_arena gc = gc_new (); - msg (D_LINK_ERRORS, - "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.sa.sin_family, - print_sockaddr (&info->lsa->remote, &gc)); + switch(from_addr->dest.addr.sa.sa_family) + { + case AF_INET: + case AF_INET6: + msg (D_LINK_ERRORS, + "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)); + break; + } buf->len = 0; - gc_free (&gc); } @@ -1729,10 +1927,21 @@ link_socket_current_remote (const struct link_socket_info *info) { const struct link_socket_addr *lsa = info->lsa; +/* + * This logic supports "redirect-gateway" semantic, which + * makes sense only for PF_INET routes over PF_INET endpoints + * + * Maybe in the future consider PF_INET6 endpoints also ... + * by now just ignore it + * + */ + 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.sa.sin_addr.s_addr); + return ntohl (lsa->actual.dest.addr.in4.sin_addr.s_addr); else if (addr_defined (&lsa->remote)) - return ntohl (lsa->remote.sa.sin_addr.s_addr); + return ntohl (lsa->remote.addr.in4.sin_addr.s_addr); else return 0; } @@ -1959,26 +2168,57 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, const unsigned int flags, struct gc_arena *gc) { - if (addr) + 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) { - struct buffer out = alloc_buf_gc (64, gc); - const int port = ntohs (addr->sa.sin_port); + 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_DONT_SHOW_ADDR)) - buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sa.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); - if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED))) - && port) + buf_printf (&out, "%d", port); + } + } + break; + case AF_INET6: { - if (separator) - buf_printf (&out, "%s", separator); + 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); + buf_printf (&out, "%d", port); + } } - return BSTR (&out); + break; + default: + ASSERT(0); } - else - return "[NULL]"; + return BSTR (&out); } const char * @@ -1987,6 +2227,10 @@ print_link_socket_actual (const struct link_socket_actual *act, struct gc_arena return print_link_socket_actual_ex (act, ":", PS_SHOW_PORT|PS_SHOW_PKTINFO, gc); } +#ifndef IF_NAMESIZE +#define IF_NAMESIZE 16 +#endif + const char * print_link_socket_actual_ex (const struct link_socket_actual *act, const char *separator, @@ -1995,15 +2239,49 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, { if (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)); #if ENABLE_IP_PKTINFO - if ((flags & PS_SHOW_PKTINFO) && act->pi.ipi_spec_dst.s_addr) + if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act)) { - struct openvpn_sockaddr sa; - CLEAR (sa); - sa.sa.sin_addr = act->pi.ipi_spec_dst; - buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); + switch(act->dest.addr.sa.sa_family) + { + case AF_INET: + { + struct openvpn_sockaddr sa; + CLEAR (sa); + sa.addr.in4.sin_family = AF_INET; +#ifdef IP_PKTINFO + sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; + if_indextoname(act->pi.in4.ipi_ifindex, ifname); +#elif defined(IP_RECVDSTADDR) + sa.addr.in4.sin_addr = act->pi.in4; + ifname[0]=0; +#else +#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), + ifname); + } + break; + case AF_INET6: + { + struct sockaddr_in6 sin6; + char buf[INET6_ADDRSTRLEN] = "[undef]"; + CLEAR(sin6); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = act->pi.in6.ipi6_addr; + if_indextoname(act->pi.in6.ipi6_ifindex, ifname); + if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), + buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) == 0) + buf_printf (&out, " (via %s%%%s)", buf, ifname); + else + buf_printf (&out, " (via [getnameinfo() err]%%%s)", ifname); + } + break; + } } #endif return BSTR (&out); @@ -2032,34 +2310,100 @@ print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc) return BSTR (&out); } +/* + * Convert an in6_addr in host byte order + * to an ascii representation of an IPv6 address + */ +const char * +print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc) +{ + struct buffer out = alloc_buf_gc (64, gc); + char tmp_out_buf[64]; /* inet_ntop wants pointer to buffer */ + + if ( memcmp(&a6, &in6addr_any, sizeof(a6)) != 0 || + !(flags & IA_EMPTY_IF_UNDEF)) + { + inet_ntop (AF_INET6, &a6, tmp_out_buf, sizeof(tmp_out_buf)-1); + buf_printf (&out, "%s", tmp_out_buf ); + } + return BSTR (&out); +} + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif + +/* add some offset to an ipv6 address + * (add in steps of 8 bits, taking overflow into next round) + */ +struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add ) +{ + int i; + + for( i=15; i>=0 && add > 0 ; i-- ) + { + register int carry; + register uint32_t h; + + h = (unsigned char) base.s6_addr[i]; + base.s6_addr[i] = (h+add) & UINT8_MAX; + + /* using explicit carry for the 8-bit additions will catch + * 8-bit and(!) 32-bit overruns nicely + */ + carry = ((h & 0xff) + (add & 0xff)) >> 8; + add = (add>>8) + carry; + } + return base; +} + /* set environmental variables for ip/port in *addr */ void -setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags) +setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const unsigned int flags) { char name_buf[256]; - if (flags & SA_IP_PORT) - openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); - else - openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); + char buf[128]; + switch(addr->addr.sa.sa_family) + { + case AF_INET: + if (flags & SA_IP_PORT) + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); + else + openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); - setenv_str (es, name_buf, inet_ntoa (addr->sa.sin_addr)); + setenv_str (es, name_buf, inet_ntoa (addr->addr.in4.sin_addr)); - if ((flags & SA_IP_PORT) && addr->sa.sin_port) - { - openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); - setenv_int (es, name_buf, ntohs (addr->sa.sin_port)); + if ((flags & SA_IP_PORT) && addr->addr.in4.sin_port) + { + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); + setenv_int (es, name_buf, ntohs (addr->addr.in4.sin_port)); + } + 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); + setenv_str (es, name_buf, buf); + + if ((flags & SA_IP_PORT) && addr->addr.in6.sin6_port) + { + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); + setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); + } + break; } } void -setenv_in_addr_t (struct env_set *es, const char *name_prefix, in_addr_t addr, const bool flags) +setenv_in_addr_t (struct env_set *es, const char *name_prefix, in_addr_t addr, const unsigned int flags) { if (addr || !(flags & SA_SET_IF_NONZERO)) { struct openvpn_sockaddr si; CLEAR (si); - si.sa.sin_addr.s_addr = htonl (addr); + si.addr.in4.sin_family = AF_INET; + si.addr.in4.sin_addr.s_addr = htonl (addr); setenv_sockaddr (es, name_prefix, &si, flags); } } @@ -2068,7 +2412,7 @@ void setenv_link_socket_actual (struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, - const bool flags) + const unsigned int flags) { setenv_sockaddr (es, name_prefix, &act->dest, flags); } @@ -2080,16 +2424,61 @@ 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; }; /* Indexed by PROTO_x */ -static const struct proto_names proto_names[] = { - {"udp", "UDPv4"}, - {"tcp-server", "TCPv4_SERVER"}, - {"tcp-client", "TCPv4_CLIENT"}, - {"tcp", "TCPv4"} +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}, }; +bool +proto_is_net(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].is_net; +} +bool +proto_is_dgram(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].is_dgram; +} +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; +} +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; +} + int ascii2proto (const char* proto_name) { @@ -2129,6 +2518,41 @@ proto2ascii_all (struct gc_arena *gc) 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) +{ + switch (af) + { + case AF_INET: return "AF_INET"; + case AF_INET6: return "AF_INET6"; + } + return "AF_UNSPEC"; +} + /* * Given a local proto, return local proto * if !remote, or compatible remote proto @@ -2143,10 +2567,13 @@ proto_remote (int proto, bool remote) ASSERT (proto >= 0 && proto < PROTO_N); if (remote) { - if (proto == PROTO_TCPv4_SERVER) - return PROTO_TCPv4_CLIENT; - if (proto == PROTO_TCPv4_CLIENT) - return PROTO_TCPv4_SERVER; + switch (proto) + { + case PROTO_TCPv4_SERVER: return PROTO_TCPv4_CLIENT; + case PROTO_TCPv4_CLIENT: return PROTO_TCPv4_SERVER; + case PROTO_TCPv6_SERVER: return PROTO_TCPv6_CLIENT; + case PROTO_TCPv6_CLIENT: return PROTO_TCPv6_SERVER; + } } return proto; } @@ -2205,10 +2632,24 @@ link_socket_read_tcp (struct link_socket *sock, #if ENABLE_IP_PKTINFO #pragma pack(1) /* needed to keep structure size consistent for 32 vs. 64-bit architectures */ -struct openvpn_pktinfo +struct openvpn_in4_pktinfo { struct cmsghdr cmsghdr; - struct in_pktinfo in_pktinfo; +#ifdef HAVE_IN_PKTINFO + struct in_pktinfo pi4; +#elif defined(IP_RECVDSTADDR) + struct in_addr pi4; +#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() @@ -2219,18 +2660,18 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, struct link_socket_actual *from) { struct iovec iov; - struct openvpn_pktinfo opi; + union openvpn_pktinfo opi; struct msghdr mesg; - socklen_t fromlen = sizeof (from->dest.sa); + socklen_t fromlen = sizeof (from->dest.addr); iov.iov_base = BPTR (buf); iov.iov_len = maxsize; mesg.msg_iov = &iov; mesg.msg_iovlen = 1; - mesg.msg_name = &from->dest.sa; + mesg.msg_name = &from->dest.addr; mesg.msg_namelen = fromlen; mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); + mesg.msg_controllen = sizeof opi; buf->len = recvmsg (sock->sd, &mesg, 0); if (buf->len >= 0) { @@ -2239,13 +2680,36 @@ 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 && cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO - && cmsg->cmsg_len >= sizeof (opi)) +#elif defined(IP_RECVDSTADDR) + && cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_RECVDSTADDR +#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 struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); - from->pi.ipi_ifindex = pkti->ipi_ifindex; - from->pi.ipi_spec_dst = pkti->ipi_spec_dst; + from->pi.in4.ipi_ifindex = pkti->ipi_ifindex; + from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst; +#elif defined(IP_RECVDSTADDR) + from->pi.in4 = *(struct in_addr*) CMSG_DATA (cmsg); +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif + } + else if (cmsg != NULL + && CMSG_NXTHDR (&mesg, cmsg) == NULL + && cmsg->cmsg_level == IPPROTO_IPV6 + && cmsg->cmsg_type == IPV6_PKTINFO + && cmsg->cmsg_len >= sizeof (struct openvpn_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; } } return fromlen; @@ -2258,18 +2722,20 @@ link_socket_read_udp_posix (struct link_socket *sock, int maxsize, struct link_socket_actual *from) { - socklen_t fromlen = sizeof (from->dest.sa); - from->dest.sa.sin_addr.s_addr = 0; + socklen_t fromlen = sizeof (from->dest.addr); + socklen_t expectedlen = af_addr_size(proto_sa_family(sock->info.proto)); + addr_zero_host(&from->dest); ASSERT (buf_safe (buf, maxsize)); #if ENABLE_IP_PKTINFO - if (sock->sockflags & SF_USE_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); else #endif buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0, - (struct sockaddr *) &from->dest.sa, &fromlen); - if (fromlen != sizeof (from->dest.sa)) - bad_address_length (fromlen, sizeof (from->dest.sa)); + &from->dest.addr.sa, &fromlen); + if (buf->len >= 0 && expectedlen && fromlen != expectedlen) + bad_address_length (fromlen, expectedlen); return buf->len; } @@ -2306,26 +2772,62 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, struct iovec iov; struct msghdr mesg; struct cmsghdr *cmsg; - struct in_pktinfo *pkti; - struct openvpn_pktinfo opi; iov.iov_base = BPTR (buf); iov.iov_len = BLEN (buf); mesg.msg_iov = &iov; mesg.msg_iovlen = 1; - mesg.msg_name = &to->dest.sa; - mesg.msg_namelen = sizeof (to->dest.sa); - mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); - mesg.msg_flags = 0; - cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi); - cmsg->cmsg_level = SOL_IP; - cmsg->cmsg_type = IP_PKTINFO; - pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); - pkti->ipi_ifindex = to->pi.ipi_ifindex; - pkti->ipi_spec_dst = to->pi.ipi_spec_dst; - pkti->ipi_addr.s_addr = 0; + switch (sock->info.lsa->remote.addr.sa.sa_family) + { + case AF_INET: + { + struct openvpn_in4_pktinfo msgpi4; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in); + mesg.msg_control = &msgpi4; + mesg.msg_controllen = sizeof msgpi4; + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); +#ifdef HAVE_IN_PKTINFO + cmsg->cmsg_level = SOL_IP; + cmsg->cmsg_type = IP_PKTINFO; + { + struct in_pktinfo *pkti; + pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); + pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; + pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; + pkti->ipi_addr.s_addr = 0; + } +#elif defined(IP_RECVDSTADDR) + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_RECVDSTADDR; + *(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4; +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif + break; + } + case AF_INET6: + { + struct openvpn_in6_pktinfo msgpi6; + struct in6_pktinfo *pkti6; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in6); + mesg.msg_control = &msgpi6; + mesg.msg_controllen = sizeof msgpi6; + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (struct openvpn_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; + break; + } + default: ASSERT(0); + } return sendmsg (sock->sd, &mesg, 0); } @@ -2346,11 +2848,11 @@ socket_recv_queue (struct link_socket *sock, int maxsize) int status; /* reset buf to its initial state */ - if (sock->info.proto == PROTO_UDPv4) + if (proto_is_udp(sock->info.proto)) { sock->reads.buf = sock->reads.buf_init; } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + else if (proto_is_tcp(sock->info.proto)) { stream_buf_get_next (&sock->stream_buf, &sock->reads.buf); } @@ -2370,10 +2872,13 @@ socket_recv_queue (struct link_socket *sock, int maxsize) ASSERT (ResetEvent (sock->reads.overlapped.hEvent)); sock->reads.flags = 0; - if (sock->info.proto == PROTO_UDPv4) + if (proto_is_udp(sock->info.proto)) { sock->reads.addr_defined = true; - sock->reads.addrlen = sizeof (sock->reads.addr); + if (sock->info.proto == PROTO_UDPv6) + sock->reads.addrlen = sizeof (sock->reads.addr6); + else + sock->reads.addrlen = sizeof (sock->reads.addr); status = WSARecvFrom( sock->sd, wsabuf, @@ -2385,7 +2890,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize) &sock->reads.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + else if (proto_is_tcp(sock->info.proto)) { sock->reads.addr_defined = false; status = WSARecv( @@ -2405,9 +2910,9 @@ socket_recv_queue (struct link_socket *sock, int maxsize) if (!status) /* operation completed immediately? */ { - if (sock->reads.addr_defined && sock->reads.addrlen != sizeof (sock->reads.addr)) - bad_address_length (sock->reads.addrlen, sizeof (sock->reads.addr)); - + 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); sock->reads.iostate = IOSTATE_IMMEDIATE_RETURN; /* since we got an immediate return, we must signal the event object ourselves */ @@ -2465,12 +2970,20 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li ASSERT (ResetEvent (sock->writes.overlapped.hEvent)); sock->writes.flags = 0; - if (sock->info.proto == PROTO_UDPv4) + if (proto_is_udp(sock->info.proto)) { /* set destination address for UDP writes */ sock->writes.addr_defined = true; - sock->writes.addr = to->dest.sa; - sock->writes.addrlen = sizeof (sock->writes.addr); + if (sock->info.proto == PROTO_UDPv6) + { + sock->writes.addr6 = to->dest.addr.in6; + sock->writes.addrlen = sizeof (sock->writes.addr6); + } + else + { + sock->writes.addr = to->dest.addr.in4; + sock->writes.addrlen = sizeof (sock->writes.addr); + } status = WSASendTo( sock->sd, @@ -2483,7 +2996,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li &sock->writes.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + else if (proto_is_tcp(sock->info.proto)) { /* destination address for TCP writes was established on connection initiation */ sock->writes.addr_defined = false; @@ -2583,7 +3096,7 @@ socket_finalize (SOCKET s, /* if no error (i.e. just not finished yet), then DON'T execute this code */ io->iostate = IOSTATE_INITIAL; ASSERT (ResetEvent (io->overlapped.hEvent)); - msg (D_WIN32_IO | M_ERRNO_SOCK, "WIN32 I/O: Socket Completion error"); + msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: Socket Completion error"); } } break; @@ -2596,7 +3109,7 @@ socket_finalize (SOCKET s, /* error return for a non-queued operation */ WSASetLastError (io->status); ret = -1; - msg (D_WIN32_IO | M_ERRNO_SOCK, "WIN32 I/O: Socket Completion non-queued error"); + msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: Socket Completion non-queued error"); } else { @@ -2623,12 +3136,36 @@ socket_finalize (SOCKET s, { if (ret >= 0 && io->addr_defined) { - if (io->addrlen != sizeof (io->addr)) - bad_address_length (io->addrlen, sizeof (io->addr)); - from->dest.sa = io->addr; + /* TODO(jjo): streamline this mess */ + /* in this func we dont have relevant info about the PF_ of this + * endpoint, as link_socket_actual will be zero for the 1st received packet + * + * Test for inets PF_ possible sizes + */ + switch (io->addrlen) + { + 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*/ + case sizeof(struct sockaddr_in6)-4: + break; + default: + bad_address_length (io->addrlen, af_addr_size(io->addr.sin_family)); + } + + switch (io->addr.sin_family) + { + case AF_INET: + from->dest.addr.in4 = io->addr; + break; + case AF_INET6: + from->dest.addr.in6 = io->addr6; + break; + } } else - CLEAR (from->dest.sa); + CLEAR (from->dest.addr); } if (buf) @@ -2706,7 +3243,7 @@ create_socket_unix (void) socket_descriptor_t sd; if ((sd = socket (PF_UNIX, SOCK_STREAM, 0)) < 0) - msg (M_SOCKERR, "Cannot create unix domain socket"); + msg (M_ERR, "Cannot create unix domain socket"); return sd; } @@ -2723,7 +3260,7 @@ socket_bind_unix (socket_descriptor_t sd, if (bind (sd, (struct sockaddr *) local, sizeof (struct sockaddr_un))) { - const int errnum = openvpn_errno_socket (); + const int errnum = openvpn_errno (); msg (M_FATAL, "%s: Socket bind[%d] failed on unix domain socket %s: %s", prefix, (int)sd, @@ -2756,7 +3293,7 @@ socket_connect_unix (socket_descriptor_t sd, { int status = connect (sd, (struct sockaddr *) remote, sizeof (struct sockaddr_un)); if (status) - status = openvpn_errno_socket (); + status = openvpn_errno (); return status; } diff --git a/socket.h b/src/openvpn/socket.h index eef98d1..44f1098 100644 --- a/socket.h +++ b/src/openvpn/socket.h @@ -70,7 +70,11 @@ typedef uint16_t packet_size_type; struct openvpn_sockaddr { /*int dummy;*/ /* add offset to force a bug if sa not explicitly dereferenced */ - struct sockaddr_in sa; + union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + } addr; }; /* actual address of remote, based on source address of received packets */ @@ -79,7 +83,14 @@ 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 - struct in_pktinfo pi; + union { +#ifdef HAVE_IN_PKTINFO + struct in_pktinfo in4; +#elif defined(IP_RECVDSTADDR) + struct in_addr in4; +#endif + struct in6_pktinfo in6; + } pi; #endif }; @@ -199,6 +210,7 @@ struct link_socket # 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; /* for stream sockets */ @@ -311,6 +323,7 @@ link_socket_init_phase1 (struct link_socket *sock, int mtu_discover_type, int rcvbuf, int sndbuf, + int mark, unsigned int sockflags); void link_socket_init_phase2 (struct link_socket *sock, @@ -351,26 +364,32 @@ const char *print_link_socket_actual (const struct link_socket_actual *act, #define IA_EMPTY_IF_UNDEF (1<<0) #define IA_NET_ORDER (1<<1) const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc); +const char *print_in6_addr (struct in6_addr addr6, unsigned int flags, struct gc_arena *gc); +struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add ); #define SA_IP_PORT (1<<0) #define SA_SET_IF_NONZERO (1<<1) void setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, - const bool flags); + const unsigned int flags); void setenv_in_addr_t (struct env_set *es, const char *name_prefix, in_addr_t addr, - const bool flags); + const unsigned int flags); void setenv_link_socket_actual (struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, - const bool flags); + const unsigned int flags); void bad_address_length (int actual, int expected); +/* IPV4_INVALID_ADDR: returned by link_socket_current_remote() + * to ease redirect-gateway logic for ipv4 tunnels on ipv6 endpoints + */ +#define IPV4_INVALID_ADDR 0xffffffff in_addr_t link_socket_current_remote (const struct link_socket_info *info); void link_socket_connection_initiated (const struct buffer *buf, @@ -404,12 +423,21 @@ int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr); bool ip_addr_dotted_quad_safe (const char *dotted_quad); 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 (void); +socket_descriptor_t create_socket_tcp (int af); socket_descriptor_t socket_do_accept (socket_descriptor_t sd, struct link_socket_actual *act, const bool nowait); +/* + * proto related + */ +bool proto_is_net(int proto); +bool proto_is_dgram(int proto); +bool proto_is_udp(int proto); +bool proto_is_tcp(int proto); + #if UNIX_SOCK_SUPPORT @@ -439,11 +467,6 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int * * DNS resolution */ -struct resolve_list { - int len; - in_addr_t data[16]; -}; - #define GETADDR_RESOLVE (1<<0) #define GETADDR_FATAL (1<<1) #define GETADDR_HOST_ORDER (1<<2) @@ -455,40 +478,58 @@ struct resolve_list { #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8) #define GETADDR_RANDOMIZE (1<<9) +/* [ab]use flags bits to get socktype info downstream */ +/* TODO(jjo): resolve tradeoff between hackiness|args-overhead */ +#define GETADDR_DGRAM (1<<10) +#define dnsflags_to_socktype(flags) ((flags & GETADDR_DGRAM) ? SOCK_DGRAM : SOCK_STREAM) + in_addr_t getaddr (unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, volatile int *signal_received); -in_addr_t getaddr_multi (unsigned int flags, - const char *hostname, - int resolve_retry_seconds, - bool *succeeded, - volatile int *signal_received, - struct resolve_list *reslist); +int openvpn_getaddrinfo (unsigned int flags, + const char *hostname, + int resolve_retry_seconds, + volatile int *signal_received, + int ai_family, + struct addrinfo **res); /* * Transport protocol naming and other details. */ -#define PROTO_UDPv4 0 -#define PROTO_TCPv4_SERVER 1 -#define PROTO_TCPv4_CLIENT 2 -#define PROTO_TCPv4 3 -#define PROTO_N 4 +/* + * Use enum's instead of #define to allow for easier + * optional proto support + */ +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_N +}; int ascii2proto (const char* proto_name); const char *proto2ascii (int proto, bool display_form); const char *proto2ascii_all (struct gc_arena *gc); int proto_remote (int proto, bool remote); +const char *addr_family_name(int af); /* * Overhead added to packets by various protocols. */ #define IPv4_UDP_HEADER_SIZE 28 #define IPv4_TCP_HEADER_SIZE 40 -#define IPv6_UDP_HEADER_SIZE 40 +#define IPv6_UDP_HEADER_SIZE 48 +#define IPv6_TCP_HEADER_SIZE 60 extern const int proto_overhead[]; @@ -509,16 +550,10 @@ legal_ipv4_port (int port) return port > 0 && port < 65536; } -static inline int -is_proto_tcp(const int p) -{ - return p > 0; /* depends on the definition of PROTO_x */ -} - static inline bool link_socket_proto_connection_oriented (int proto) { - return proto == PROTO_TCPv4_SERVER || proto == PROTO_TCPv4_CLIENT; + return !proto_is_dgram(proto); } static inline bool @@ -533,7 +568,31 @@ link_socket_connection_oriented (const struct link_socket *sock) static inline bool addr_defined (const struct openvpn_sockaddr *addr) { - return addr->sa.sin_addr.s_addr != 0; + if (!addr) return 0; + switch (addr->addr.sa.sa_family) { + case AF_INET: return addr->addr.in4.sin_addr.s_addr != 0; + case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&addr->addr.in6.sin6_addr); + default: return 0; + } +} +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 + 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; +#endif + case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&lsa->pi.in6.ipi6_addr); + default: return 0; + } +#else + ASSERT(0); +#endif + return false; } static inline bool @@ -545,20 +604,42 @@ link_socket_actual_defined (const struct link_socket_actual *act) static inline bool addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2) { - return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr; + switch(a1->addr.sa.sa_family) { + case AF_INET: + return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr; + case AF_INET6: + return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr); + } + ASSERT(0); + return false; } static inline in_addr_t -addr_host (const struct openvpn_sockaddr *s) +addr_host (const struct openvpn_sockaddr *addr) { - return ntohl (s->sa.sin_addr.s_addr); + /* + * "public" addr returned is checked against ifconfig for + * possible clash: non sense for now given + * that we do ifconfig only IPv4 + */ + if(addr->addr.sa.sa_family != AF_INET) + return 0; + return ntohl (addr->addr.in4.sin_addr.s_addr); } static inline bool addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2) { - return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr - && a1->sa.sin_port == a2->sa.sin_port; + switch(a1->addr.sa.sa_family) { + case AF_INET: + 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) + && a1->addr.in6.sin6_port == a2->addr.in6.sin6_port; + } + ASSERT(0); + return false; } static inline bool @@ -571,6 +652,61 @@ addr_match_proto (const struct openvpn_sockaddr *a1, : addr_port_match (a1, a2); } +static inline void +addr_zero_host(struct openvpn_sockaddr *addr) +{ + switch(addr->addr.sa.sa_family) { + case AF_INET: + addr->addr.in4.sin_addr.s_addr = 0; + break; + case AF_INET6: + memset(&addr->addr.in6.sin6_addr, 0, sizeof (struct in6_addr)); + break; + } +} + +static inline void +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); +static inline int +af_addr_size(unsigned short af) +{ + switch(af) { + case AF_INET: return sizeof (struct sockaddr_in); + case AF_INET6: return sizeof (struct sockaddr_in6); + default: +#if 0 + /* could be called from socket_do_accept() with empty addr */ + msg (M_ERR, "Bad address family: %d\n", af); + ASSERT(0); +#endif + return 0; + } +} + static inline bool link_socket_actual_match (const struct link_socket_actual *a1, const struct link_socket_actual *a2) { @@ -609,7 +745,7 @@ socket_connection_reset (const struct link_socket *sock, int status) return true; else if (status < 0) { - const int err = openvpn_errno_socket (); + const int err = openvpn_errno (); #ifdef WIN32 return err == WSAECONNRESET || err == WSAECONNABORTED; #else @@ -627,14 +763,16 @@ link_socket_verify_incoming_addr (struct buffer *buf, { if (buf->len > 0) { - if (from_addr->dest.sa.sin_family != AF_INET) - return false; - if (!link_socket_actual_defined (from_addr)) - return false; - if (info->remote_float || !addr_defined (&info->lsa->remote)) - return true; - if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto)) - return true; + switch (from_addr->dest.addr.sa.sa_family) { + case AF_INET6: + case AF_INET: + if (!link_socket_actual_defined (from_addr)) + return false; + if (info->remote_float || !addr_defined (&info->lsa->remote)) + return true; + if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto)) + return true; + } } return false; } @@ -740,7 +878,7 @@ link_socket_read (struct link_socket *sock, int maxsize, struct link_socket_actual *from) { - if (sock->info.proto == PROTO_UDPv4) + if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */ { int res; @@ -751,10 +889,10 @@ link_socket_read (struct link_socket *sock, #endif return res; } - else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) + else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */ { /* from address was returned by accept */ - from->dest.sa = sock->info.lsa->actual.dest.sa; + addr_copy_sa(&from->dest, &sock->info.lsa->actual.dest); return link_socket_read_tcp (sock, buf); } else @@ -809,13 +947,14 @@ link_socket_write_udp_posix (struct link_socket *sock, struct buffer *buf, struct link_socket_actual *to); - if (sock->sockflags & SF_USE_IP_PKTINFO) + if (proto_is_udp(sock->info.proto) && (sock->sockflags & SF_USE_IP_PKTINFO) + && addr_defined_ipi(to)) return link_socket_write_udp_posix_sendmsg (sock, buf, to); else #endif return sendto (sock->sd, BPTR (buf), BLEN (buf), 0, - (struct sockaddr *) &to->dest.sa, - (socklen_t) sizeof (to->dest.sa)); + (struct sockaddr *) &to->dest.addr.sa, + (socklen_t) af_addr_size(to->dest.addr.sa.sa_family)); } static inline int @@ -846,11 +985,11 @@ link_socket_write (struct link_socket *sock, struct buffer *buf, struct link_socket_actual *to) { - if (sock->info.proto == PROTO_UDPv4) + if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */ { return link_socket_write_udp (sock, buf, to); } - else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) + else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */ { return link_socket_write_tcp (sock, buf, to); } diff --git a/socks.c b/src/openvpn/socks.c index 8287274..235982e 100644 --- a/socks.c +++ b/src/openvpn/socks.c @@ -30,6 +30,12 @@ * (Pierre Bourdon <delroth@gmail.com>) */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #ifdef ENABLE_SOCKS @@ -57,23 +63,10 @@ struct socks_proxy_info * socks_proxy_new (const char *server, int port, const char *authfile, - bool retry, - struct auto_proxy_info *auto_proxy_info) + bool retry) { struct socks_proxy_info *p; - if (auto_proxy_info) - { - if (!server) - { - if (!auto_proxy_info->socks.server) - return NULL; - - server = auto_proxy_info->socks.server; - port = auto_proxy_info->socks.port; - } - } - ALLOC_OBJ_CLEAR (p, struct socks_proxy_info); ASSERT (server); @@ -127,7 +120,7 @@ socks_username_password_auth (struct socks_proxy_info *p, if (size != strlen (to_send)) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()"); return false; } @@ -153,14 +146,14 @@ socks_username_password_auth (struct socks_proxy_info *p, /* timeout? */ if (status == 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired"); return false; } /* error */ if (status < 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()"); return false; } @@ -170,7 +163,7 @@ socks_username_password_auth (struct socks_proxy_info *p, /* error? */ if (size != 1) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()"); return false; } @@ -201,7 +194,7 @@ socks_handshake (struct socks_proxy_info *p, const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL); if (size != 4) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()"); return false; } @@ -227,14 +220,14 @@ socks_handshake (struct socks_proxy_info *p, /* timeout? */ if (status == 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port read timeout expired"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired"); return false; } /* error */ if (status < 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port read failed on select()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()"); return false; } @@ -244,7 +237,7 @@ socks_handshake (struct socks_proxy_info *p, /* error? */ if (size != 1) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port read failed on recv()"); + msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()"); return false; } @@ -299,9 +292,9 @@ recv_socks_reply (socket_descriptor_t sd, if (addr != NULL) { - addr->sa.sin_family = AF_INET; - addr->sa.sin_addr.s_addr = htonl (INADDR_ANY); - addr->sa.sin_port = htons (0); + addr->addr.in4.sin_family = AF_INET; + addr->addr.in4.sin_addr.s_addr = htonl (INADDR_ANY); + addr->addr.in4.sin_port = htons (0); } while (len < 4 + alen + 2) @@ -326,14 +319,14 @@ recv_socks_reply (socket_descriptor_t sd, /* timeout? */ if (status == 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_socks_reply: TCP port read timeout expired"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired"); return false; } /* error */ if (status < 0) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_socks_reply: TCP port read failed on select()"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()"); return false; } @@ -343,7 +336,7 @@ recv_socks_reply (socket_descriptor_t sd, /* error? */ if (size != 1) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_socks_reply: TCP port read failed on recv()"); + msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()"); return false; } @@ -388,8 +381,8 @@ recv_socks_reply (socket_descriptor_t sd, /* ATYP == 1 (IP V4 address) */ if (atyp == '\x01' && addr != NULL) { - memcpy (&addr->sa.sin_addr, buf + 4, sizeof (addr->sa.sin_addr)); - memcpy (&addr->sa.sin_port, buf + 8, sizeof (addr->sa.sin_port)); + memcpy (&addr->addr.in4.sin_addr, buf + 4, sizeof (addr->addr.in4.sin_addr)); + memcpy (&addr->addr.in4.sin_port, buf + 8, sizeof (addr->addr.in4.sin_port)); } @@ -428,7 +421,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p, const ssize_t size = send (sd, buf, 5 + len + 2, MSG_NOSIGNAL); if ((int)size != 5 + (int)len + 2) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "establish_socks_proxy_passthru: TCP port write failed on send()"); + msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()"); goto error; } } @@ -465,7 +458,7 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p, 10, MSG_NOSIGNAL); if (size != 10) { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "establish_socks_proxy_passthru: TCP port write failed on send()"); + msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()"); goto error; } } @@ -507,8 +500,8 @@ socks_process_incoming_udp (struct buffer *buf, if (atyp != 1) /* ATYP == 1 (IP V4) */ goto error; - buf_read (buf, &from->dest.sa.sin_addr, sizeof (from->dest.sa.sin_addr)); - buf_read (buf, &from->dest.sa.sin_port, sizeof (from->dest.sa.sin_port)); + buf_read (buf, &from->dest.addr.in4.sin_addr, sizeof (from->dest.addr.in4.sin_addr)); + buf_read (buf, &from->dest.addr.in4.sin_port, sizeof (from->dest.addr.in4.sin_port)); return; @@ -540,8 +533,8 @@ socks_process_outgoing_udp (struct buffer *buf, buf_write_u16 (&head, 0); /* RSV = 0 */ buf_write_u8 (&head, 0); /* FRAG = 0 */ buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */ - buf_write (&head, &to->dest.sa.sin_addr, sizeof (to->dest.sa.sin_addr)); - buf_write (&head, &to->dest.sa.sin_port, sizeof (to->dest.sa.sin_port)); + buf_write (&head, &to->dest.addr.in4.sin_addr, sizeof (to->dest.addr.in4.sin_addr)); + buf_write (&head, &to->dest.addr.in4.sin_port, sizeof (to->dest.addr.in4.sin_port)); return 10; } diff --git a/socks.h b/src/openvpn/socks.h index b748bb3..b55ff6f 100644 --- a/socks.h +++ b/src/openvpn/socks.h @@ -51,8 +51,7 @@ 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, - struct auto_proxy_info *auto_proxy_info); + bool retry); void socks_proxy_close (struct socks_proxy_info *sp); diff --git a/ssl.c b/src/openvpn/ssl.c index 6d9a9fd..19512c0 100644 --- a/ssl.c +++ b/src/openvpn/ssl.c @@ -6,6 +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> * * Additions for eurephia plugin done by: * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2008-2009 @@ -26,6 +27,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/** + * @file Control Channel SSL/Data channel negotiation Module + */ + /* * The routines in this file deal with dynamically negotiating * the data channel HMAC and cipher keys through a TLS session. @@ -34,11 +39,16 @@ * over the same TCP/UDP port. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) -#include "ssl.h" #include "error.h" #include "common.h" #include "integer.h" @@ -51,10 +61,12 @@ #include "gremlin.h" #include "pkcs11.h" #include "list.h" +#include "base64.h" +#include "route.h" -#ifdef WIN32 -#include "cryptoapi.h" -#endif +#include "ssl.h" +#include "ssl_verify.h" +#include "ssl_backend.h" #include "memdbg.h" @@ -101,68 +113,6 @@ show_tls_performance_stats(void) #endif -#ifdef BIO_DEBUG - -#warning BIO_DEBUG defined - -static FILE *biofp; /* GLOBAL */ -static bool biofp_toggle; /* GLOBAL */ -static time_t biofp_last_open; /* GLOBAL */ -static const int biofp_reopen_interval = 600; /* GLOBAL */ - -static void -close_biofp() -{ - if (biofp) - { - ASSERT (!fclose (biofp)); - biofp = NULL; - } -} - -static void -open_biofp() -{ - const time_t current = time (NULL); - const pid_t pid = getpid (); - - if (biofp_last_open + biofp_reopen_interval < current) - close_biofp(); - if (!biofp) - { - char fn[256]; - openvpn_snprintf(fn, sizeof(fn), "bio/%d-%d.log", pid, biofp_toggle); - biofp = fopen (fn, "w"); - ASSERT (biofp); - biofp_last_open = time (NULL); - biofp_toggle ^= 1; - } -} - -static void -bio_debug_data (const char *mode, BIO *bio, const uint8_t *buf, int len, const char *desc) -{ - struct gc_arena gc = gc_new (); - if (len > 0) - { - open_biofp(); - fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n", - mode, desc, time (NULL), (ptr_type)bio, len, format_hex (buf, len, 0, &gc)); - fflush (biofp); - } - gc_free (&gc); -} - -static void -bio_debug_oc (const char *mode, BIO *bio) -{ - open_biofp(); - fprintf(biofp, "BIO %s time=" time_format " bio=" ptr_format "\n", - mode, time (NULL), (ptr_type)bio); - fflush (biofp); -} - -#endif /* * Max number of bytes we will add @@ -202,55 +152,21 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame frame_set_mtu_dynamic (frame, 0, SET_MTU_TUN); } -/* - * Allocate space in SSL objects - * in which to store a struct tls_session - * pointer back to parent. - */ - -static int mydata_index; /* GLOBAL */ - -static void -ssl_set_mydata_index () -{ - mydata_index = SSL_get_ex_new_index (0, "struct session *", NULL, NULL, NULL); - ASSERT (mydata_index >= 0); -} - void init_ssl_lib () { - SSL_library_init (); - SSL_load_error_strings (); - OpenSSL_add_all_algorithms (); - - init_crypto_lib(); - - /* - * If you build the OpenSSL library and OpenVPN with - * CRYPTO_MDEBUG, you will get a listing of OpenSSL - * memory leaks on program termination. - */ -#ifdef CRYPTO_MDEBUG - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); -#endif + tls_init_lib (); - ssl_set_mydata_index (); + crypto_init_lib (); } void free_ssl_lib () { -#ifdef CRYPTO_MDEBUG - FILE* fp = fopen ("sdlog", "w"); - ASSERT (fp); - CRYPTO_mem_leaks_fp (fp); - fclose (fp); -#endif - - uninit_crypto_lib (); - EVP_cleanup (); - ERR_free_strings (); + crypto_uninit_lib (); + prng_uninit(); + + tls_free_lib(); } /* @@ -294,17 +210,35 @@ static char *auth_challenge; /* GLOBAL */ #endif void -auth_user_pass_setup (const char *auth_file) +auth_user_pass_setup (const char *auth_file, const struct static_challenge_info *sci) { auth_user_pass_enabled = true; if (!auth_user_pass.defined) { #if AUTO_USERID get_user_pass_auto_userid (&auth_user_pass, auth_file); -#elif defined(ENABLE_CLIENT_CR) - get_user_pass_cr (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE, auth_challenge); #else - get_user_pass (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE); +# ifdef ENABLE_CLIENT_CR + if (auth_challenge) /* dynamic challenge/response */ + get_user_pass_cr (&auth_user_pass, + auth_file, + UP_TYPE_AUTH, + GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_DYNAMIC_CHALLENGE, + auth_challenge); + else if (sci) /* static challenge response */ + { + int flags = GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_STATIC_CHALLENGE; + if (sci->flags & SC_ECHO) + flags |= GET_USER_PASS_STATIC_CHALLENGE_ECHO; + get_user_pass_cr (&auth_user_pass, + auth_file, + UP_TYPE_AUTH, + flags, + sci->challenge_text); + } + else +# endif + get_user_pass (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE); #endif } } @@ -320,15 +254,27 @@ ssl_set_auth_nocache (void) } /* + * Set an authentication token + */ +void +ssl_set_auth_token (const char *token) +{ + set_auth_token (&auth_user_pass, token); +} + +/* * Forget private key password AND auth-user-pass username/password. */ void -ssl_purge_auth (void) +ssl_purge_auth (const bool auth_user_pass_only) { -#ifdef USE_PKCS11 - pkcs11_logout (); + if (!auth_user_pass_only) + { +#ifdef ENABLE_PKCS11 + pkcs11_logout (); #endif - purge_user_pass (&passbuf, true); + purge_user_pass (&passbuf, true); + } purge_user_pass (&auth_user_pass, true); #ifdef ENABLE_CLIENT_CR ssl_purge_auth_challenge(); @@ -354,1655 +300,109 @@ ssl_put_auth_challenge (const char *cr_str) #endif /* - * 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) - { - msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength); - rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL); - } - return (rsa_tmp); -} - -/* - * Cert hash functions - */ -static void -cert_hash_remember (struct tls_session *session, const int error_depth, const unsigned char *sha1_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); - 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)); - } - } - gc_free (&gc); -} -#endif - -static void -cert_hash_free (struct cert_hash_set *chs) -{ - if (chs) - { - int i; - for (i = 0; i < MAX_CERT_DEPTH; ++i) - free (chs->ch[i]); - free (chs); - } -} - -static bool -cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2) -{ - if (chs1 && chs2) - { - int i; - for (i = 0; i < MAX_CERT_DEPTH; ++i) - { - const struct cert_hash *ch1 = chs1->ch[i]; - const struct cert_hash *ch2 = chs2->ch[i]; - - if (!ch1 && !ch2) - continue; - else if (ch1 && ch2 && !memcmp (ch1->sha1_hash, ch2->sha1_hash, SHA_DIGEST_LENGTH)) - continue; - else - return false; - } - return true; - } - else if (!chs1 && !chs2) - return true; - else - return false; -} - -static struct cert_hash_set * -cert_hash_copy (const struct cert_hash_set *chs) -{ - struct cert_hash_set *dest = NULL; - if (chs) - { - int i; - ALLOC_OBJ_CLEAR (dest, struct cert_hash_set); - for (i = 0; i < MAX_CERT_DEPTH; ++i) - { - const struct cert_hash *ch = chs->ch[i]; - if (ch) - { - ALLOC_OBJ (dest->ch[i], struct cert_hash); - memcpy (dest->ch[i]->sha1_hash, ch->sha1_hash, SHA_DIGEST_LENGTH); - } - } - } - return dest; -} - -/* - * Extract a field from an X509 subject name. - * - * Example: - * - * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net - * - * The common name is 'Test-CA' - * - * Return true on success, false on error (insufficient buffer size in 'out' - * to contain result is grounds for error). - */ -static bool -extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, int size) -{ - int lastpos = -1; - 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); - - ASSERT (size > 0); - *out = '\0'; - do { - lastpos = tmp; - tmp = X509_NAME_get_index_by_NID(x509, nid, lastpos); - } while (tmp > -1); - - /* Nothing found */ - if (lastpos == -1) - return false; - - x509ne = X509_NAME_get_entry(x509, lastpos); - if (!x509ne) - return false; - - asn1 = X509_NAME_ENTRY_get_data(x509ne); - if (!asn1) - return false; - tmp = ASN1_STRING_to_UTF8(&buf, asn1); - if (tmp <= 0) - return false; - - strncpynt(out, (char *)buf, size); - - { - const bool ret = (strlen ((char *)buf) < size); - OPENSSL_free (buf); - return ret; - } -} - -/* - * Save X509 fields to environment, using the naming convention: - * - * X509_{cert_depth}_{name}={value} - */ -static void -setenv_x509 (struct env_set *es, const int error_depth, X509_NAME *x509) -{ - int i, n; - int fn_nid; - ASN1_OBJECT *fn; - ASN1_STRING *val; - X509_NAME_ENTRY *ent; - const char *objbuf; - unsigned char *buf; - char *name_expand; - size_t name_expand_size; - - n = X509_NAME_entry_count (x509); - for (i = 0; i < n; ++i) - { - ent = X509_NAME_get_entry (x509, i); - if (!ent) - continue; - fn = X509_NAME_ENTRY_get_object (ent); - if (!fn) - continue; - val = X509_NAME_ENTRY_get_data (ent); - if (!val) - continue; - fn_nid = OBJ_obj2nid (fn); - if (fn_nid == NID_undef) - continue; - objbuf = OBJ_nid2sn (fn_nid); - if (!objbuf) - continue; - 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) - continue; - name_expand_size = 64 + strlen (objbuf); - name_expand = (char *) malloc (name_expand_size); - check_malloc_return (name_expand); - openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", error_depth, objbuf); - string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); - string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_'); - setenv_str (es, name_expand, (char*)buf); - free (name_expand); - OPENSSL_free (buf); - } -} - -static void -setenv_untrusted (struct tls_session *session) -{ - setenv_link_socket_actual (session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT); -} - -static void -set_common_name (struct tls_session *session, const char *common_name) -{ - if (session->common_name) - { - free (session->common_name); - session->common_name = NULL; -#ifdef ENABLE_PF - session->common_name_hashval = 0; -#endif - } - if (common_name) - { - session->common_name = string_alloc (common_name, NULL); -#ifdef ENABLE_PF - { - const uint32_t len = (uint32_t) strlen (common_name); - if (len) - session->common_name_hashval = hash_func ((const uint8_t*)common_name, len+1, 0); - else - session->common_name_hashval = 0; - } -#endif - } -} - -#if OPENSSL_VERSION_NUMBER >= 0x00907000L - -bool verify_cert_eku (X509 *x509, const char * const expected_oid) { - - EXTENDED_KEY_USAGE *eku = NULL; - bool fFound = false; - - if ((eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i (x509, NID_ext_key_usage, NULL, NULL)) == NULL) { - msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); - } - else { - int i; - - msg (D_HANDSHAKE, "Validating certificate extended key usage"); - for(i = 0; !fFound && i < sk_ASN1_OBJECT_num (eku); i++) { - ASN1_OBJECT *oid = sk_ASN1_OBJECT_value (eku, i); - char szOid[1024]; - - if (!fFound && OBJ_obj2txt (szOid, sizeof (szOid), oid, 0) != -1) { - msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", szOid, expected_oid); - if (!strcmp (expected_oid, szOid)) { - fFound = true; - } - } - if (!fFound && OBJ_obj2txt (szOid, sizeof (szOid), oid, 1) != -1) { - msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", szOid, expected_oid); - if (!strcmp (expected_oid, szOid)) { - fFound = true; - } - } - } - } - - if (eku != NULL) { - sk_ASN1_OBJECT_pop_free (eku, ASN1_OBJECT_free); - } - - return fFound; -} - -bool verify_cert_ku (X509 *x509, const unsigned * const expected_ku, int expected_len) { - - ASN1_BIT_STRING *ku = NULL; - bool fFound = false; - - if ((ku = (ASN1_BIT_STRING *)X509_get_ext_d2i (x509, NID_key_usage, NULL, NULL)) == NULL) { - msg (D_HANDSHAKE, "Certificate does not have key usage extension"); - } - else { - unsigned nku = 0; - int i; - for (i=0;i<8;i++) { - if (ASN1_BIT_STRING_get_bit (ku, i)) { - nku |= 1<<(7-i); - } - } - - /* - * Fixup if no LSB bits - */ - if ((nku & 0xff) == 0) { - nku >>= 8; - } - - msg (D_HANDSHAKE, "Validating certificate key usage"); - for (i=0;!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 = true; - } - } - } - } - - if (ku != NULL) { - ASN1_BIT_STRING_free (ku); - } - - return fFound; -} - -#endif /* OPENSSL_VERSION_NUMBER */ - -/* - * nsCertType checking - */ - -#define verify_nsCertType(x, usage) (((x)->ex_flags & EXFLAG_NSCERT) && ((x)->ex_nscert & (usage))) - -static const char * -print_nsCertType (int type) -{ - switch (type) - { - case NS_SSL_SERVER: - return "SERVER"; - case NS_SSL_CLIENT: - return "CLIENT"; - default: - return "?"; - } -} - -static void -string_mod_sslname (char *str, const unsigned int restrictive_flags, const unsigned int ssl_flags) -{ - if (ssl_flags & SSLF_NO_NAME_REMAPPING) - string_mod (str, CC_PRINT, CC_CRLF, '_'); - else - string_mod (str, restrictive_flags, 0, '_'); -} - -/* Get peer cert and store it in pem format in a temporary file - * in tmp_dir - */ - -const char * -get_peer_cert(X509_STORE_CTX *ctx, const char *tmp_dir, struct gc_arena *gc) -{ - X509 *peercert; - FILE *peercert_file; - const char *peercert_filename=""; - - if(!tmp_dir) - return NULL; - - /* get peer cert */ - peercert = X509_STORE_CTX_get_current_cert(ctx); - if(!peercert) - { - msg (M_ERR, "Unable to get peer certificate from current context"); - return NULL; - } - - /* create tmp file to store peer cert */ - peercert_filename = create_temp_file (tmp_dir, "pcf", gc); - - /* write peer-cert in tmp-file */ - peercert_file = fopen(peercert_filename, "w+"); - if(!peercert_file) - { - msg (M_ERR, "Failed to open temporary file : %s", peercert_filename); - return NULL; - } - if(PEM_write_X509(peercert_file,peercert)<0) - { - msg (M_ERR, "Failed to write peer certificate in PEM format"); - fclose(peercert_file); - return NULL; - } - - fclose(peercert_file); - return peercert_filename; -} - -char * x509_username_field; /* GLOBAL */ - -/* - * Our verify callback function -- check - * that an incoming peer certificate is good. + * Initialize SSL context. + * All files are in PEM format. */ - -static int -verify_callback (int preverify_ok, X509_STORE_CTX * ctx) -{ - char *subject = NULL; - char envname[64]; - char common_name[TLS_USERNAME_LEN]; - SSL *ssl; - struct tls_session *session; - const struct tls_options *opt; - const int max_depth = MAX_CERT_DEPTH; - struct argv argv = argv_new (); - - /* get the tls_session pointer */ - ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - ASSERT (ssl); - session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index); - ASSERT (session); - opt = session->opt; - ASSERT (opt); - - session->verified = false; - - /* get the X509 name */ - subject = X509_NAME_oneline (X509_get_subject_name (ctx->current_cert), NULL, 0); - if (!subject) - { - msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 subject string from certificate", ctx->error_depth); - goto err; - } - - /* Save X509 fields in environment */ - setenv_x509 (opt->es, ctx->error_depth, X509_get_subject_name (ctx->current_cert)); - - /* enforce character class restrictions in X509 name */ - string_mod_sslname (subject, X509_NAME_CHAR_CLASS, opt->ssl_flags); - string_replace_leading (subject, '-', '_'); - - /* extract the username (default is CN) */ - if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), x509_username_field, common_name, sizeof(common_name))) - { - if (!ctx->error_depth) - { - msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 subject string ('%s') -- note that the username length is limited to %d characters", - x509_username_field, - subject, - TLS_USERNAME_LEN); - goto err; - } - } - - - string_mod_sslname (common_name, COMMON_NAME_CHAR_CLASS, opt->ssl_flags); - - cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash); - -#if 0 /* print some debugging info */ - { - struct gc_arena gc = gc_new (); - msg (M_INFO, "LOCAL OPT[%d]: %s", ctx->error_depth, opt->local_options); - msg (M_INFO, "X509[%d]: %s", ctx->error_depth, subject); - msg (M_INFO, "SHA1[%d]: %s", ctx->error_depth, format_hex(ctx->current_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, &gc)); - gc_free (&gc); - } -#endif - - /* did peer present cert which was signed our root cert? */ - if (!preverify_ok) - { - /* 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); - goto err; /* Reject connection */ - } - - /* warn if cert chain is too deep */ - if (ctx->error_depth >= max_depth) - { - msg (D_TLS_ERRORS, "TLS Error: Convoluted certificate chain detected with depth [%d] greater than %d", ctx->error_depth, max_depth); - goto err; /* Reject connection */ - } - - /* save common name in session object */ - if (ctx->error_depth == 0) - set_common_name (session, common_name); - - /* export subject name string as environmental variable */ - session->verify_maxlevel = max_int (session->verify_maxlevel, ctx->error_depth); - openvpn_snprintf (envname, sizeof(envname), "tls_id_%d", ctx->error_depth); - setenv_str (opt->es, envname, subject); - -#ifdef ENABLE_EUREPHIA - /* export X509 cert SHA1 fingerprint */ - { - struct gc_arena gc = gc_new (); - openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", ctx->error_depth); - setenv_str (opt->es, envname, - format_hex_ex(ctx->current_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc)); - gc_free(&gc); - } -#endif -#if 0 - /* export common name string as environmental variable */ - openvpn_snprintf (envname, sizeof(envname), "tls_common_name_%d", ctx->error_depth); - setenv_str (opt->es, envname, common_name); -#endif - - /* export serial number as environmental variable */ - { - BIO *bio = NULL; - char serial[100]; - int n1, n2; - - CLEAR (serial); - if ((bio = BIO_new (BIO_s_mem ())) == NULL) - { - msg (M_WARN, "CALLBACK: Cannot create BIO (for tls_serial_%d)", ctx->error_depth); - } - else - { - /* "prints" the serial number onto the BIO and read it back */ - if ( ! ( ( (n1 = i2a_ASN1_INTEGER(bio, X509_get_serialNumber (ctx->current_cert))) >= 0 ) && - ( (n2 = BIO_read (bio, serial, sizeof (serial)-1)) >= 0 ) && - ( n1 == n2 ) ) ) - { - msg (M_WARN, "CALLBACK: Error reading/writing BIO (for tls_serial_%d)", ctx->error_depth); - CLEAR (serial); /* empty string */ - } - - openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", ctx->error_depth); - setenv_str (opt->es, envname, serial); - BIO_free(bio); - } - } - - /* export current untrusted IP */ - setenv_untrusted (session); - - /* verify certificate nsCertType */ - if (opt->ns_cert_type && ctx->error_depth == 0) - { - if (verify_nsCertType (ctx->current_cert, opt->ns_cert_type)) - { - msg (D_HANDSHAKE, "VERIFY OK: nsCertType=%s", - print_nsCertType (opt->ns_cert_type)); - } - else - { - msg (D_HANDSHAKE, "VERIFY nsCertType ERROR: %s, require nsCertType=%s", - subject, print_nsCertType (opt->ns_cert_type)); - goto err; /* Reject connection */ - } - } - -#if OPENSSL_VERSION_NUMBER >= 0x00907000L - - /* verify certificate ku */ - if (opt->remote_cert_ku[0] != 0 && ctx->error_depth == 0) - { - if (verify_cert_ku (ctx->current_cert, opt->remote_cert_ku, MAX_PARMS)) - { - msg (D_HANDSHAKE, "VERIFY KU OK"); - } - else - { - msg (D_HANDSHAKE, "VERIFY KU ERROR"); - goto err; /* Reject connection */ - } - } - - /* verify certificate eku */ - if (opt->remote_cert_eku != NULL && ctx->error_depth == 0) - { - if (verify_cert_eku (ctx->current_cert, opt->remote_cert_eku)) - { - msg (D_HANDSHAKE, "VERIFY EKU OK"); - } - else - { - msg (D_HANDSHAKE, "VERIFY EKU ERROR"); - goto err; /* Reject connection */ - } - } - -#endif /* OPENSSL_VERSION_NUMBER */ - - /* verify X509 name or common name against --tls-remote */ - if (opt->verify_x509name && strlen (opt->verify_x509name) > 0 && ctx->error_depth == 0) - { - if (strcmp (opt->verify_x509name, subject) == 0 - || strncmp (opt->verify_x509name, common_name, strlen (opt->verify_x509name)) == 0) - msg (D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject); - else - { - msg (D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s", - subject, opt->verify_x509name); - goto err; /* Reject connection */ - } - } - - /* call --tls-verify plug-in(s) */ - if (plugin_defined (opt->plugins, OPENVPN_PLUGIN_TLS_VERIFY)) - { - int ret; - - argv_printf (&argv, "%d %s", - ctx->error_depth, - subject); - - ret = plugin_call (opt->plugins, OPENVPN_PLUGIN_TLS_VERIFY, &argv, NULL, opt->es); - - if (ret == OPENVPN_PLUGIN_FUNC_SUCCESS) - { - msg (D_HANDSHAKE, "VERIFY PLUGIN OK: depth=%d, %s", - ctx->error_depth, subject); - } - else - { - msg (D_HANDSHAKE, "VERIFY PLUGIN ERROR: depth=%d, %s", - ctx->error_depth, subject); - goto err; /* Reject connection */ - } - } - - /* run --tls-verify script */ - if (opt->verify_command) - { - const char *tmp_file = NULL; - struct gc_arena gc; - int ret; - - setenv_str (opt->es, "script_type", "tls-verify"); - - if (opt->verify_export_cert) - { - gc = gc_new(); - if ((tmp_file=get_peer_cert(ctx, opt->verify_export_cert,&gc))) - { - setenv_str(opt->es, "peer_cert", tmp_file); - } - } - - argv_printf (&argv, "%sc %d %s", - opt->verify_command, - ctx->error_depth, - subject); - argv_msg_prefix (D_TLS_DEBUG, &argv, "TLS: executing verify command"); - ret = openvpn_run_script (&argv, opt->es, 0, "--tls-verify script"); - - if (opt->verify_export_cert) - { - if (tmp_file) - delete_file(tmp_file); - gc_free(&gc); - } - - if (ret) - { - msg (D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s", - ctx->error_depth, subject); - } - else - { - msg (D_HANDSHAKE, "VERIFY SCRIPT ERROR: depth=%d, %s", - ctx->error_depth, subject); - goto err; /* Reject connection */ - } - } - - /* check peer cert against CRL */ - if (opt->crl_file) - { - X509_CRL *crl=NULL; - X509_REVOKED *revoked; - BIO *in=NULL; - int n,i,retval = 0; - - in=BIO_new(BIO_s_file()); - - if (in == NULL) { - msg (M_ERR, "CRL: BIO err"); - goto end; - } - if (BIO_read_filename(in, opt->crl_file) <= 0) { - msg (M_ERR, "CRL: cannot read: %s", opt->crl_file); - goto end; - } - crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); - if (crl == NULL) { - msg (M_ERR, "CRL: cannot read CRL from file %s", opt->crl_file); - goto end; - } - - if (X509_NAME_cmp(X509_CRL_get_issuer(crl), X509_get_issuer_name(ctx->current_cert)) != 0) { - msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of certificate %s", opt->crl_file, subject); - retval = 1; - 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(ctx->current_cert)) == 0) { - msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED",subject); - goto end; - } - } - - retval = 1; - msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); - - end: - - BIO_free(in); - if (crl) - X509_CRL_free (crl); - if (!retval) - goto err; - } - - msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", ctx->error_depth, subject); - - session->verified = true; - OPENSSL_free (subject); - argv_reset (&argv); - return 1; /* Accept connection */ - - err: - ERR_clear_error (); - OPENSSL_free (subject); - argv_reset (&argv); - return 0; /* Reject connection */ -} - -void -tls_set_common_name (struct tls_multi *multi, const char *common_name) -{ - if (multi) - set_common_name (&multi->session[TM_ACTIVE], common_name); -} - -const char * -tls_common_name (const struct tls_multi *multi, const bool null) -{ - const char *ret = NULL; - if (multi) - ret = multi->session[TM_ACTIVE].common_name; - if (ret && strlen (ret)) - return ret; - else if (null) - return NULL; - else - return "UNDEF"; -} - void -tls_lock_common_name (struct tls_multi *multi) +init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) { - const char *cn = multi->session[TM_ACTIVE].common_name; - if (cn && !multi->locked_cn) - multi->locked_cn = string_alloc (cn, NULL); -} + ASSERT(NULL != new_ctx); -void -tls_lock_cert_hash_set (struct tls_multi *multi) -{ - const struct cert_hash_set *chs = multi->session[TM_ACTIVE].cert_hash_set; - if (chs && !multi->locked_cert_hash_set) - multi->locked_cert_hash_set = cert_hash_copy (chs); -} - -static bool -tls_lock_username (struct tls_multi *multi, const char *username) -{ - if (multi->locked_username) - { - if (!username || strcmp (username, multi->locked_username)) - { - msg (D_TLS_ERRORS, "TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled", - multi->locked_username, - np(username)); - - /* disable the tunnel */ - tls_deauthenticate (multi); - return false; - } - } - else - { - if (username) - multi->locked_username = string_alloc (username, NULL); - } - return true; -} + tls_clear_error(); -#ifdef ENABLE_DEF_AUTH -/* key_state_test_auth_control_file return values, - NOTE: acf_merge indexing depends on these values */ -#define ACF_UNDEFINED 0 -#define ACF_SUCCEEDED 1 -#define ACF_DISABLED 2 -#define ACF_FAILED 3 -#endif - -#ifdef MANAGEMENT_DEF_AUTH -static void -man_def_auth_set_client_reason (struct tls_multi *multi, const char *client_reason) -{ - if (multi->client_reason) + if (options->tls_server) { - free (multi->client_reason); - multi->client_reason = NULL; + tls_ctx_server_new(new_ctx); + tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline); } - if (client_reason && strlen (client_reason)) - multi->client_reason = string_alloc (client_reason, NULL); -} - -static inline unsigned int -man_def_auth_test (const struct key_state *ks) -{ - if (management_enable_def_auth (management)) - return ks->mda_status; - else - return ACF_DISABLED; -} -#endif - -#ifdef PLUGIN_DEF_AUTH - -/* - * auth_control_file functions - */ - -static void -key_state_rm_auth_control_file (struct key_state *ks) -{ - if (ks && ks->auth_control_file) + else /* if client */ { - delete_file (ks->auth_control_file); - free (ks->auth_control_file); - ks->auth_control_file = NULL; + tls_ctx_client_new(new_ctx); } -} - -static void -key_state_gen_auth_control_file (struct key_state *ks, const struct tls_options *opt) -{ - struct gc_arena gc = gc_new (); - const char *acf; - key_state_rm_auth_control_file (ks); - acf = create_temp_file (opt->tmp_dir, "acf", &gc); - if( acf ) { - ks->auth_control_file = string_alloc (acf, NULL); - setenv_str (opt->es, "auth_control_file", ks->auth_control_file); - } /* FIXME: Should have better error handling? */ - gc_free (&gc); -} + tls_ctx_set_options(new_ctx, options->ssl_flags); -static unsigned int -key_state_test_auth_control_file (struct key_state *ks) -{ - if (ks && ks->auth_control_file) + if (options->pkcs12_file) { - unsigned int ret = ks->auth_control_status; - if (ret == ACF_UNDEFINED) - { - FILE *fp = fopen (ks->auth_control_file, "r"); - if (fp) - { - const int c = fgetc (fp); - if (c == '1') - ret = ACF_SUCCEEDED; - else if (c == '0') - ret = ACF_FAILED; - fclose (fp); - ks->auth_control_status = ret; - } - } - return ret; + if (0 != tls_ctx_load_pkcs12(new_ctx, options->pkcs12_file, + options->pkcs12_file_inline, !options->ca_file)) + goto err; } - return ACF_DISABLED; -} - -#endif - -/* - * Return current session authentication state. Return - * value is TLS_AUTHENTICATION_x. - */ - -int -tls_authentication_status (struct tls_multi *multi, const int latency) -{ - bool deferred = false; - bool success = false; - bool active = false; - -#ifdef ENABLE_DEF_AUTH - static const unsigned char acf_merge[] = - { - ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_UNDEFINED */ - ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_SUCCEEDED */ - ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_DISABLED */ - ACF_FAILED, /* s1=ACF_UNDEFINED s2=ACF_FAILED */ - ACF_UNDEFINED, /* s1=ACF_SUCCEEDED s2=ACF_UNDEFINED */ - ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_SUCCEEDED */ - ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_DISABLED */ - ACF_FAILED, /* s1=ACF_SUCCEEDED s2=ACF_FAILED */ - ACF_UNDEFINED, /* s1=ACF_DISABLED s2=ACF_UNDEFINED */ - ACF_SUCCEEDED, /* s1=ACF_DISABLED s2=ACF_SUCCEEDED */ - ACF_DISABLED, /* s1=ACF_DISABLED s2=ACF_DISABLED */ - ACF_FAILED, /* s1=ACF_DISABLED s2=ACF_FAILED */ - ACF_FAILED, /* s1=ACF_FAILED s2=ACF_UNDEFINED */ - ACF_FAILED, /* s1=ACF_FAILED s2=ACF_SUCCEEDED */ - ACF_FAILED, /* s1=ACF_FAILED s2=ACF_DISABLED */ - ACF_FAILED /* s1=ACF_FAILED s2=ACF_FAILED */ - }; -#endif - - if (multi) +#ifdef ENABLE_PKCS11 + else if (options->pkcs11_providers[0]) { - int i; - -#ifdef ENABLE_DEF_AUTH - if (latency && multi->tas_last && multi->tas_last + latency >= now) - return TLS_AUTHENTICATION_UNDEFINED; - multi->tas_last = now; -#endif - - for (i = 0; i < KEY_SCAN_SIZE; ++i) + if (!tls_ctx_use_pkcs11 (new_ctx, options->pkcs11_id_management, options->pkcs11_id)) { - struct key_state *ks = multi->key_scan[i]; - if (DECRYPT_KEY_ENABLED (multi, ks)) - { - active = true; - if (ks->authenticated) - { -#ifdef ENABLE_DEF_AUTH - unsigned int s1 = ACF_DISABLED; - unsigned int s2 = ACF_DISABLED; -#ifdef PLUGIN_DEF_AUTH - s1 = key_state_test_auth_control_file (ks); -#endif -#ifdef MANAGEMENT_DEF_AUTH - s2 = man_def_auth_test (ks); -#endif - ASSERT (s1 < 4 && s2 < 4); - switch (acf_merge[(s1<<2) + s2]) - { - case ACF_SUCCEEDED: - case ACF_DISABLED: - success = true; - ks->auth_deferred = false; - break; - case ACF_UNDEFINED: - if (now < ks->auth_deferred_expire) - deferred = true; - break; - case ACF_FAILED: - ks->authenticated = false; - break; - default: - ASSERT (0); - } -#else - success = true; -#endif - } - } + msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface", + options->pkcs11_id); + goto err; } } - -#if 0 - dmsg (D_TLS_ERRORS, "TAS: a=%d s=%d d=%d", active, success, deferred); #endif - - if (success) - return TLS_AUTHENTICATION_SUCCEEDED; - else if (!active || deferred) - return TLS_AUTHENTICATION_DEFERRED; - else - return TLS_AUTHENTICATION_FAILED; -} - -#ifdef MANAGEMENT_DEF_AUTH -/* - * For deferred auth, this is where the management interface calls (on server) - * to indicate auth failure/success. - */ -bool -tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason) -{ - bool ret = false; - if (multi) +#ifdef ENABLE_CRYPTOAPI + else if (options->cryptoapi_cert) { - int i; - man_def_auth_set_client_reason (multi, client_reason); - for (i = 0; i < KEY_SCAN_SIZE; ++i) - { - struct key_state *ks = multi->key_scan[i]; - if (ks->mda_key_id == mda_key_id) - { - ks->mda_status = auth ? ACF_SUCCEEDED : ACF_FAILED; - ret = true; - } - } + tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert); } - return ret; -} #endif - -void -tls_deauthenticate (struct tls_multi *multi) -{ - if (multi) +#ifdef MANAGMENT_EXTERNAL_KEY + else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file) { - int i, j; - for (i = 0; i < TM_SIZE; ++i) - for (j = 0; j < KS_SIZE; ++j) - multi->session[i].key[j].authenticated = false; - } -} + openvpn_x509_cert_t *my_cert = NULL; + tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, + &my_cert); + tls_ctx_use_external_private_key(new_ctx, my_cert); -/* - * Print debugging information on SSL/TLS session negotiation. - */ -static void -info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret) -{ - if (where & SSL_CB_LOOP) - { - dmsg (D_HANDSHAKE_VERBOSE, "SSL state (%s): %s", - where & SSL_ST_CONNECT ? "connect" : - where & SSL_ST_ACCEPT ? "accept" : - "undefined", SSL_state_string_long (s)); + tls_ctx_free_cert_file(my_cert); } - else if (where & SSL_CB_ALERT) - { - dmsg (D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s", - where & SSL_CB_READ ? "read" : "write", - SSL_alert_type_string_long (ret), - SSL_alert_desc_string_long (ret)); - } -} - -#if ENABLE_INLINE_FILES - -static int -use_inline_load_verify_locations (SSL_CTX *ctx, const char *ca_string) -{ - X509_STORE *store = NULL; - X509* cert = NULL; - BIO *in = NULL; - int ret = 0; - - in = BIO_new_mem_buf ((char *)ca_string, -1); - if (!in) - goto err; - - for (;;) - { - if (!PEM_read_bio_X509 (in, &cert, 0, NULL)) - { - ret = 1; - break; - } - if (!cert) - break; - - store = SSL_CTX_get_cert_store (ctx); - if (!store) - break; - - if (!X509_STORE_add_cert (store, cert)) - break; - - if (cert) - { - X509_free (cert); - cert = NULL; - } - } - - err: - if (cert) - X509_free (cert); - if (in) - BIO_free (in); - return ret; -} - -static int -xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b) -{ - return(X509_NAME_cmp(*a,*b)); -} - -static STACK_OF(X509_NAME) * -use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string) -{ - BIO *in = NULL; - X509 *x = NULL; - X509_NAME *xn = NULL; - STACK_OF(X509_NAME) *ret = NULL, *sk; - - sk=sk_X509_NAME_new(xname_cmp); - - in = BIO_new_mem_buf ((char *)ca_string, -1); - if (!in) - goto err; - - if ((sk == NULL) || (in == NULL)) - goto err; - - for (;;) - { - if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL) - break; - if (ret == NULL) - { - ret = sk_X509_NAME_new_null(); - if (ret == NULL) - goto err; - } - if ((xn=X509_get_subject_name(x)) == NULL) goto err; - /* check for duplicates */ - xn=X509_NAME_dup(xn); - if (xn == NULL) goto err; - if (sk_X509_NAME_find(sk,xn) >= 0) - X509_NAME_free(xn); - else - { - sk_X509_NAME_push(sk,xn); - sk_X509_NAME_push(ret,xn); - } - } - - if (0) - { - err: - if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free); - ret=NULL; - } - if (sk != NULL) sk_X509_NAME_free(sk); - if (in != NULL) BIO_free(in); - if (x != NULL) X509_free(x); - if (ret != NULL) - ERR_clear_error(); - return(ret); -} - -static int -use_inline_certificate_file (SSL_CTX *ctx, const char *cert_string) -{ - BIO *in = NULL; - X509 *x = NULL; - int ret = 0; - - in = BIO_new_mem_buf ((char *)cert_string, -1); - if (!in) - goto end; - - x = PEM_read_bio_X509 (in, - NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (!x) - goto end; - - ret = SSL_CTX_use_certificate(ctx, x); - - end: - if (x) - X509_free (x); - if (in) - BIO_free (in); - return ret; -} - -static int -use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string) -{ - BIO *in = NULL; - EVP_PKEY *pkey = NULL; - int ret = 0; - - in = BIO_new_mem_buf ((char *)key_string, -1); - if (!in) - goto end; - - pkey = PEM_read_bio_PrivateKey (in, - NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (!pkey) - goto end; - - ret = SSL_CTX_use_PrivateKey (ctx, pkey); - - end: - if (pkey) - EVP_PKEY_free (pkey); - if (in) - BIO_free (in); - return ret; -} - -#endif - -/* - * Initialize SSL context. - * All files are in PEM format. - */ -SSL_CTX * -init_ssl (const struct options *options) -{ - SSL_CTX *ctx = NULL; - DH *dh; - BIO *bio; - bool using_cert_file = false; - - ERR_clear_error (); - - if (options->tls_server) - { - ctx = SSL_CTX_new (TLSv1_server_method ()); - if (ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method"); - - SSL_CTX_set_tmp_rsa_callback (ctx, tmp_rsa_cb); - -#if ENABLE_INLINE_FILES - if (!strcmp (options->dh_file, INLINE_FILE_TAG) && options->dh_file_inline) - { - if (!(bio = BIO_new_mem_buf ((char *)options->dh_file_inline, -1))) - msg (M_SSLERR, "Cannot open memory BIO for inline DH parameters"); - } - else #endif - { - /* Get Diffie Hellman Parameters */ - if (!(bio = BIO_new_file (options->dh_file, "r"))) - msg (M_SSLERR, "Cannot open %s for DH parameters", options->dh_file); - } - - dh = PEM_read_bio_DHparams (bio, NULL, NULL, NULL); - BIO_free (bio); - if (!dh) - msg (M_SSLERR, "Cannot load DH parameters from %s", options->dh_file); - if (!SSL_CTX_set_tmp_dh (ctx, dh)) - msg (M_SSLERR, "SSL_CTX_set_tmp_dh"); - msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key", - 8 * DH_size (dh)); - DH_free (dh); - } - else /* if client */ - { - ctx = SSL_CTX_new (TLSv1_client_method ()); - if (ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method"); - } - - /* Set SSL options */ - SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_OFF); - SSL_CTX_set_options (ctx, SSL_OP_SINGLE_DH_USE); - - /* Set callback for getting password from user to decrypt private key */ - SSL_CTX_set_default_passwd_cb (ctx, pem_password_callback); - - if (options->pkcs12_file) + else { - /* Use PKCS #12 file for key, cert and CA certs */ - - FILE *fp; - EVP_PKEY *pkey; - X509 *cert; - STACK_OF(X509) *ca = NULL; - PKCS12 *p12=NULL; - int i; - char password[256]; - -#if ENABLE_INLINE_FILES - if (!strcmp (options->pkcs12_file, INLINE_FILE_TAG) && options->pkcs12_file_inline) - { - BIO *b64 = BIO_new (BIO_f_base64()); - BIO *bio = BIO_new_mem_buf ((void *)options->pkcs12_file_inline, (int)strlen(options->pkcs12_file_inline)); - ASSERT(b64 && bio); - BIO_push (b64, bio); - p12 = d2i_PKCS12_bio(b64, NULL); - if (!p12) - msg (M_SSLERR, "Error reading inline PKCS#12 file"); - BIO_free (b64); - BIO_free (bio); - } - else -#endif + /* Load Certificate */ + if (options->cert_file) { - /* Load the PKCS #12 file */ - if (!(fp = fopen(options->pkcs12_file, "rb"))) - msg (M_SSLERR, "Error opening file %s", options->pkcs12_file); - p12 = d2i_PKCS12_fp(fp, NULL); - fclose (fp); - if (!p12) - msg (M_SSLERR, "Error reading PKCS#12 file %s", options->pkcs12_file); + tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, NULL); } - /* Parse the PKCS #12 file */ - if (!PKCS12_parse(p12, "", &pkey, &cert, &ca)) - { - pem_password_callback (password, sizeof(password) - 1, 0, NULL); - /* Reparse the PKCS #12 file with password */ - ca = NULL; - if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) - { -#ifdef ENABLE_MANAGEMENT - if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE)) - management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); -#endif - PKCS12_free(p12); - msg (M_INFO, "OpenSSL ERROR code: %d", (ERR_GET_REASON (ERR_peek_error()))); // fixme - goto err; - } - } - PKCS12_free(p12); - - /* Load Certificate */ - if (!SSL_CTX_use_certificate (ctx, cert)) - msg (M_SSLERR, "Cannot use certificate"); - /* Load Private Key */ - if (!SSL_CTX_use_PrivateKey (ctx, pkey)) - msg (M_SSLERR, "Cannot use private key"); - warn_if_group_others_accessible (options->pkcs12_file); - - /* Check Private Key */ - if (!SSL_CTX_check_private_key (ctx)) - msg (M_SSLERR, "Private key does not match the certificate"); - - /* Set Certificate Verification chain */ - if (!options->ca_file) - { - if (ca && sk_X509_num(ca)) - { - for (i = 0; i < sk_X509_num(ca); i++) - { - if (!X509_STORE_add_cert(ctx->cert_store,sk_X509_value(ca, i))) - msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)"); - if (!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) - msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); - } - } - } - } - else - { - /* Use seperate PEM files for key, cert and CA certs */ - -#ifdef ENABLE_PKCS11 - if (options->pkcs11_providers[0]) - { - /* Load Certificate and Private Key */ - if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_id_management, options->pkcs11_id)) - { - msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface", options->pkcs11_id); - goto err; - } - } - else -#endif - -#ifdef WIN32 - if (options->cryptoapi_cert) + if (options->priv_key_file) { - /* Load Certificate and Private Key */ - if (!SSL_CTX_use_CryptoAPI_certificate (ctx, options->cryptoapi_cert)) - msg (M_SSLERR, "Cannot load certificate \"%s\" from Microsoft Certificate Store", - options->cryptoapi_cert); - } - else -#endif - { - /* Load Certificate */ - if (options->cert_file) - { -#if ENABLE_INLINE_FILES - if (!strcmp (options->cert_file, INLINE_FILE_TAG) && options->cert_file_inline) - { - if (!use_inline_certificate_file (ctx, options->cert_file_inline)) - msg (M_SSLERR, "Cannot load inline certificate file"); - } - else -#endif - { - if (!SSL_CTX_use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM)) - msg (M_SSLERR, "Cannot load certificate file %s", options->cert_file); - using_cert_file = true; - } - } - - /* Load Private Key */ - if (options->priv_key_file) - { - int status; - -#if ENABLE_INLINE_FILES - if (!strcmp (options->priv_key_file, INLINE_FILE_TAG) && options->priv_key_file_inline) - { - status = use_inline_PrivateKey_file (ctx, options->priv_key_file_inline); - } - else -#endif - { - status = SSL_CTX_use_PrivateKey_file (ctx, options->priv_key_file, SSL_FILETYPE_PEM); - } - if (!status) - { -#ifdef ENABLE_MANAGEMENT - if (management && (ERR_GET_REASON (ERR_peek_error()) == EVP_R_BAD_DECRYPT)) - management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); -#endif - msg (M_WARN|M_SSL, "Cannot load private key file %s", options->priv_key_file); - goto err; - } - warn_if_group_others_accessible (options->priv_key_file); - - /* Check Private Key */ - if (!SSL_CTX_check_private_key (ctx)) - msg (M_SSLERR, "Private key does not match the certificate"); - } + if (0 != tls_ctx_load_priv_file(new_ctx, options->priv_key_file, options->priv_key_file_inline)) + goto err; } } if (options->ca_file || options->ca_path) { - int status; - -#if ENABLE_INLINE_FILES - if (options->ca_file && !strcmp (options->ca_file, INLINE_FILE_TAG) && options->ca_file_inline) - { - status = use_inline_load_verify_locations (ctx, options->ca_file_inline); - } - else -#endif - { - /* Load CA file for verifying peer supplied certificate */ - status = SSL_CTX_load_verify_locations (ctx, options->ca_file, options->ca_path); - } - - if (!status) - msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", options->ca_file, options->ca_path); - - /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */ - if (options->ca_path) { - X509_STORE *store = SSL_CTX_get_cert_store(ctx); - - if (store) - { - X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); - if (!X509_LOOKUP_add_dir(lookup, options->ca_path, X509_FILETYPE_PEM)) - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - else - msg(M_WARN, "WARNING: experimental option --capath %s", options->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 - } - else - msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)"); - } - - /* Load names of CAs from file and use it as a client CA list */ - if (options->ca_file) { - STACK_OF(X509_NAME) *cert_names = NULL; -#if ENABLE_INLINE_FILES - if (!strcmp (options->ca_file, INLINE_FILE_TAG) && options->ca_file_inline) - { - cert_names = use_inline_load_client_CA_file (ctx, options->ca_file_inline); - } - else -#endif - { - cert_names = SSL_load_client_CA_file (options->ca_file); - } - if (!cert_names) - msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", options->ca_file); - SSL_CTX_set_client_CA_list (ctx, cert_names); - } - } - - /* Enable the use of certificate chains */ - if (using_cert_file) - { - if (!SSL_CTX_use_certificate_chain_file (ctx, options->cert_file)) - msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file); + tls_ctx_load_ca(new_ctx, options->ca_file, options->ca_file_inline, + options->ca_path, options->tls_server); } - /* Require peer certificate verification */ -#if P2MP_SERVER - if (options->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 + /* 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) { -#ifdef ENABLE_X509ALTUSERNAME - x509_username_field = (char *) options->x509_username_field; -#else - x509_username_field = X509_USERNAME_FIELD_DEFAULT; -#endif - SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - verify_callback); + tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline); } - /* Connection information callback */ - SSL_CTX_set_info_callback (ctx, info_callback); - /* Allowable ciphers */ if (options->cipher_list) { - if (!SSL_CTX_set_cipher_list (ctx, options->cipher_list)) - msg (M_SSLERR, "Problem with cipher list: %s", options->cipher_list); + tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); } - ERR_clear_error (); +#ifdef ENABLE_CRYPTO_POLARSSL + /* Personalise the random by mixing in the certificate */ + tls_ctx_personalise_random (new_ctx); +#endif - return ctx; + tls_clear_error (); + return; err: - ERR_clear_error (); - if (ctx) - SSL_CTX_free (ctx); - return NULL; -} - -/* - * Print a one line summary of SSL/TLS session handshake. - */ -static void -print_details (SSL * c_ssl, const char *prefix) -{ - const SSL_CIPHER *ciph; - X509 *cert; - char s1[256]; - char s2[256]; - - s1[0] = s2[0] = 0; - ciph = SSL_get_current_cipher (c_ssl); - openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s %s", - prefix, - SSL_get_version (c_ssl), - SSL_CIPHER_get_version (ciph), - SSL_CIPHER_get_name (ciph)); - cert = SSL_get_peer_certificate (c_ssl); - if (cert != NULL) - { - EVP_PKEY *pkey = X509_get_pubkey (cert); - if (pkey != NULL) - { - if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL - && pkey->pkey.rsa->n != NULL) - { - openvpn_snprintf (s2, sizeof (s2), ", %d bit RSA", - BN_num_bits (pkey->pkey.rsa->n)); - } - else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL - && pkey->pkey.dsa->p != NULL) - { - openvpn_snprintf (s2, sizeof (s2), ", %d bit DSA", - BN_num_bits (pkey->pkey.dsa->p)); - } - EVP_PKEY_free (pkey); - } - X509_free (cert); - } - /* The SSL API does not allow us to look at temporary RSA/DH keys, - * otherwise we should print their lengths too */ - msg (D_HANDSHAKE, "%s%s", s1, s2); -} - -/* - * Show the TLS ciphers that are available for us to use - * in the OpenSSL library. - */ -void -show_available_tls_ciphers () -{ - SSL_CTX *ctx; - SSL *ssl; - const char *cipher_name; - int priority = 0; - - ctx = SSL_CTX_new (TLSv1_method ()); - if (!ctx) - msg (M_SSLERR, "Cannot create SSL_CTX object"); - ssl = SSL_new (ctx); - if (!ssl) - msg (M_SSLERR, "Cannot create SSL object"); - - printf ("Available TLS Ciphers,\n"); - printf ("listed in order of preference:\n\n"); - while ((cipher_name = SSL_get_cipher_list (ssl, priority++))) - printf ("%s\n", cipher_name); - printf ("\n"); - - SSL_free (ssl); - SSL_CTX_free (ctx); -} - -/* - * The OpenSSL library has a notion of preference in TLS - * ciphers. Higher preference == more secure. - * Return the highest preference cipher. - */ -void -get_highest_preference_tls_cipher (char *buf, int size) -{ - SSL_CTX *ctx; - SSL *ssl; - const char *cipher_name; - - ctx = SSL_CTX_new (TLSv1_method ()); - if (!ctx) - msg (M_SSLERR, "Cannot create SSL_CTX object"); - ssl = SSL_new (ctx); - if (!ssl) - msg (M_SSLERR, "Cannot create SSL object"); - - cipher_name = SSL_get_cipher_list (ssl, 0); - strncpynt (buf, cipher_name, size); - - SSL_free (ssl); - SSL_CTX_free (ctx); + tls_clear_error (); + tls_ctx_free (new_ctx); + return; } /* @@ -2119,242 +519,42 @@ is_hard_reset (int op, int key_method) return false; } -/* - * OpenVPN's interface to SSL/TLS authentication, - * encryption, and decryption is exclusively - * through "memory BIOs". - */ -static BIO * -getbio (BIO_METHOD * type, const char *desc) -{ - BIO *ret; - ret = BIO_new (type); - if (!ret) - msg (M_SSLERR, "Error creating %s BIO", desc); - return ret; -} - -/* - * Write to an OpenSSL BIO in non-blocking mode. - */ -static int -bio_write (struct tls_multi* multi, BIO *bio, const uint8_t *data, int size, const char *desc) -{ - int i; - int ret = 0; - ASSERT (size >= 0); - if (size) - { - /* - * Free the L_TLS lock prior to calling BIO routines - * so that foreground thread can still call - * tls_pre_decrypt or tls_pre_encrypt, - * allowing tunnel packet forwarding to continue. - */ -#ifdef BIO_DEBUG - bio_debug_data ("write", bio, data, size, desc); -#endif - i = BIO_write (bio, data, size); - - if (i < 0) - { - if (BIO_should_retry (bio)) - { - ; - } - else - { - msg (D_TLS_ERRORS | M_SSL, "TLS ERROR: BIO write %s error", - desc); - ret = -1; - ERR_clear_error (); - } - } - else if (i != size) - { - msg (D_TLS_ERRORS | M_SSL, - "TLS ERROR: BIO write %s incomplete %d/%d", desc, i, size); - ret = -1; - ERR_clear_error (); - } - else - { /* successful write */ - dmsg (D_HANDSHAKE_VERBOSE, "BIO write %s %d bytes", desc, i); - ret = 1; - } - } - return ret; -} - -/* - * Read from an OpenSSL BIO in non-blocking mode. - */ -static int -bio_read (struct tls_multi* multi, BIO *bio, struct buffer *buf, int maxlen, const char *desc) -{ - int i; - int ret = 0; - ASSERT (buf->len >= 0); - if (buf->len) - { - ; - } - else - { - int len = buf_forward_capacity (buf); - if (maxlen < len) - len = maxlen; - - /* - * BIO_read brackets most of the serious RSA - * key negotiation number crunching. - */ - i = BIO_read (bio, BPTR (buf), len); +/** @addtogroup control_processor + * @{ */ - VALGRIND_MAKE_READABLE ((void *) &i, sizeof (i)); +/** @name Functions for initialization and cleanup of key_state structures + * @{ */ -#ifdef BIO_DEBUG - bio_debug_data ("read", bio, BPTR (buf), i, desc); -#endif - if (i < 0) - { - if (BIO_should_retry (bio)) - { - ; - } - else - { - msg (D_TLS_ERRORS | M_SSL, "TLS_ERROR: BIO read %s error", - desc); - buf->len = 0; - ret = -1; - ERR_clear_error (); - } - } - else if (!i) - { - buf->len = 0; - } - else - { /* successful read */ - dmsg (D_HANDSHAKE_VERBOSE, "BIO read %s %d bytes", desc, i); - buf->len = i; - ret = 1; - VALGRIND_MAKE_READABLE ((void *) BPTR (buf), BLEN (buf)); - } - } - return ret; -} - -/* - * Inline functions for reading from and writing - * to BIOs. - */ - -static void -bio_write_post (const int status, struct buffer *buf) -{ - if (status == 1) /* success status return from bio_write? */ - { - memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ - buf->len = 0; - } -} - -static int -key_state_write_plaintext (struct tls_multi *multi, struct key_state *ks, struct buffer *buf) -{ - int ret; - perf_push (PERF_BIO_WRITE_PLAINTEXT); - ret = bio_write (multi, ks->ssl_bio, BPTR(buf), BLEN(buf), "tls_write_plaintext"); - bio_write_post (ret, buf); - perf_pop (); - return ret; -} - -static int -key_state_write_plaintext_const (struct tls_multi *multi, struct key_state *ks, const uint8_t *data, int len) -{ - int ret; - perf_push (PERF_BIO_WRITE_PLAINTEXT); - ret = bio_write (multi, ks->ssl_bio, data, len, "tls_write_plaintext_const"); - perf_pop (); - return ret; -} - -static int -key_state_write_ciphertext (struct tls_multi *multi, struct key_state *ks, struct buffer *buf) -{ - int ret; - perf_push (PERF_BIO_WRITE_CIPHERTEXT); - ret = bio_write (multi, ks->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); - bio_write_post (ret, buf); - perf_pop (); - return ret; -} - -static int -key_state_read_plaintext (struct tls_multi *multi, struct key_state *ks, struct buffer *buf, - int maxlen) -{ - int ret; - perf_push (PERF_BIO_READ_PLAINTEXT); - ret = bio_read (multi, ks->ssl_bio, buf, maxlen, "tls_read_plaintext"); - perf_pop (); - return ret; -} - -static int -key_state_read_ciphertext (struct tls_multi *multi, struct key_state *ks, struct buffer *buf, - int maxlen) -{ - int ret; - perf_push (PERF_BIO_READ_CIPHERTEXT); - ret = bio_read (multi, ks->ct_out, buf, maxlen, "tls_read_ciphertext"); - perf_pop (); - return ret; -} - -/* - * Initialize a key_state. Each key_state corresponds to - * a specific SSL/TLS session. +/** + * Initialize a \c key_state structure. + * @ingroup control_processor + * + * This function initializes a \c key_state structure associated with a \c + * tls_session. It sets up the structure's SSL-BIO, sets the object's \c + * key_state.state to \c S_INITIAL, and sets the session ID and key ID two + * appropriate values based on the \c tls_session's internal state. It + * also initializes a new set of structures for the \link reliable + * Reliability Layer\endlink. + * + * @param session - A pointer to the \c tls_session structure + * associated with the \a ks argument. + * @param ks - A pointer to the \c key_state structure to be + * initialized. This structure should already have + * been allocated before calling this function. */ static void key_state_init (struct tls_session *session, struct key_state *ks) { update_time (); + CLEAR (*ks); + /* * Build TLS object that reads/writes ciphertext * to/from memory BIOs. */ - CLEAR (*ks); - - ks->ssl = SSL_new (session->opt->ssl_ctx); - if (!ks->ssl) - msg (M_SSLERR, "SSL_new failed"); - - /* put session * in ssl object so we can access it - from verify callback*/ - SSL_set_ex_data (ks->ssl, mydata_index, session); - - ks->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio"); - ks->ct_in = getbio (BIO_s_mem (), "ct_in"); - ks->ct_out = getbio (BIO_s_mem (), "ct_out"); - -#ifdef BIO_DEBUG - bio_debug_oc ("open ssl_bio", ks->ssl_bio); - bio_debug_oc ("open ct_in", ks->ct_in); - bio_debug_oc ("open ct_out", ks->ct_out); -#endif - - if (session->opt->server) - SSL_set_accept_state (ks->ssl); - else - SSL_set_connect_state (ks->ssl); - - SSL_set_bio (ks->ssl, ks->ct_in, ks->ct_out); - BIO_set_ssl (ks->ssl_bio, ks->ssl, BIO_NOCLOSE); + key_state_ssl_init(&ks->ks_ssl, &session->opt->ssl_ctx, session->opt->server, + session); /* Set control-channel initiation mode */ ks->initial_opcode = session->initial_opcode; @@ -2393,28 +593,36 @@ key_state_init (struct tls_session *session, struct key_state *ks) /* init packet ID tracker */ packet_id_init (&ks->packet_id, + session->opt->tcp_mode, session->opt->replay_window, - session->opt->replay_time); + session->opt->replay_time, + "SSL", ks->key_id); #ifdef MANAGEMENT_DEF_AUTH ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++; #endif } + +/** + * Cleanup a \c key_state structure. + * @ingroup control_processor + * + * This function cleans up a \c key_state structure. It frees the + * associated SSL-BIO, and the structures allocated for the \link reliable + * Reliability Layer\endlink. + * + * @param ks - A pointer to the \c key_state structure to be + * cleaned up. + * @param clear - Whether the memory allocated for the \a ks object + * should be overwritten with 0s. + */ static void key_state_free (struct key_state *ks, bool clear) { ks->state = S_UNDEF; - if (ks->ssl) { -#ifdef BIO_DEBUG - bio_debug_oc ("close ssl_bio", ks->ssl_bio); - bio_debug_oc ("close ct_in", ks->ct_in); - bio_debug_oc ("close ct_out", ks->ct_out); -#endif - BIO_free_all(ks->ssl_bio); - SSL_free (ks->ssl); - } + key_state_ssl_free(&ks->ks_ssl); free_key_ctx_bi (&ks->key); free_buf (&ks->plaintext_read_buf); @@ -2450,6 +658,11 @@ key_state_free (struct key_state *ks, bool clear) CLEAR (*ks); } +/** @} name Functions for initialization and cleanup of key_state structures */ + +/** @} addtogroup control_processor */ + + /* * Must be called if we move a tls_session in memory. */ @@ -2457,9 +670,26 @@ static inline void tls_session_set_self_referential_pointers (struct tls_session session->tls_auth.packet_id = &session->tls_auth_pid; } -/* - * Initialize a TLS session. A TLS session normally has 2 key_state objects, - * one for the current key, and one for the lame duck (i.e. retiring) key. + +/** @addtogroup control_processor + * @{ */ + +/** @name Functions for initialization and cleanup of tls_session structures + * @{ */ + +/** + * Initialize a \c tls_session structure. + * @ingroup control_processor + * + * This function initializes a \c tls_session structure. This includes + * generating a random session ID, and initializing the \c KS_PRIMARY \c + * key_state in the \c tls_session.key array. + * + * @param multi - A pointer to the \c tls_multi structure + * associated with the \a session argument. + * @param session - A pointer to the \c tls_session structure to be + * initialized. This structure should already have + * been allocated before calling this function. */ static void tls_session_init (struct tls_multi *multi, struct tls_session *session) @@ -2498,8 +728,10 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session) /* initialize packet ID replay window for --tls-auth */ packet_id_init (session->tls_auth.packet_id, + session->opt->tcp_mode, session->opt->replay_window, - session->opt->replay_time); + session->opt->replay_time, + "TLS_AUTH", 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); @@ -2512,6 +744,18 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session) gc_free (&gc); } +/** + * Clean up a \c tls_session structure. + * @ingroup control_processor + * + * This function cleans up a \c tls_session structure. This includes + * cleaning up all associated \c key_state structures. + * + * @param session - A pointer to the \c tls_session structure to be + * cleaned up. + * @param clear - Whether the memory allocated for the \a session + * object should be overwritten with 0s. + */ static void tls_session_free (struct tls_session *session, bool clear) { @@ -2532,6 +776,11 @@ tls_session_free (struct tls_session *session, bool clear) CLEAR (*session); } +/** @} name Functions for initialization and cleanup of tls_session structures */ + +/** @} addtogroup control_processor */ + + static void move_session (struct tls_multi* multi, int dest, int src, bool reinit_src) { @@ -2615,10 +864,6 @@ lame_duck_must_die (const struct tls_session* session, interval_t *wakeup) return false; } -/* - * A tls_multi object fully encapsulates OpenVPN's TLS state. - * See ssl.h for more comments. - */ struct tls_multi * tls_multi_init (struct tls_options *tls_options) { @@ -2641,9 +886,6 @@ tls_multi_init (struct tls_options *tls_options) return ret; } -/* - * Finalize our computation of frame sizes. - */ void tls_multi_init_finalize (struct tls_multi* multi, const struct frame* frame) { @@ -2704,6 +946,9 @@ tls_multi_init_set_options (struct tls_multi* multi, #endif } +/* + * Cleanup a tls_multi structure and free associated memory allocations. + */ void tls_multi_free (struct tls_multi *multi, bool clear) { @@ -2734,6 +979,7 @@ tls_multi_free (struct tls_multi *multi, bool clear) free(multi); } + /* * Move a packet authentication HMAC + related fields to or from the front * of the buffer so it can be processed by encrypt/decrypt. @@ -2757,7 +1003,7 @@ swap_hmac (struct buffer *buf, const struct crypto_options *co, bool incoming) { /* hmac + packet_id (8 bytes) */ - const int hmac_size = HMAC_size (ctx->hmac) + packet_id_size (true); + const int hmac_size = hmac_ctx_size (ctx->hmac) + packet_id_size (true); /* opcode + session_id */ const int osid_size = 1 + SID_SIZE; @@ -2909,27 +1155,18 @@ key_source2_print (const struct key_source2 *k) } /* - * Use the TLS PRF function for generating data channel keys. - * This code is taken from the OpenSSL library. - * - * TLS generates keys as such: - * - * master_secret[48] = PRF(pre_master_secret[48], "master secret", - * ClientHello.random[32] + ServerHello.random[32]) - * - * key_block[] = PRF(SecurityParameters.master_secret[48], - * "key expansion", - * SecurityParameters.server_random[32] + - * SecurityParameters.client_random[32]); - * - * Notes: + * Generate the hash required by for the \c tls1_PRF function. * - * (1) key_block contains a full set of 4 keys. - * (2) The pre-master secret is generated by the client. + * @param md_kt Message digest to use + * @param sec Secret to base the hash on + * @param sec_len Length of the secret + * @param seed Seed to hash + * @param seed_len Length of the seed + * @param out Output buffer + * @param olen Length of the output buffer */ - -static void -tls1_P_hash(const EVP_MD *md, +void +tls1_P_hash(const md_kt_t *md_kt, const uint8_t *sec, int sec_len, const uint8_t *seed, @@ -2939,60 +1176,81 @@ tls1_P_hash(const EVP_MD *md, { struct gc_arena gc = gc_new (); int chunk,n; - unsigned int j; - HMAC_CTX ctx; - HMAC_CTX ctx_tmp; - uint8_t A1[EVP_MAX_MD_SIZE]; + hmac_ctx_t ctx; + hmac_ctx_t ctx_tmp; + uint8_t A1[MAX_HMAC_KEY_LENGTH]; unsigned int A1_len; #ifdef ENABLE_DEBUG const int olen_orig = olen; const uint8_t *out_orig = out; #endif - + + CLEAR(ctx); + CLEAR(ctx_tmp); + dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex (sec, sec_len, 0, &gc)); dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex (seed, seed_len, 0, &gc)); - chunk=EVP_MD_size(md); + chunk = md_kt_size(md_kt); + A1_len = md_kt_size(md_kt); + + hmac_ctx_init(&ctx, sec, sec_len, md_kt); + hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt); - HMAC_CTX_init(&ctx); - HMAC_CTX_init(&ctx_tmp); - HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); - HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); - HMAC_Update(&ctx,seed,seed_len); - HMAC_Final(&ctx,A1,&A1_len); + hmac_ctx_update(&ctx,seed,seed_len); + hmac_ctx_final(&ctx, A1); n=0; for (;;) { - HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ - HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ - HMAC_Update(&ctx,A1,A1_len); - HMAC_Update(&ctx_tmp,A1,A1_len); - HMAC_Update(&ctx,seed,seed_len); + hmac_ctx_reset(&ctx); + hmac_ctx_reset(&ctx_tmp); + hmac_ctx_update(&ctx,A1,A1_len); + hmac_ctx_update(&ctx_tmp,A1,A1_len); + hmac_ctx_update(&ctx,seed,seed_len); if (olen > chunk) { - HMAC_Final(&ctx,out,&j); - out+=j; - olen-=j; - HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ + hmac_ctx_final(&ctx, out); + out+=chunk; + olen-=chunk; + hmac_ctx_final(&ctx_tmp, A1); /* calc the next A1 value */ } else /* last one */ { - HMAC_Final(&ctx,A1,&A1_len); + hmac_ctx_final(&ctx, A1); memcpy(out,A1,olen); break; } } - HMAC_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&ctx_tmp); + hmac_ctx_cleanup(&ctx); + hmac_ctx_cleanup(&ctx_tmp); CLEAR (A1); dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex (out_orig, olen_orig, 0, &gc)); gc_free (&gc); } +/* + * Use the TLS PRF function for generating data channel keys. + * This code is based on the OpenSSL library. + * + * TLS generates keys as such: + * + * master_secret[48] = PRF(pre_master_secret[48], "master secret", + * ClientHello.random[32] + ServerHello.random[32]) + * + * key_block[] = PRF(SecurityParameters.master_secret[48], + * "key expansion", + * SecurityParameters.server_random[32] + + * SecurityParameters.client_random[32]); + * + * Notes: + * + * (1) key_block contains a full set of 4 keys. + * (2) The pre-master secret is generated by the client. + */ static void tls1_PRF(uint8_t *label, int label_len, @@ -3002,8 +1260,8 @@ tls1_PRF(uint8_t *label, int olen) { struct gc_arena gc = gc_new (); - const EVP_MD *md5 = EVP_md5(); - const EVP_MD *sha1 = EVP_sha1(); + const md_kt_t *md5 = md_kt_get("MD5"); + const md_kt_t *sha1 = md_kt_get("SHA1"); int len,i; const uint8_t *S1,*S2; uint8_t *out2; @@ -3015,7 +1273,6 @@ tls1_PRF(uint8_t *label, S2= &(sec[len]); len+=(slen&1); /* add for odd, make longer */ - tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen); tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); @@ -3138,13 +1395,13 @@ generate_key_expansion (struct key_ctx_bi *key, init_key_ctx (&key->encrypt, &key2.keys[(int)server], key_type, - DO_ENCRYPT, + OPENVPN_OP_ENCRYPT, "Data Channel Encrypt"); init_key_ctx (&key->decrypt, &key2.keys[1-(int)server], key_type, - DO_DECRYPT, + OPENVPN_OP_DECRYPT, "Data Channel Decrypt"); ret = true; @@ -3161,7 +1418,7 @@ random_bytes_to_buf (struct buffer *buf, uint8_t *out, int outlen) { - if (!RAND_bytes (out, outlen)) + if (!rand_bytes (out, outlen)) msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation [SSL]"); if (!buf_write (buf, out, outlen)) return false; @@ -3220,22 +1477,17 @@ key_source2_read (struct key_source2 *k2, } static void -flush_payload_buffer (struct tls_multi *multi, struct key_state *ks) +flush_payload_buffer (struct key_state *ks) { struct buffer *b; + while ((b = buffer_list_peek (ks->paybuf))) { - key_state_write_plaintext_const (multi, ks, b->data, b->len); + key_state_write_plaintext_const (&ks->ks_ssl, b->data, b->len); buffer_list_pop (ks->paybuf); } } -/* - * Macros for key_state_soft_reset & tls_process - */ -#define ks (&session->key[KS_PRIMARY]) /* primary key */ -#define ks_lame (&session->key[KS_LAME_DUCK]) /* retiring key */ - /* true if no in/out acknowledgements pending */ #define FULL_SYNC \ (reliable_empty(ks->send_reliable) && reliable_ack_empty (ks->rec_ack)) @@ -3247,6 +1499,9 @@ flush_payload_buffer (struct tls_multi *multi, struct key_state *ks) static void key_state_soft_reset (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 */ + ks->must_die = now + session->opt->transition_window; /* remaining lifetime of old key */ key_state_free (ks_lame, false); *ks_lame = *ks; @@ -3261,6 +1516,14 @@ key_state_soft_reset (struct tls_session *session) */ static bool +write_empty_string (struct buffer *buf) +{ + if (!buf_write_u16 (buf, 0)) + return false; + return true; +} + +static bool write_string (struct buffer *buf, const char *str, const int maxlen) { const int len = strlen (str) + 1; @@ -3274,14 +1537,6 @@ write_string (struct buffer *buf, const char *str, const int maxlen) } static bool -write_empty_string (struct buffer *buf) -{ - if (!buf_write_u16 (buf, 0)) - return false; - return true; -} - -static bool read_string (struct buffer *buf, char *str, const unsigned int capacity) { const int len = buf_read_u16 (buf); @@ -3321,171 +1576,6 @@ read_string_discard (struct buffer *buf) } /* - * Authenticate a client using username/password. - * Runs on server. - * - * If you want to add new authentication methods, - * this is the place to start. - */ - -static bool -verify_user_pass_script (struct tls_session *session, const struct user_pass *up) -{ - struct gc_arena gc = gc_new (); - struct argv argv = argv_new (); - const char *tmp_file = ""; - bool ret = false; - - /* Is username defined? */ - if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) - { - /* Set environmental variables prior to calling script */ - setenv_str (session->opt->es, "script_type", "user-pass-verify"); - - if (session->opt->auth_user_pass_verify_script_via_file) - { - struct status_output *so; - - tmp_file = create_temp_file (session->opt->tmp_dir, "up", &gc); - if( tmp_file ) { - so = status_open (tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE); - status_printf (so, "%s", up->username); - status_printf (so, "%s", up->password); - if (!status_close (so)) - { - msg (D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s", - tmp_file); - goto done; - } - } else { - msg (D_TLS_ERRORS, "TLS Auth Error: could not create write " - "username/password to temp file"); - } - } - else - { - setenv_str (session->opt->es, "username", up->username); - setenv_str (session->opt->es, "password", up->password); - } - - /* setenv incoming cert common name for script */ - setenv_str (session->opt->es, "common_name", session->common_name); - - /* setenv client real IP address */ - setenv_untrusted (session); - - /* format command line */ - argv_printf (&argv, "%sc %s", session->opt->auth_user_pass_verify_script, tmp_file); - - /* call command */ - ret = openvpn_run_script (&argv, session->opt->es, 0, - "--auth-user-pass-verify"); - - if (!session->opt->auth_user_pass_verify_script_via_file) - setenv_del (session->opt->es, "password"); - } - else - { - msg (D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username"); - } - - done: - if (tmp_file && strlen (tmp_file) > 0) - delete_file (tmp_file); - - argv_reset (&argv); - gc_free (&gc); - return ret; -} - -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; - - /* Is username defined? */ - if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) - { - /* set username/password in private env space */ - setenv_str (session->opt->es, "username", raw_username); - setenv_str (session->opt->es, "password", up->password); - - /* setenv incoming cert common name for script */ - setenv_str (session->opt->es, "common_name", session->common_name); - - /* setenv client real IP address */ - setenv_untrusted (session); - -#ifdef PLUGIN_DEF_AUTH - /* generate filename for deferred auth control file */ - key_state_gen_auth_control_file (ks, session->opt); -#endif - - /* call command */ - retval = plugin_call (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); - -#ifdef PLUGIN_DEF_AUTH - /* purge auth control filename (and file itself) for non-deferred returns */ - if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) - key_state_rm_auth_control_file (ks); -#endif - - setenv_del (session->opt->es, "password"); - setenv_str (session->opt->es, "username", up->username); - } - else - { - msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username"); - } - - return retval; -} - -/* - * MANAGEMENT_DEF_AUTH internal ssl.c status codes - */ -#define KMDA_ERROR 0 -#define KMDA_SUCCESS 1 -#define KMDA_UNDEF 2 -#define KMDA_DEF 3 - -#ifdef MANAGEMENT_DEF_AUTH -static int -verify_user_pass_management (struct tls_session *session, const struct user_pass *up, const char *raw_username) -{ - int retval = KMDA_ERROR; - - /* Is username defined? */ - if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) - { - /* set username/password in private env space */ - setenv_str (session->opt->es, "username", raw_username); - setenv_str (session->opt->es, "password", up->password); - - /* setenv incoming cert common name for script */ - setenv_str (session->opt->es, "common_name", session->common_name); - - /* setenv client real IP address */ - setenv_untrusted (session); - - if (management) - management_notify_client_needing_auth (management, ks->mda_key_id, session->opt->mda_context, session->opt->es); - - setenv_del (session->opt->es, "password"); - setenv_str (session->opt->es, "username", up->username); - - retval = KMDA_SUCCESS; - } - else - { - msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_management): peer provided a blank username"); - } - - return retval; -} -#endif - -/* * Handle the reading and writing of key data to and from * the TLS control channel (cleartext). */ @@ -3494,6 +1584,8 @@ static bool 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)); @@ -3512,7 +1604,7 @@ key_method_1_write (struct buffer *buf, struct tls_session *session) } init_key_ctx (&ks->key.encrypt, &key, &session->opt->key_type, - DO_ENCRYPT, "Data Channel Encrypt"); + OPENVPN_OP_ENCRYPT, "Data Channel Encrypt"); CLEAR (key); /* send local options string */ @@ -3564,12 +1656,17 @@ push_peer_info(struct buffer *buf, struct tls_session *session) /* push mac addr */ { - bool get_default_gateway_mac_addr (unsigned char *macaddr); - uint8_t macaddr[6]; - get_default_gateway_mac_addr (macaddr); - buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (macaddr, 6, 0, 1, ":", &gc)); + struct route_gateway_info rgi; + get_default_gateway (&rgi); + if (rgi.flags & RGI_HWADDR_DEFINED) + buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc)); } + /* push LZO status */ +#ifdef ENABLE_LZO_STUB + buf_printf (&out, "IV_LZO_STUB=1\n"); +#endif + /* push env vars that begin with UV_ */ for (e=es->list; e != NULL; e=e->next) { @@ -3599,6 +1696,9 @@ push_peer_info(struct buffer *buf, struct tls_session *session) 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)); @@ -3623,7 +1723,11 @@ key_method_2_write (struct buffer *buf, struct tls_session *session) /* write username/password if specified */ if (auth_user_pass_enabled) { - auth_user_pass_setup (NULL); +#ifdef ENABLE_CLIENT_CR + auth_user_pass_setup (NULL, session->opt->sci); +#else + auth_user_pass_setup (NULL, NULL); +#endif if (!write_string (buf, auth_user_pass.username, -1)) goto error; if (!write_string (buf, auth_user_pass.password, -1)) @@ -3676,6 +1780,8 @@ 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); @@ -3719,7 +1825,7 @@ 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, - DO_DECRYPT, "Data Channel Decrypt"); + OPENVPN_OP_DECRYPT, "Data Channel Decrypt"); CLEAR (key); ks->authenticated = true; return true; @@ -3733,23 +1839,20 @@ key_method_1_read (struct buffer *buf, struct tls_session *session) static bool key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_session *session) { - struct gc_arena gc = gc_new (); + 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; - char *options; - struct user_pass *up; + bool username_status, password_status; - bool man_def_auth = KMDA_UNDEF; + struct gc_arena gc = gc_new (); + char *options; -#ifdef MANAGEMENT_DEF_AUTH - if (management_enable_def_auth (management)) - man_def_auth = KMDA_DEF; -#endif + /* allocate temporary objects */ + ALLOC_ARRAY_CLEAR_GC (options, char, TLS_OPTIONS_LEN, &gc); ASSERT (session->opt->key_method == 2); - /* allocate temporary objects */ - ALLOC_ARRAY_CLEAR_GC (options, char, TLS_OPTIONS_LEN, &gc); - /* discard leading uint32 */ ASSERT (buf_advance (buf, 4)); @@ -3777,21 +1880,17 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi goto error; } - /* should we check username/password? */ ks->authenticated = false; - if (session->opt->auth_user_pass_verify_script - || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) - || man_def_auth == KMDA_DEF) + + if (verify_user_pass_enabled(session)) { - int s1 = OPENVPN_PLUGIN_FUNC_SUCCESS; - bool s2 = true; - char *raw_username; - bool username_status, password_status; + /* Perform username/password authentication */ + struct user_pass *up; - /* get username/password from plaintext buffer */ 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 (!username_status || !password_status) { CLEAR (*up); @@ -3802,76 +1901,18 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi } } - /* preserve raw username before string_mod remapping, for plugins */ - ALLOC_ARRAY_CLEAR_GC (raw_username, char, USER_PASS_LEN, &gc); - strcpy (raw_username, up->username); - string_mod (raw_username, CC_PRINT, CC_CRLF, '_'); - - /* enforce character class restrictions in username/password */ - string_mod_sslname (up->username, COMMON_NAME_CHAR_CLASS, session->opt->ssl_flags); - string_mod (up->password, CC_PRINT, CC_CRLF, '_'); - - /* call plugin(s) and/or script */ #ifdef MANAGEMENT_DEF_AUTH /* get peer info from control channel */ free (multi->peer_info); multi->peer_info = read_string_alloc (buf); - - if (man_def_auth == KMDA_DEF) - man_def_auth = verify_user_pass_management (session, up, raw_username); #endif - if (plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)) - s1 = verify_user_pass_plugin (session, up, raw_username); - if (session->opt->auth_user_pass_verify_script) - s2 = verify_user_pass_script (session, up); - - /* check sizing of username if it will become our common name */ - if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_USERNAME_LEN) - { - msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_USERNAME_LEN); - s1 = OPENVPN_PLUGIN_FUNC_ERROR; - } - - /* auth succeeded? */ - if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS -#ifdef PLUGIN_DEF_AUTH - || s1 == OPENVPN_PLUGIN_FUNC_DEFERRED -#endif - ) && s2 && man_def_auth != KMDA_ERROR - && tls_lock_username (multi, up->username)) - { - ks->authenticated = true; -#ifdef PLUGIN_DEF_AUTH - if (s1 == OPENVPN_PLUGIN_FUNC_DEFERRED) - ks->auth_deferred = true; -#endif -#ifdef MANAGEMENT_DEF_AUTH - if (man_def_auth != KMDA_UNDEF) - ks->auth_deferred = true; -#endif - if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)) - set_common_name (session, up->username); -#ifdef ENABLE_DEF_AUTH - msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", - ks->auth_deferred ? "deferred" : "succeeded", - up->username, - (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : ""); -#else - msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", - "succeeded", - up->username, - (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : ""); -#endif - } - else - { - msg (D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer"); - } + verify_user_pass(up, multi, session); CLEAR (*up); } else { + /* Session verification should have occurred during TLS negotiation*/ if (!session->verified) { msg (D_TLS_ERRORS, @@ -3881,52 +1922,10 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi ks->authenticated = true; } - /* While it shouldn't really happen, don't allow the common name to be NULL */ - if (!session->common_name) - set_common_name (session, ""); - - /* Don't allow the CN to change once it's been locked */ - if (ks->authenticated && multi->locked_cn) + /* Perform final authentication checks */ + if (ks->authenticated) { - const char *cn = session->common_name; - if (cn && strcmp (cn, multi->locked_cn)) - { - msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled", - multi->locked_cn, - cn); - - /* change the common name back to its original value and disable the tunnel */ - set_common_name (session, multi->locked_cn); - tls_deauthenticate (multi); - } - } - - /* Don't allow the cert hashes to change once they have been locked */ - if (ks->authenticated && multi->locked_cert_hash_set) - { - const struct cert_hash_set *chs = session->cert_hash_set; - if (chs && !cert_hash_compare (chs, multi->locked_cert_hash_set)) - { - msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth", - session->common_name); - - /* disable the tunnel */ - tls_deauthenticate (multi); - } - } - - /* verify --client-config-dir based authentication */ - if (ks->authenticated && session->opt->client_config_dir_exclusive) - { - const char *cn = session->common_name; - const char *path = gen_path (session->opt->client_config_dir_exclusive, cn, &gc); - if (!cn || !strcmp (cn, CCD_DEFAULT) || !test_file (path)) - { - ks->authenticated = false; - msg (D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'", - session->common_name, - path ? path : "UNDEF"); - } + verify_final_auth_checks(multi, session); } #ifdef ENABLE_OCC @@ -4016,6 +2015,8 @@ tls_process (struct tls_multi *multi, struct buffer *buf; bool state_change = false; bool active = false; + struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */ /* Make sure we were initialized and that we're not in an error state */ ASSERT (ks->state != S_UNDEF); @@ -4134,7 +2135,7 @@ tls_process (struct tls_multi *multi, ks->established = now; dmsg (D_TLS_DEBUG_MED, "STATE S_ACTIVE"); if (check_debug_level (D_HANDSHAKE)) - print_details (ks->ssl, "Control Channel:"); + print_details (&ks->ks_ssl, "Control Channel:"); state_change = true; ks->state = S_ACTIVE; INCR_SUCCESS; @@ -4142,8 +2143,8 @@ tls_process (struct tls_multi *multi, /* 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 (multi, 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(); @@ -4195,7 +2196,7 @@ tls_process (struct tls_multi *multi, int status = 0; if (buf->len) { - status = key_state_write_ciphertext (multi, ks, buf); + status = key_state_write_ciphertext (&ks->ks_ssl, buf); if (status == -1) { msg (D_TLS_ERRORS, @@ -4222,7 +2223,7 @@ tls_process (struct tls_multi *multi, int status; ASSERT (buf_init (buf, 0)); - status = key_state_read_plaintext (multi, ks, buf, TLS_CHANNEL_BUF_SIZE); + status = key_state_read_plaintext (&ks->ks_ssl, buf, TLS_CHANNEL_BUF_SIZE); update_time (); if (status == -1) { @@ -4295,7 +2296,7 @@ tls_process (struct tls_multi *multi, buf = &ks->plaintext_write_buf; if (buf->len) { - int status = key_state_write_plaintext (multi, ks, buf); + int status = key_state_write_plaintext (&ks->ks_ssl, buf); if (status == -1) { msg (D_TLS_ERRORS, @@ -4315,7 +2316,7 @@ tls_process (struct tls_multi *multi, buf = reliable_get_buf_output_sequenced (ks->send_reliable); if (buf) { - int status = key_state_read_ciphertext (multi, ks, buf, PAYLOAD_SIZE_DYNAMIC (&multi->opt.frame)); + int status = key_state_read_ciphertext (&ks->ks_ssl, buf, PAYLOAD_SIZE_DYNAMIC (&multi->opt.frame)); if (status == -1) { msg (D_TLS_ERRORS, @@ -4384,7 +2385,7 @@ tls_process (struct tls_multi *multi, } error: - ERR_clear_error (); + tls_clear_error(); ks->state = S_ERROR; msg (D_TLS_ERRORS, "TLS Error: TLS handshake failed"); INCR_ERROR; @@ -4392,9 +2393,6 @@ error: return false; } -#undef ks -#undef ks_lame - /* * Called by the top-level event loop. * @@ -4417,7 +2415,7 @@ tls_multi_process (struct tls_multi *multi, perf_push (PERF_TLS_MULTI_PROCESS); - ERR_clear_error (); + tls_clear_error (); /* * Process each session object having state of S_INITIAL or greater, @@ -5024,7 +3022,7 @@ tls_pre_decrypt (struct tls_multi *multi, error: ++multi->n_soft_errors; error_lite: - ERR_clear_error (); + tls_clear_error(); goto done; } @@ -5135,7 +3133,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas, return ret; error: - ERR_clear_error (); + tls_clear_error(); gc_free (&gc); return ret; } @@ -5230,7 +3228,7 @@ tls_send_payload (struct tls_multi *multi, struct key_state *ks; bool ret = false; - ERR_clear_error (); + tls_clear_error(); ASSERT (multi); @@ -5239,7 +3237,7 @@ tls_send_payload (struct tls_multi *multi, if (ks->state >= S_ACTIVE) { - if (key_state_write_plaintext_const (multi, ks, data, size) == 1) + if (key_state_write_plaintext_const (&ks->ks_ssl, data, size) == 1) ret = true; } else @@ -5250,7 +3248,8 @@ tls_send_payload (struct tls_multi *multi, ret = true; } - ERR_clear_error (); + + tls_clear_error(); return ret; } @@ -5263,7 +3262,7 @@ tls_rec_payload (struct tls_multi *multi, struct key_state *ks; bool ret = false; - ERR_clear_error (); + tls_clear_error(); ASSERT (multi); @@ -5277,7 +3276,7 @@ tls_rec_payload (struct tls_multi *multi, ks->plaintext_read_buf.len = 0; } - ERR_clear_error (); + tls_clear_error(); return ret; } @@ -5382,4 +3381,4 @@ done: #else static void dummy(void) {} -#endif /* USE_CRYPTO && USE_SSL*/ +#endif /* ENABLE_CRYPTO && ENABLE_SSL*/ diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h new file mode 100644 index 0000000..cd7cae2 --- /dev/null +++ b/src/openvpn/ssl.h @@ -0,0 +1,507 @@ +/* + * 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 SSL/Data channel negotiation module + */ + +#ifndef OPENVPN_SSL_H +#define OPENVPN_SSL_H + +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) + +#include "basic.h" +#include "common.h" +#include "crypto.h" +#include "packet_id.h" +#include "session_id.h" +#include "reliable.h" +#include "socket.h" +#include "mtu.h" +#include "options.h" +#include "plugin.h" + +#include "ssl_common.h" +#include "ssl_verify.h" +#include "ssl_backend.h" + +/* Used in the TLS PRF function */ +#define KEY_EXPANSION_ID "OpenVPN" + +/* packet opcode (high 5 bits) and key-id (low 3 bits) are combined in one byte */ +#define P_KEY_ID_MASK 0x07 +#define P_OPCODE_SHIFT 3 + +/* packet opcodes -- the V1 is intended to allow protocol changes in the future */ +#define P_CONTROL_HARD_RESET_CLIENT_V1 1 /* initial key from client, forget previous state */ +#define P_CONTROL_HARD_RESET_SERVER_V1 2 /* initial key from server, forget previous state */ +#define P_CONTROL_SOFT_RESET_V1 3 /* new key, graceful transition from old to new key */ +#define P_CONTROL_V1 4 /* control channel packet (usually TLS ciphertext) */ +#define P_ACK_V1 5 /* acknowledgement for packets received */ +#define P_DATA_V1 6 /* data channel packet */ + +/* indicates key_method >= 2 */ +#define P_CONTROL_HARD_RESET_CLIENT_V2 7 /* initial key from client, forget previous state */ +#define P_CONTROL_HARD_RESET_SERVER_V2 8 /* initial key from server, forget previous state */ + +/* define the range of legal opcodes */ +#define P_FIRST_OPCODE 1 +#define P_LAST_OPCODE 8 + +/* Should we aggregate TLS + * acknowledgements, and tack them onto + * control packets? */ +#define TLS_AGGREGATE_ACK + +/* + * If TLS_AGGREGATE_ACK, set the + * max number of acknowledgments that + * can "hitch a ride" on an outgoing + * non-P_ACK_V1 control packet. + */ +#define CONTROL_SEND_ACK_MAX 4 + +/* + * Define number of buffers for send and receive in the reliability layer. + */ +#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliablity layer */ +#define TLS_RELIABLE_N_REC_BUFFERS 8 + +/* + * Various timeouts + */ +#define TLS_MULTI_REFRESH 15 /* call tls_multi_process once every n seconds */ +#define TLS_MULTI_HORIZON 2 /* call tls_multi_process frequently for n seconds after + every packet sent/received action */ + +/* + * The SSL/TLS worker thread will wait at most this many seconds for the + * interprocess communication pipe to the main thread to be ready to accept + * writes. + */ +#define TLS_MULTI_THREAD_SEND_TIMEOUT 5 + +/* Interval that tls_multi_process should call tls_authentication_status */ +#define TLS_MULTI_AUTH_STATUS_INTERVAL 10 + +/* + * Buffer sizes (also see mtu.h). + */ + +/* Maximum length of OCC options string passed as part of auth handshake */ +#define TLS_OPTIONS_LEN 512 + +/* Default field in X509 to be username */ +#define X509_USERNAME_FIELD_DEFAULT "CN" + +/* + * Range of key exchange methods + */ +#define KEY_METHOD_MIN 1 +#define KEY_METHOD_MAX 2 + +/* key method taken from lower 4 bits */ +#define KEY_METHOD_MASK 0x0F + +/* + * Measure success rate of TLS handshakes, for debugging only + */ +/* #define MEASURE_TLS_HANDSHAKE_STATS */ + +/* + * Used in --mode server mode to check tls-auth signature on initial + * packets received from new clients. + */ +struct tls_auth_standalone +{ + struct key_ctx_bi tls_auth_key; + struct crypto_options tls_auth_options; + struct frame frame; +}; + +/* + * Prepare the SSL library for use + */ +void init_ssl_lib (void); + +/* + * Free any internal state that the SSL library might have + */ +void free_ssl_lib (void); + +/** + * Build master SSL context object that serves for the whole of OpenVPN + * instantiation + */ +void init_ssl (const struct options *options, struct tls_root_ctx *ctx); + +/** @addtogroup control_processor + * @{ */ + +/** @name Functions for initialization and cleanup of tls_multi structures + * @{ */ + +/** + * Allocate and initialize a \c tls_multi structure. + * @ingroup control_processor + * + * This function allocates a new \c tls_multi structure, and performs some + * amount of initialization. Afterwards, the \c tls_multi_init_finalize() + * function must be called to finalize the structure's initialization + * process. + * + * @param tls_options - The configuration options to be used for this VPN + * tunnel. + * + * @return A newly allocated and initialized \c tls_multi structure. + */ +struct tls_multi *tls_multi_init (struct tls_options *tls_options); + +/** + * Finalize initialization of a \c tls_multi structure. + * @ingroup control_processor + * + * This function initializes the \c TM_ACTIVE \c tls_session, and in + * server mode also the \c TM_UNTRUSTED \c tls_session, associated with + * this \c tls_multi structure. It also configures the control channel's + * \c frame structure based on the data channel's \c frame given in + * argument \a frame. + * + * @param multi - The \c tls_multi structure of which to finalize + * initialization. + * @param frame - The data channel's \c frame structure. + */ +void tls_multi_init_finalize(struct tls_multi *multi, + const struct frame *frame); + +/* + * Initialize a standalone tls-auth verification object. + */ +struct tls_auth_standalone *tls_auth_standalone_init (struct tls_options *tls_options, + struct gc_arena *gc); + +/* + * Finalize a standalone tls-auth verification object. + */ +void tls_auth_standalone_finalize (struct tls_auth_standalone *tas, + const struct frame *frame); + +/* + * Set local and remote option compatibility strings. + * Used to verify compatibility of local and remote option + * sets. + */ +void tls_multi_init_set_options(struct tls_multi* multi, + const char *local, + const char *remote); + +/** + * Cleanup a \c tls_multi structure and free associated memory + * allocations. + * @ingroup control_processor + * + * This function cleans up a \c tls_multi structure. This includes + * cleaning up all associated \c tls_session structures. + * + * @param multi - The \c tls_multi structure to clean up in free. + * @param clear - Whether the memory allocated for the \a multi + * object should be overwritten with 0s. + */ +void tls_multi_free (struct tls_multi *multi, bool clear); + +/** @} name Functions for initialization and cleanup of tls_multi structures */ + +/** @} addtogroup control_processor */ + +#define TLSMP_INACTIVE 0 +#define TLSMP_ACTIVE 1 +#define TLSMP_KILL 2 + +/* + * Called by the top-level event loop. + * + * Basically decides if we should call tls_process for + * the active or untrusted sessions. + */ +int tls_multi_process (struct tls_multi *multi, + struct buffer *to_link, + struct link_socket_actual **to_link_addr, + struct link_socket_info *to_link_socket_info, + interval_t *wakeup); + + +/**************************************************************************/ +/** + * Determine whether an incoming packet is a data channel or control + * channel packet, and process accordingly. + * @ingroup external_multiplexer + * + * When OpenVPN is in TLS mode, this is the first function to process an + * incoming packet. It inspects the packet's one-byte header which + * contains the packet's opcode and key ID. Depending on the opcode, the + * packet is processed as a data channel or as a control channel packet. + * + * @par Data channel packets + * + * If the opcode indicates the packet is a data channel packet, then the + * packet's key ID is used to find the local TLS state it is associated + * with. This state is checked whether it is active, authenticated, and + * its remote peer is the source of this packet. If these checks passed, + * the state's security parameters are loaded into the \a opt crypto + * options so that \p openvpn_decrypt() can later use them to authenticate + * and decrypt the packet. + * + * This function then returns false. The \a buf buffer has not been + * modified, except for removing the header. + * + * @par Control channel packets + * + * If the opcode indicates the packet is a control channel packet, then + * this function will process it based on its plaintext header. depending + * on the packet's opcode and session ID this function determines if it is + * destined for an active TLS session, or whether a new TLS session should + * be started. This function also initiates data channel session key + * renegotiation if the received opcode requests that. + * + * If the incoming packet is destined for an active TLS session, then the + * packet is inserted into the Reliability Layer and will be handled + * later. + * + * @param multi - The TLS multi structure associated with the VPN tunnel + * 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. + * + * @return + * @li True if the packet is a control channel packet that has been + * processed successfully. + * @li False if the packet is a data channel packet, or if an error + * occurred during processing of a control channel packet. + */ +bool tls_pre_decrypt (struct tls_multi *multi, + const struct link_socket_actual *from, + struct buffer *buf, + struct crypto_options *opt); + + +/**************************************************************************/ +/** @name Functions for managing security parameter state for data channel packets + * @{ */ + +/** + * Inspect an incoming packet for which no VPN tunnel is active, and + * determine whether a new VPN tunnel should be created. + * @ingroup data_crypto + * + * This function receives the initial incoming packet from a client that + * wishes to establish a new VPN tunnel, and determines the packet is a + * valid initial packet. It is only used when OpenVPN is running in + * server mode. + * + * The tests performed by this function are whether the packet's opcode is + * correct for establishing a new VPN tunnel, whether its key ID is 0, and + * whether its size is not too large. This function also performs the + * initial HMAC firewall test, if configured to do so. + * + * The incoming packet and the local VPN tunnel state are not modified by + * this function. Its sole purpose is to inspect the packet and determine + * whether a new VPN tunnel should be created. If so, that new VPN tunnel + * instance will handle processing of the packet. + * + * @param tas - The standalone TLS authentication setting structure for + * this process. + * @param from - The source address of the packet. + * @param buf - A buffer structure containing the incoming packet. + * + * @return + * @li True if the packet is valid and a new VPN tunnel should be created + * for this client. + * @li False if the packet is not valid, did not pass the HMAC firewall + * test, or some other error occurred. + */ +bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas, + const struct link_socket_actual *from, + const struct buffer *buf); + + +/** + * Choose the appropriate security parameters with which to process an + * outgoing packet. + * @ingroup data_crypto + * + * If no appropriate security parameters can be found, or if some other + * error occurs, then the buffer is set to empty. + * + * @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. + */ +void tls_pre_encrypt (struct tls_multi *multi, + 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. + * @ingroup data_crypto + * + * @param multi - The TLS state for this packet's destination VPN tunnel. + * @param buf - The buffer containing the outgoing packet. + */ +void tls_post_encrypt (struct tls_multi *multi, struct buffer *buf); + +/** @} name Functions for managing security parameter state for data channel packets */ + +/* + * Setup private key file password. If auth_file is given, use the + * credentials stored in the file. + */ +void pem_password_setup (const char *auth_file); + +/* + * Setup authentication username and password. If auth_file is given, use the + * credentials stored in the file. + */ +void auth_user_pass_setup (const char *auth_file, const struct static_challenge_info *sc_info); + +/* + * Ensure that no caching is performed on authentication information + */ +void ssl_set_auth_nocache (void); + +/* + * Purge any stored authentication information, both for key files and tunnel + * authentication. If PCKS #11 is enabled, purge authentication for that too. + */ +void ssl_purge_auth (const bool auth_user_pass_only); + +void ssl_set_auth_token (const char *token); + +#ifdef ENABLE_CLIENT_CR +/* + * ssl_get_auth_challenge will parse the server-pushed auth-failed + * reason string and return a dynamically allocated + * auth_challenge_info struct. + */ +void ssl_purge_auth_challenge (void); +void ssl_put_auth_challenge (const char *cr_str); +#endif + +/* + * Reserve any extra space required on frames. + */ +void tls_adjust_frame_parameters(struct frame *frame); + +/* + * Send a payload over the TLS control channel + */ +bool tls_send_payload (struct tls_multi *multi, + const uint8_t *data, + int size); + +/* + * Receive a payload through the TLS control channel + */ +bool tls_rec_payload (struct tls_multi *multi, + struct buffer *buf); + +#ifdef MANAGEMENT_DEF_AUTH +static inline char * +tls_get_peer_info(const struct tls_multi *multi) +{ + return multi->peer_info; +} +#endif + +/* + * inline functions + */ + +static inline bool +tls_initial_packet_received (const struct tls_multi *multi) +{ + return multi->n_sessions > 0; +} + +static inline bool +tls_test_auth_deferred_interval (const struct tls_multi *multi) +{ + if (multi) + { + const struct key_state *ks = &multi->session[TM_ACTIVE].key[KS_PRIMARY]; + return now < ks->auth_deferred_expire; + } + return false; +} + +static inline int +tls_test_payload_len (const struct tls_multi *multi) +{ + if (multi) + { + const struct key_state *ks = &multi->session[TM_ACTIVE].key[KS_PRIMARY]; + if (ks->state >= S_ACTIVE) + return BLEN (&ks->plaintext_read_buf); + } + return 0; +} + +static inline void +tls_set_single_session (struct tls_multi *multi) +{ + if (multi) + multi->opt.single_session = true; +} + +/* + * protocol_dump() flags + */ +#define PD_TLS_AUTH_HMAC_SIZE_MASK 0xFF +#define PD_SHOW_DATA (1<<8) +#define PD_TLS (1<<9) +#define PD_VERBOSE (1<<10) + +const char *protocol_dump (struct buffer *buffer, + unsigned int flags, + struct gc_arena *gc); + +/* + * debugging code + */ + +#ifdef MEASURE_TLS_HANDSHAKE_STATS +void show_tls_performance_stats(void); +#endif + +/*#define EXTRACT_X509_FIELD_TEST*/ +void extract_x509_field_test (void); + +#endif /* ENABLE_CRYPTO && ENABLE_SSL */ + +#endif diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h new file mode 100644 index 0000000..203a4d2 --- /dev/null +++ b/src/openvpn/ssl_backend.h @@ -0,0 +1,435 @@ +/* + * 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 SSL library backend module + */ + + +#ifndef SSL_BACKEND_H_ +#define SSL_BACKEND_H_ + +#include "buffer.h" + +#ifdef ENABLE_CRYPTO_OPENSSL +#include "ssl_openssl.h" +#include "ssl_verify_openssl.h" +#endif +#ifdef ENABLE_CRYPTO_POLARSSL +#include "ssl_polarssl.h" +#include "ssl_verify_polarssl.h" +#endif + + +/* + * + * Functions implemented in ssl.c for use by the backend SSL library + * + */ + +/** + * Callback to retrieve the user's password + * + * @param buf Buffer to return the password in + * @param size Size of the buffer + * @param rwflag Unused, needed for OpenSSL compatibility + * @param u Unused, needed for OpenSSL compatibility + */ +int pem_password_callback (char *buf, int size, int rwflag, void *u); + +/* + * + * Functions used in ssl.c which must be implemented by the backend SSL library + * + */ + +/** + * Perform any static initialisation necessary by the library. + * Called on OpenVPN initialisation + */ +void tls_init_lib(); + +/** + * Free any global SSL library-specific data structures. + */ +void tls_free_lib(); +/** + * Clear the underlying SSL library's error state. + */ +void tls_clear_error(); + +/** + * Initialise a library-specific TLS context for a server. + * + * @param ctx TLS context to initialise + */ +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 + */ +void tls_ctx_client_new(struct tls_root_ctx *ctx); + +/** + * Frees the library-specific TLSv1 context + * + * @param ctx TLS context to free + */ +void tls_ctx_free(struct tls_root_ctx *ctx); + +/** + * Checks whether the given TLS context is initialised + * + * @param ctx TLS context to check + * + * @return true if the context is initialised, false if not. + */ +bool tls_ctx_initialised(struct tls_root_ctx *ctx); + +/** + * Set any library specific options. + * + * Examples include disabling session caching, the password callback to use, + * and session verification parameters. + * + * @param ctx TLS context to set options on + * @param ssl_flags SSL flags to set + */ +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. + */ +void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); + +/** + * Load Diffie Hellman Parameters, and load them into the library-specific + * TLS context. + * + * @param ctx TLS context to use + * @param dh_file The file name to load the parameters from, or + * "[[INLINE]]" in the case of inline files. + * @param dh_file_inline A string containing the parameters + */ +void tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file, + const char *dh_file_inline); + +/** + * Load PKCS #12 file for key, cert and (optionally) CA certs, and add to + * library-specific TLS context. + * + * @param ctx TLS context to use + * @param pkcs12_file The file name to load the information from, or + * "[[INLINE]]" in the case of inline files. + * @param pkcs12_file_inline A string containing the information + * + * @return 1 if an error occurred, 0 if parsing was + * successful. + */ +int tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, + const char *pkcs12_file_inline, bool load_ca_file + ); + +/** + * Use Windows cryptoapi for key and cert, and add to library-specific TLS + * context. + * + * @param ctx TLS context to use + * @param crypto_api_cert String representing the certificate to load. + */ +#ifdef ENABLE_CRYPTOAPI +void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert); +#endif /* WIN32 */ + +/** + * Load certificate file into the given TLS context. If the given certificate + * file contains a certificate chain, load the whole chain. + * + * If the x509 parameter is not NULL, the certificate will be returned in it. + * + * @param ctx TLS context to use + * @param cert_file The file name to load the certificate from, or + * "[[INLINE]]" in the case of inline files. + * @param cert_file_inline A string containing the certificate + * @param x509 An optional certificate, if x509 is NULL, + * do nothing, if x509 is not NULL, *x509 will be + * allocated and filled with the loaded certificate. + * *x509 must be NULL. + */ +void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, + const char *cert_file_inline, openvpn_x509_cert_t **x509 + ); + +/** + * Free the given certificate + * + * @param x509 certificate to free + */ +void tls_ctx_free_cert_file (openvpn_x509_cert_t *x509); + +/** + * Load private key file into the given TLS context. + * + * @param ctx TLS context to use + * @param priv_key_file The file name to load the private key from, or + * "[[INLINE]]" in the case of inline files. + * @param priv_key_file_inline A string containing the private key + * + * @return 1 if an error occurred, 0 if parsing was + * successful. + */ +int tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, + const char *priv_key_file_inline + ); + +#ifdef MANAGMENT_EXTERNAL_KEY + +/** + * Tell the management interface to load the external private key matching + * the given certificate. + * + * @param ctx TLS context to use + * @param cert The certificate file to load the private key for + * "[[INLINE]]" in the case of inline files. + * + * @return 1 if an error occurred, 0 if parsing was + * successful. + */ +int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, openvpn_x509_cert_t *cert); +#endif + + +/** + * Load certificate authority certificates from the given file or path. + * + * Note that not all SSL libraries support loading from a path. + * + * @param ctx TLS context to use + * @param ca_file The file name to load the CAs from, or + * "[[INLINE]]" in the case of inline files. + * @param ca_file_inline A string containing the CAs + * @param ca_path The path to load the CAs from + */ +void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, + const char *ca_file_inline, const char *ca_path, bool tls_server + ); + +/** + * Load extra certificate authority certificates from the given file or path. + * These Load extra certificates that are part of our own certificate + * chain but shouldn't be included in the verify chain. + * + * + * @param ctx TLS context to use + * @param extra_certs_file The file name to load the certs from, or + * "[[INLINE]]" in the case of inline files. + * @param extra_certs_file_inline A string containing the certs + */ +void tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, + const char *extra_certs_file_inline + ); + +#ifdef ENABLE_CRYPTO_POLARSSL +/** + * Add a personalisation string to the PolarSSL RNG, based on the certificate + * loaded into the given context. + * + * @param ctx TLS context to use + */ +void tls_ctx_personalise_random(struct tls_root_ctx *ctx); +#endif + +/* ************************************** + * + * Key-state specific functions + * + ***************************************/ + +/** + * Initialise the SSL channel part of the given key state. Settings will be + * loaded from a previously initialised TLS context. + * + * @param ks_ssl The SSL channel's state info to initialise + * @param ssl_ctx The TLS context to use when initialising the channel. + * @param is_server Initialise a server? + * @param session The session associated with the given key_state + */ +void key_state_ssl_init(struct key_state_ssl *ks_ssl, + const struct tls_root_ctx *ssl_ctx, bool is_server, void *session); + +/** + * Free the SSL channel part of the given key state. + * + * @param ks_ssl The SSL channel's state info to free + */ +void key_state_ssl_free(struct key_state_ssl *ks_ssl); + +/**************************************************************************/ +/** @addtogroup control_tls + * @{ */ + +/** @name Functions for packets to be sent to a remote OpenVPN peer + * @{ */ + +/** + * Insert a plaintext buffer into the TLS module. + * + * After successfully processing the data, the data in \a buf is zeroized, + * its length set to zero, and a value of \c 1 is returned. + * + * @param ks_ssl - The security parameter state for this %key + * session. + * @param buf - The plaintext message to process. + * + * @return The return value indicates whether the data was successfully + * processed: + * - \c 1: All the data was processed successfully. + * - \c 0: The data was not processed, this function should be called + * again later to retry. + * - \c -1: An error occurred. + */ +int key_state_write_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf); + +/** + * Insert plaintext data into the TLS module. + * + * @param ks_ssl - The security parameter state for this %key + * session. + * @param data - A pointer to the data to process. + * @param len - The length in bytes of the data to process. + * + * @return The return value indicates whether the data was successfully + * processed: + * - \c 1: All the data was processed successfully. + * - \c 0: The data was not processed, this function should be called + * again later to retry. + * - \c -1: An error occurred. + */ +int key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, + const uint8_t *data, int len); + +/** + * Extract ciphertext data from the TLS module. + * + * If the \a buf buffer has a length other than zero, this function does + * not perform any action and returns 0. + * + * @param ks_ssl - The security parameter state for this %key + * session. + * @param buf - A buffer in which to store the ciphertext. + * @param maxlen - The maximum number of bytes to extract. + * + * @return The return value indicates whether the data was successfully + * processed: + * - \c 1: Data was extracted successfully. + * - \c 0: No data was extracted, this function should be called again + * later to retry. + * - \c -1: An error occurred. + */ +int key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf, + int maxlen); + +/** @} name Functions for packets to be sent to a remote OpenVPN peer */ + + +/** @name Functions for packets received from a remote OpenVPN peer + * @{ */ + +/** + * Insert a ciphertext buffer into the TLS module. + * + * After successfully processing the data, the data in \a buf is zeroized, + * its length set to zero, and a value of \c 1 is returned. + * + * @param ks_ssl - The security parameter state for this %key + * session. + * @param buf - The ciphertext message to process. + * + * @return The return value indicates whether the data was successfully + * processed: + * - \c 1: All the data was processed successfully. + * - \c 0: The data was not processed, this function should be called + * again later to retry. + * - \c -1: An error occurred. + */ +int key_state_write_ciphertext (struct key_state_ssl *ks_ssl, + struct buffer *buf); + +/** + * Extract plaintext data from the TLS module. + * + * If the \a buf buffer has a length other than zero, this function does + * not perform any action and returns 0. + * + * @param ks_ssl - The security parameter state for this %key + * session. + * @param buf - A buffer in which to store the plaintext. + * @param maxlen - The maximum number of bytes to extract. + * + * @return The return value indicates whether the data was successfully + * processed: + * - \c 1: Data was extracted successfully. + * - \c 0: No data was extracted, this function should be called again + * later to retry. + * - \c -1: An error occurred. + */ +int key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf, + int maxlen); + +/** @} name Functions for packets received from a remote OpenVPN peer */ + +/** @} addtogroup control_tls */ + +/* ************************************** + * + * Information functions + * + * Print information for the end user. + * + ***************************************/ + +/* + * Print a one line summary of SSL/TLS session handshake. + */ +void print_details (struct key_state_ssl * ks_ssl, const char *prefix); + +/* + * Show the TLS ciphers that are available for us to use in the OpenSSL + * library. + */ +void show_available_tls_ciphers (); + +/* + * The OpenSSL library has a notion of preference in TLS ciphers. Higher + * preference == more secure. Return the highest preference cipher. + */ +void get_highest_preference_tls_cipher (char *buf, int size); + +#endif /* SSL_BACKEND_H_ */ diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h new file mode 100644 index 0000000..cb259a9 --- /dev/null +++ b/src/openvpn/ssl_common.h @@ -0,0 +1,498 @@ +/* + * 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 Common Data Structures + */ + +#ifndef SSL_COMMON_H_ +#define SSL_COMMON_H_ + +#include "session_id.h" +#include "socket.h" +#include "packet_id.h" +#include "crypto.h" +#include "options.h" + +#include "ssl_backend.h" + +/* passwords */ +#define UP_TYPE_AUTH "Auth" +#define UP_TYPE_PRIVATE_KEY "Private Key" + +/** @addtogroup control_processor + * @{ */ +/** + * @name Control channel negotiation states + * + * These states represent the different phases of control channel + * negotiation between OpenVPN peers. OpenVPN servers and clients + * progress through the states in a different order, because of their + * different roles during exchange of random material. The references to + * the \c key_source2 structure in the list below is only valid if %key + * method 2 is being used. See the \link key_generation data channel key + * generation\endlink related page for more information. + * + * Clients follow this order: + * -# \c S_INITIAL, ready to begin three-way handshake and control + * channel negotiation. + * -# \c S_PRE_START, have started three-way handshake, waiting for + * acknowledgment from remote. + * -# \c S_START, initial three-way handshake complete. + * -# \c S_SENT_KEY, have sent local part of \c key_source2 random + * material. + * -# \c S_GOT_KEY, have received remote part of \c key_source2 random + * material. + * -# \c S_ACTIVE, normal operation during remaining handshake window. + * -# \c S_NORMAL_OP, normal operation. + * + * Servers follow the same order, except for \c S_SENT_KEY and \c + * S_GOT_KEY being reversed, because the server first receives the + * client's \c key_source2 random material before generating and sending + * its own. + * + * @{ + */ +#define S_ERROR -1 /**< Error state. */ +#define S_UNDEF 0 /**< Undefined state, used after a \c + * key_state is cleaned up. */ +#define S_INITIAL 1 /**< Initial \c key_state state after + * initialization by \c key_state_init() + * before start of three-way handshake. */ +#define S_PRE_START 2 /**< Waiting for the remote OpenVPN peer + * to acknowledge during the initial + * three-way handshake. */ +#define S_START 3 /**< Three-way handshake is complete, + * start of key exchange. */ +#define S_SENT_KEY 4 /**< Local OpenVPN process has sent its + * part of the key material. */ +#define S_GOT_KEY 5 /**< Local OpenVPN process has received + * the remote's part of the key + * material. */ +#define S_ACTIVE 6 /**< Operational \c key_state state + * immediately after negotiation has + * completed while still within the + * handshake window. */ +/* ready to exchange data channel packets */ +#define S_NORMAL_OP 7 /**< Normal operational \c key_state + * state. */ +/** @} name Control channel negotiation states */ +/** @} addtogroup control_processor */ + +/** + * Container for one half of random material to be used in %key method 2 + * \ref key_generation "data channel key generation". + * @ingroup control_processor + */ +struct key_source { + uint8_t pre_master[48]; /**< Random used for master secret + * generation, provided only by client + * OpenVPN peer. */ + uint8_t random1[32]; /**< Seed used for master secret + * generation, provided by both client + * and server. */ + uint8_t random2[32]; /**< Seed used for key expansion, provided + * by both client and server. */ +}; + + +/** + * Container for both halves of random material to be used in %key method + * 2 \ref key_generation "data channel key generation". + * @ingroup control_processor + */ +struct key_source2 { + struct key_source client; /**< Random provided by client. */ + struct key_source server; /**< Random provided by server. */ +}; + +/** + * Security parameter state of one TLS and data channel %key session. + * @ingroup control_processor + * + * This structure represents one security parameter session between + * OpenVPN peers. It includes the control channel TLS state and the data + * channel crypto state. It also contains the reliability layer + * structures used for control channel messages. + * + * A new \c key_state structure is initialized for each hard or soft + * reset. + * + * @see + * - This structure should be initialized using the \c key_state_init() + * function. + * - This structure should be cleaned up using the \c key_state_free() + * function. + */ +struct key_state +{ + int state; + int key_id; /* inherited from struct tls_session below */ + + struct key_state_ssl ks_ssl; /* contains SSL object and BIOs for the control channel */ + + time_t established; /* when our state went S_ACTIVE */ + time_t must_negotiate; /* key negotiation times out if not finished before this time */ + time_t must_die; /* this object is destroyed at this time */ + + 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 key_source2 *key_src; /* source entropy for key expansion */ + + struct buffer plaintext_read_buf; + struct buffer plaintext_write_buf; + struct buffer ack_write_buf; + + struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */ + struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ + struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ + + struct buffer_list *paybuf; + + counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */ + counter_type n_packets; /* how many packets sent/recvd since last key exchange */ + + /* + * If bad username/password, TLS connection will come up but 'authenticated' will be false. + */ + bool authenticated; + time_t auth_deferred_expire; + +#ifdef ENABLE_DEF_AUTH + /* If auth_deferred is true, authentication is being deferred */ + bool auth_deferred; +#ifdef MANAGEMENT_DEF_AUTH + unsigned int mda_key_id; + unsigned int mda_status; +#endif +#ifdef PLUGIN_DEF_AUTH + unsigned int auth_control_status; + time_t acf_last_mod; + char *auth_control_file; +#endif +#endif +}; + +/* + * Our const options, obtained directly or derived from + * command line options. + */ +struct tls_options +{ + /* our master TLS context from which all SSL objects derived */ + struct tls_root_ctx ssl_ctx; + + /* data channel cipher, hmac, and key lengths */ + struct key_type key_type; + + /* true if we are a TLS server, client otherwise */ + bool server; + + /* if true, don't xmit until first packet from peer is received */ + bool xmit_hold; + +#ifdef ENABLE_OCC + /* local and remote options strings + that must match between client and server */ + const char *local_options; + const char *remote_options; +#endif + + /* from command line */ + int key_method; + bool replay; + bool single_session; +#ifdef ENABLE_OCC + bool disable_occ; +#endif +#ifdef ENABLE_PUSH_PEER_INFO + bool push_peer_info; +#endif + int transition_window; + int handshake_window; + interval_t packet_timeout; + int renegotiate_bytes; + int renegotiate_packets; + interval_t renegotiate_seconds; + + /* cert verification parms */ + const char *verify_command; + const char *verify_export_cert; + const char *verify_x509name; + const char *crl_file; + int ns_cert_type; + unsigned remote_cert_ku[MAX_PARMS]; + const char *remote_cert_eku; + uint8_t *verify_hash; + char *x509_username_field; + + /* allow openvpn config info to be + passed over control channel */ + bool pass_config_info; + + /* struct crypto_option flags */ + unsigned int crypto_flags_and; + unsigned int crypto_flags_or; + + int replay_window; /* --replay-window parm */ + 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; + + /* frame parameters for TLS control channel */ + struct frame frame; + + /* used for username/password authentication */ + const char *auth_user_pass_verify_script; + bool auth_user_pass_verify_script_via_file; + const char *tmp_dir; + + /* use the client-config-dir as a positive authenticator */ + const char *client_config_dir_exclusive; + + /* instance-wide environment variable set */ + struct env_set *es; + const struct plugin_list *plugins; + + /* configuration file boolean 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_OPT_VERIFY (1<<4) +# define SSLF_CRL_VERIFY_DIR (1<<5) + unsigned int ssl_flags; + +#ifdef MANAGEMENT_DEF_AUTH + 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; +#endif + + /* --gremlin bits */ + int gremlin; +}; + +/** @addtogroup control_processor + * @{ */ +/** @name Index of key_state objects within a tls_session structure + * + * This is the index of \c tls_session.key + * + * @{ */ +#define KS_PRIMARY 0 /**< Primary %key state index. */ +#define KS_LAME_DUCK 1 /**< %Key state index that will retire + * soon. */ +#define KS_SIZE 2 /**< Size of the \c tls_session.key array. */ +/** @} name Index of key_state objects within a tls_session structure */ +/** @} addtogroup control_processor */ + + +/** + * Security parameter state of a single session within a VPN tunnel. + * @ingroup control_processor + * + * This structure represents an OpenVPN peer-to-peer control channel + * session. + * + * A \c tls_session remains over soft resets, but a new instance is + * initialized for each hard reset. + * + * @see + * - This structure should be initialized using the \c tls_session_init() + * function. + * - This structure should be cleaned up using the \c tls_session_free() + * function. + */ +struct tls_session +{ + /* const options and config info */ + struct tls_options *opt; + + /* during hard reset used to control burst retransmit */ + bool burst; + + /* authenticate control packets */ + struct crypto_options tls_auth; + struct packet_id tls_auth_pid; + + 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) */ + + int limit_next; /* used for traffic shaping on the control channel */ + + int verify_maxlevel; + + char *common_name; + + struct cert_hash_set *cert_hash_set; + +#ifdef ENABLE_PF + uint32_t common_name_hashval; +#endif + + bool verified; /* true if peer certificate was verified against CA */ + + /* not-yet-authenticated incoming client */ + struct link_socket_actual untrusted_addr; + + struct key_state key[KS_SIZE]; +}; + +/** @addtogroup control_processor + * @{ */ +/** @name Index of tls_session objects within a tls_multi structure + * + * This is the index of \c tls_multi.session + * + * Normally three tls_session objects are maintained by an active openvpn + * session. The first is the current, TLS authenticated session, the + * second is used to process connection requests from a new client that + * would usurp the current session if successfully authenticated, and the + * third is used as a repository for a "lame-duck" %key in the event that + * the primary session resets due to error while the lame-duck %key still + * has time left before its expiration. Lame duck keys are used to + * maintain the continuity of the data channel connection while a new %key + * is being negotiated. + * + * @{ */ +#define TM_ACTIVE 0 /**< Active \c tls_session. */ +#define TM_UNTRUSTED 1 /**< As yet un-trusted \c tls_session + * being negotiated. */ +#define TM_LAME_DUCK 2 /**< Old \c tls_session. */ +#define TM_SIZE 3 /**< Size of the \c tls_multi.session + * array. */ +/** @} name Index of tls_session objects within a tls_multi structure */ +/** @} addtogroup control_processor */ + + +/* + * The number of keys we will scan on encrypt or decrypt. The first + * is the "active" key. The second is the lame_duck or retiring key + * associated with the active key's session ID. The third is a detached + * lame duck session that only occurs in situations where a key renegotiate + * failed on the active key, but a lame duck key was still valid. By + * preserving the lame duck session, we can be assured of having a data + * channel key available even when network conditions are so bad that + * we can't negotiate a new key within the time allotted. + */ +#define KEY_SCAN_SIZE 3 + + +/** + * Security parameter state for a single VPN tunnel. + * @ingroup control_processor + * + * An active VPN tunnel running with TLS enabled has one \c tls_multi + * object, in which it stores all control channel and data channel + * security parameter state. This structure can contain multiple, + * possibly simultaneously active, \c tls_context objects to allow for + * interruption-less transitions during session renegotiations. Each \c + * tls_context represents one control channel session, which can span + * multiple data channel security parameter sessions stored in \c + * key_state structures. + */ +struct tls_multi +{ + /* used to coordinate access between main thread and TLS thread */ + /*MUTEX_PTR_DEFINE (mutex);*/ + + /* const options and config info */ + struct tls_options opt; + + struct key_state* key_scan[KEY_SCAN_SIZE]; + /**< List of \c key_state objects in the + * order they should be scanned by data + * channel modules. */ + + /* + * used by tls_pre_encrypt to communicate the encrypt key + * to tls_post_encrypt() + */ + struct key_state *save_ks; /* temporary pointer used between pre/post routines */ + + /* + * Used to return outgoing address from + * tls_multi_process. + */ + struct link_socket_actual to_link_addr; + + int n_sessions; /**< Number of sessions negotiated thus + * far. */ + + /* + * Number of errors. + */ + int n_hard_errors; /* errors due to TLS negotiation failure */ + int n_soft_errors; /* errors due to unrecognized or failed-to-authenticate incoming packets */ + + /* + * Our locked common name, username, and cert hashes (cannot change during the life of this tls_multi object) + */ + char *locked_cn; + char *locked_username; + struct cert_hash_set *locked_cert_hash_set; + +#ifdef ENABLE_DEF_AUTH + /* + * An error message to send to client on AUTH_FAILED + */ + char *client_reason; + + /* + * 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 + + /* + * Our session objects. + */ + struct tls_session session[TM_SIZE]; + /**< Array of \c tls_session objects + * representing control channel + * sessions with the remote peer. */ +}; + + +#endif /* SSL_COMMON_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c new file mode 100644 index 0000000..a727b60 --- /dev/null +++ b/src/openvpn/ssl_openssl.c @@ -0,0 +1,1175 @@ +/* + * 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 OpenSSL 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_OPENSSL) + +#include "errlevel.h" +#include "buffer.h" +#include "misc.h" +#include "manage.h" +#include "memdbg.h" +#include "ssl_backend.h" +#include "ssl_common.h" +#include "base64.h" + +#ifdef ENABLE_CRYPTOAPI +#include "cryptoapi.h" +#endif + +#include "ssl_verify_openssl.h" + +#include <openssl/err.h> +#include <openssl/pkcs12.h> +#include <openssl/x509.h> +#include <openssl/crypto.h> + +/* + * Allocate space in SSL objects in which to store a struct tls_session + * pointer back to parent. + * + */ + +int mydata_index; /* GLOBAL */ + +void +tls_init_lib() +{ + SSL_library_init(); +#ifndef ENABLE_SMALL + SSL_load_error_strings(); +#endif + OpenSSL_add_all_algorithms (); + + mydata_index = SSL_get_ex_new_index(0, "struct session *", NULL, NULL, NULL); + ASSERT (mydata_index >= 0); +} + +void +tls_free_lib() +{ + EVP_cleanup(); +#ifndef ENABLE_SMALL + ERR_free_strings(); +#endif +} + +void +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) + { + msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength); + rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL); + } + return (rsa_tmp); +} + +void +tls_ctx_server_new(struct tls_root_ctx *ctx) +{ + ASSERT(NULL != ctx); + + ctx->ctx = SSL_CTX_new (TLSv1_server_method ()); + + if (ctx->ctx == NULL) + msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method"); + + SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb); +} + +void +tls_ctx_client_new(struct tls_root_ctx *ctx) +{ + ASSERT(NULL != ctx); + + ctx->ctx = SSL_CTX_new (TLSv1_client_method ()); + + if (ctx->ctx == NULL) + msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method"); +} + +void +tls_ctx_free(struct tls_root_ctx *ctx) +{ + ASSERT(NULL != ctx); + if (NULL != ctx->ctx) + SSL_CTX_free (ctx->ctx); + ctx->ctx = NULL; +} + +bool tls_ctx_initialised(struct tls_root_ctx *ctx) +{ + ASSERT(NULL != ctx); + return NULL != ctx->ctx; +} + +/* + * Print debugging information on SSL/TLS session negotiation. + */ + +#ifndef INFO_CALLBACK_SSL_CONST +#define INFO_CALLBACK_SSL_CONST const +#endif +static void +info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret) +{ + if (where & SSL_CB_LOOP) + { + dmsg (D_HANDSHAKE_VERBOSE, "SSL state (%s): %s", + where & SSL_ST_CONNECT ? "connect" : + where & SSL_ST_ACCEPT ? "accept" : + "undefined", SSL_state_string_long (s)); + } + else if (where & SSL_CB_ALERT) + { + dmsg (D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s", + where & SSL_CB_READ ? "read" : "write", + SSL_alert_type_string_long (ret), + SSL_alert_desc_string_long (ret)); + } +} + +void +tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) +{ + ASSERT(NULL != ctx); + + SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_options (ctx->ctx, SSL_OP_SINGLE_DH_USE); + SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback); + + /* Require peer certificate verification */ +#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"); + } + else +#endif + SSL_CTX_set_verify (ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); + + SSL_CTX_set_info_callback (ctx->ctx, info_callback); +} + +void +tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) +{ + ASSERT(NULL != ctx); + + if(!SSL_CTX_set_cipher_list(ctx->ctx, ciphers)) + msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", ciphers); +} + +void +tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, + const char *dh_file_inline + ) +{ + DH *dh; + BIO *bio; + + ASSERT(NULL != ctx); + + if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline) + { + if (!(bio = BIO_new_mem_buf ((char *)dh_file_inline, -1))) + msg (M_SSLERR, "Cannot open memory BIO for inline DH parameters"); + } + else + { + /* Get Diffie Hellman Parameters */ + if (!(bio = BIO_new_file (dh_file, "r"))) + msg (M_SSLERR, "Cannot open %s for DH parameters", dh_file); + } + + dh = PEM_read_bio_DHparams (bio, NULL, NULL, NULL); + BIO_free (bio); + + if (!dh) + msg (M_SSLERR, "Cannot load DH parameters from %s", dh_file); + if (!SSL_CTX_set_tmp_dh (ctx->ctx, dh)) + msg (M_SSLERR, "SSL_CTX_set_tmp_dh"); + + msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key", + 8 * DH_size (dh)); + + DH_free (dh); +} + +int +tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, + const char *pkcs12_file_inline, + bool load_ca_file + ) +{ + FILE *fp; + EVP_PKEY *pkey; + X509 *cert; + STACK_OF(X509) *ca = NULL; + PKCS12 *p12; + int i; + char password[256]; + + ASSERT(NULL != ctx); + + if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline) + { + BIO *b64 = BIO_new(BIO_f_base64()); + BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline, + (int) strlen(pkcs12_file_inline)); + ASSERT(b64 && bio); + BIO_push(b64, bio); + p12 = d2i_PKCS12_bio(b64, NULL); + if (!p12) + msg(M_SSLERR, "Error reading inline PKCS#12 file"); + BIO_free(b64); + BIO_free(bio); + } + else + { + /* Load the PKCS #12 file */ + if (!(fp = platform_fopen(pkcs12_file, "rb"))) + msg(M_SSLERR, "Error opening file %s", pkcs12_file); + p12 = d2i_PKCS12_fp(fp, NULL); + fclose(fp); + if (!p12) + msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file); + } + + /* Parse the PKCS #12 file */ + if (!PKCS12_parse(p12, "", &pkey, &cert, &ca)) + { + pem_password_callback (password, sizeof(password) - 1, 0, NULL); + /* Reparse the PKCS #12 file with password */ + ca = NULL; + if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) + { +#ifdef ENABLE_MANAGEMENT + if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE)) + management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); +#endif + PKCS12_free(p12); + return 1; + } + } + PKCS12_free(p12); + + /* Load Certificate */ + if (!SSL_CTX_use_certificate (ctx->ctx, cert)) + msg (M_SSLERR, "Cannot use certificate"); + + /* Load Private Key */ + if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey)) + msg (M_SSLERR, "Cannot use private key"); + warn_if_group_others_accessible (pkcs12_file); + + /* Check Private Key */ + if (!SSL_CTX_check_private_key (ctx->ctx)) + msg (M_SSLERR, "Private key does not match the certificate"); + + /* Set Certificate Verification chain */ + if (load_ca_file) + { + if (ca && sk_X509_num(ca)) + { + for (i = 0; i < sk_X509_num(ca); i++) + { + if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i))) + msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)"); + if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i))) + msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); + } + } + } + return 0; +} + +#ifdef ENABLE_CRYPTOAPI +void +tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) +{ + ASSERT(NULL != ctx); + + /* Load Certificate and Private Key */ + if (!SSL_CTX_use_CryptoAPI_certificate (ctx->ctx, cryptoapi_cert)) + msg (M_SSLERR, "Cannot load certificate \"%s\" from Microsoft Certificate Store", + cryptoapi_cert); +} +#endif /* WIN32 */ + +static void +tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio) +{ + X509 *cert; + for (;;) + { + cert = NULL; + if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ + break; + if (!cert) + msg (M_SSLERR, "Error reading extra certificate"); + if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) + msg (M_SSLERR, "Error adding extra certificate"); + } +} + +void +tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, + const char *cert_file_inline, X509 **x509 + ) +{ + BIO *in = NULL; + X509 *x = NULL; + int ret = 0; + bool inline_file = false; + + ASSERT (NULL != ctx); + if (NULL != x509) + ASSERT (NULL == *x509); + + inline_file = (strcmp (cert_file, INLINE_FILE_TAG) == 0); + + if (inline_file && cert_file_inline) + in = BIO_new_mem_buf ((char *)cert_file_inline, -1); + else + in = BIO_new_file (cert_file, "r"); + + if (in == NULL) + { + SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + + x = PEM_read_bio_X509 (in, NULL, ctx->ctx->default_passwd_callback, + ctx->ctx->default_passwd_callback_userdata); + if (x == NULL) + { + SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB); + goto end; + } + + ret = SSL_CTX_use_certificate (ctx->ctx, x); + if (ret) + tls_ctx_add_extra_certs (ctx, in); + +end: + if (!ret) + { + if (inline_file) + msg (M_SSLERR, "Cannot load inline certificate file"); + else + msg (M_SSLERR, "Cannot load certificate file %s", cert_file); + } + + if (in != NULL) + BIO_free(in); + if (x509) + *x509 = x; + else if (x) + X509_free (x); +} + +void +tls_ctx_free_cert_file (X509 *x509) +{ + X509_free(x509); +} + +int +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; + int ret = 1; + + ASSERT(NULL != ctx); + + ssl_ctx = ctx->ctx; + + if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline) + in = BIO_new_mem_buf ((char *)priv_key_file_inline, -1); + else + in = BIO_new_file (priv_key_file, "r"); + + if (!in) + goto end; + + pkey = PEM_read_bio_PrivateKey (in, NULL, + ssl_ctx->default_passwd_callback, + ssl_ctx->default_passwd_callback_userdata); + if (!pkey) + goto end; + + if (!SSL_CTX_use_PrivateKey (ssl_ctx, pkey)) + { +#ifdef ENABLE_MANAGEMENT + if (management && (ERR_GET_REASON (ERR_peek_error()) == EVP_R_BAD_DECRYPT)) + management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); +#endif + msg (M_WARN|M_SSL, "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)) + msg (M_SSLERR, "Private key does not match the certificate"); + ret = 0; + +end: + if (pkey) + EVP_PKEY_free (pkey); + if (in) + BIO_free (in); + return ret; +} + +#ifdef MANAGMENT_EXTERNAL_KEY + +/* encrypt */ +static int +rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + ASSERT(0); + return -1; +} + +/* verify arbitrary data */ +static int +rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + ASSERT(0); + return -1; +} + +/* decrypt */ +static int +rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + ASSERT(0); + return -1; +} + +/* called at RSA_free */ +static int +rsa_finish(RSA *rsa) +{ + free ((void*)rsa->meth); + rsa->meth = NULL; + return 1; +} + +/* sign arbitrary data */ +static int +rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + /* optional app data in rsa->meth->app_data; */ + char *in_b64 = NULL; + char *out_b64 = NULL; + int ret = -1; + int len; + + if (padding != RSA_PKCS1_PADDING) + { + RSAerr (RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto done; + } + + /* convert 'from' to base64 */ + if (openvpn_base64_encode (from, flen, &in_b64) <= 0) + goto done; + + /* call MI for signature */ + if (management) + out_b64 = management_query_rsa_sig (management, in_b64); + if (!out_b64) + goto done; + + /* decode base64 signature to binary */ + len = RSA_size(rsa); + ret = openvpn_base64_decode (out_b64, to, len); + + /* verify length */ + if (ret != len) + ret = -1; + + done: + if (in_b64) + free (in_b64); + if (out_b64) + free (out_b64); + return ret; +} + +int +tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert) +{ + RSA *rsa = NULL; + RSA *pub_rsa; + RSA_METHOD *rsa_meth; + + ASSERT (NULL != ctx); + ASSERT (NULL != cert); + + /* allocate custom RSA method object */ + ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD); + rsa_meth->name = "OpenVPN external private key RSA Method"; + rsa_meth->rsa_pub_enc = rsa_pub_enc; + rsa_meth->rsa_pub_dec = rsa_pub_dec; + rsa_meth->rsa_priv_enc = rsa_priv_enc; + rsa_meth->rsa_priv_dec = rsa_priv_dec; + rsa_meth->init = NULL; + rsa_meth->finish = rsa_finish; + rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; + rsa_meth->app_data = NULL; + + /* allocate RSA object */ + rsa = RSA_new(); + if (rsa == NULL) + { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the public key */ + ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */ + pub_rsa = cert->cert_info->key->pkey->pkey.rsa; + + /* initialize RSA object */ + rsa->n = BN_dup(pub_rsa->n); + rsa->flags |= RSA_FLAG_EXT_PKEY; + if (!RSA_set_method(rsa, rsa_meth)) + goto err; + + /* bind our custom RSA object to ssl_ctx */ + if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa)) + goto err; + + RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ + return 1; + + err: + if (rsa) + RSA_free(rsa); + else + { + if (rsa_meth) + free(rsa_meth); + } + msg (M_SSLERR, "Cannot enable SSL external private key capability"); + return 0; +} + +#endif + +static int +sk_x509_name_cmp(const X509_NAME * const *a, const X509_NAME * const *b) +{ + return X509_NAME_cmp (*a, *b); +} + +void +tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, + const char *ca_file_inline, + const char *ca_path, bool tls_server + ) +{ + STACK_OF(X509_INFO) *info_stack = NULL; + STACK_OF(X509_NAME) *cert_names = NULL; + X509_LOOKUP *lookup = NULL; + X509_STORE *store = NULL; + X509_NAME *xn = NULL; + BIO *in = NULL; + int i, added = 0; + + ASSERT(NULL != ctx); + + store = SSL_CTX_get_cert_store(ctx->ctx); + if (!store) + msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)"); + + /* Try to add certificates and CRLs from ca_file */ + if (ca_file) + { + if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline) + in = BIO_new_mem_buf ((char *)ca_file_inline, -1); + else + in = BIO_new_file (ca_file, "r"); + + if (in) + info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL); + + if (info_stack) + { + for (i = 0; i < sk_X509_INFO_num (info_stack); i++) + { + X509_INFO *info = sk_X509_INFO_value (info_stack, i); + if (info->crl) + X509_STORE_add_crl (store, info->crl); + + if (info->x509) + { + X509_STORE_add_cert (store, info->x509); + added++; + + if (!tls_server) + continue; + + /* Use names of CAs as a client CA list */ + if (cert_names == NULL) + { + cert_names = sk_X509_NAME_new (sk_x509_name_cmp); + if (!cert_names) + continue; + } + + xn = X509_get_subject_name (info->x509); + if (!xn) + continue; + + /* Don't add duplicate CA names */ + if (sk_X509_NAME_find (cert_names, xn) == -1) + { + xn = X509_NAME_dup (xn); + if (!xn) + continue; + sk_X509_NAME_push (cert_names, xn); + } + } + } + sk_X509_INFO_pop_free (info_stack, X509_INFO_free); + } + + if (tls_server) + SSL_CTX_set_client_CA_list (ctx->ctx, cert_names); + + if (!added || (tls_server && sk_X509_NAME_num (cert_names) != added)) + msg (M_SSLERR, "Cannot load CA certificate file %s", np(ca_file)); + if (in) + BIO_free (in); + } + + /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */ + if (ca_path) + { + lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ()); + if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM)) + msg(M_WARN, "WARNING: experimental option --capath %s", ca_path); + else + msg(M_SSLERR, "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 + } +} + +void +tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, + const char *extra_certs_file_inline + ) +{ + BIO *in; + if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) + in = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1); + else + in = BIO_new_file (extra_certs_file, "r"); + + if (in == NULL) + msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); + else + tls_ctx_add_extra_certs (ctx, in); + + BIO_free (in); +} + +/* ************************************** + * + * Key-state specific functions + * + ***************************************/ +/* + * + * BIO functions + * + */ + +#ifdef BIO_DEBUG + +#warning BIO_DEBUG defined + +static FILE *biofp; /* GLOBAL */ +static bool biofp_toggle; /* GLOBAL */ +static time_t biofp_last_open; /* GLOBAL */ +static const int biofp_reopen_interval = 600; /* GLOBAL */ + +static void +close_biofp() +{ + if (biofp) + { + ASSERT (!fclose (biofp)); + biofp = NULL; + } +} + +static void +open_biofp() +{ + const time_t current = time (NULL); + const pid_t pid = getpid (); + + if (biofp_last_open + biofp_reopen_interval < current) + close_biofp(); + if (!biofp) + { + char fn[256]; + openvpn_snprintf(fn, sizeof(fn), "bio/%d-%d.log", pid, biofp_toggle); + biofp = fopen (fn, "w"); + ASSERT (biofp); + biofp_last_open = time (NULL); + biofp_toggle ^= 1; + } +} + +static void +bio_debug_data (const char *mode, BIO *bio, const uint8_t *buf, int len, const char *desc) +{ + struct gc_arena gc = gc_new (); + if (len > 0) + { + open_biofp(); + fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n", + mode, desc, time (NULL), (ptr_type)bio, len, format_hex (buf, len, 0, &gc)); + fflush (biofp); + } + gc_free (&gc); +} + +static void +bio_debug_oc (const char *mode, BIO *bio) +{ + open_biofp(); + fprintf(biofp, "BIO %s time=" time_format " bio=" ptr_format "\n", + mode, time (NULL), (ptr_type)bio); + fflush (biofp); +} + +#endif + +/* + * OpenVPN's interface to SSL/TLS authentication, + * encryption, and decryption is exclusively + * through "memory BIOs". + */ +static BIO * +getbio (BIO_METHOD * type, const char *desc) +{ + BIO *ret; + ret = BIO_new (type); + if (!ret) + msg (M_SSLERR, "Error creating %s BIO", desc); + return ret; +} + +/* + * Write to an OpenSSL BIO in non-blocking mode. + */ +static int +bio_write (BIO *bio, const uint8_t *data, int size, const char *desc) +{ + int i; + int ret = 0; + ASSERT (size >= 0); + if (size) + { + /* + * Free the L_TLS lock prior to calling BIO routines + * so that foreground thread can still call + * tls_pre_decrypt or tls_pre_encrypt, + * allowing tunnel packet forwarding to continue. + */ +#ifdef BIO_DEBUG + bio_debug_data ("write", bio, data, size, desc); +#endif + i = BIO_write (bio, data, size); + + if (i < 0) + { + if (BIO_should_retry (bio)) + { + ; + } + else + { + msg (D_TLS_ERRORS | M_SSL, "TLS ERROR: BIO write %s error", + desc); + ret = -1; + ERR_clear_error (); + } + } + else if (i != size) + { + msg (D_TLS_ERRORS | M_SSL, + "TLS ERROR: BIO write %s incomplete %d/%d", desc, i, size); + ret = -1; + ERR_clear_error (); + } + else + { /* successful write */ + dmsg (D_HANDSHAKE_VERBOSE, "BIO write %s %d bytes", desc, i); + ret = 1; + } + } + return ret; +} + +/* + * Inline functions for reading from and writing + * to BIOs. + */ + +static void +bio_write_post (const int status, struct buffer *buf) +{ + if (status == 1) /* success status return from bio_write? */ + { + memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ + buf->len = 0; + } +} + +/* + * Read from an OpenSSL BIO in non-blocking mode. + */ +static int +bio_read (BIO *bio, struct buffer *buf, int maxlen, const char *desc) +{ + int i; + int ret = 0; + ASSERT (buf->len >= 0); + if (buf->len) + { + ; + } + else + { + int len = buf_forward_capacity (buf); + if (maxlen < len) + len = maxlen; + + /* + * BIO_read brackets most of the serious RSA + * key negotiation number crunching. + */ + i = BIO_read (bio, BPTR (buf), len); + + VALGRIND_MAKE_READABLE ((void *) &i, sizeof (i)); + +#ifdef BIO_DEBUG + bio_debug_data ("read", bio, BPTR (buf), i, desc); +#endif + if (i < 0) + { + if (BIO_should_retry (bio)) + { + ; + } + else + { + msg (D_TLS_ERRORS | M_SSL, "TLS_ERROR: BIO read %s error", + desc); + buf->len = 0; + ret = -1; + ERR_clear_error (); + } + } + else if (!i) + { + buf->len = 0; + } + else + { /* successful read */ + dmsg (D_HANDSHAKE_VERBOSE, "BIO read %s %d bytes", desc, i); + buf->len = i; + ret = 1; + VALGRIND_MAKE_READABLE ((void *) BPTR (buf), BLEN (buf)); + } + } + return ret; +} + +void +key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_ctx, bool is_server, void *session) +{ + ASSERT(NULL != ssl_ctx); + ASSERT(ks_ssl); + CLEAR (*ks_ssl); + + ks_ssl->ssl = SSL_new (ssl_ctx->ctx); + if (!ks_ssl->ssl) + msg (M_SSLERR, "SSL_new failed"); + + /* put session * in ssl object so we can access it + from verify callback*/ + SSL_set_ex_data (ks_ssl->ssl, mydata_index, session); + + ks_ssl->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio"); + ks_ssl->ct_in = getbio (BIO_s_mem (), "ct_in"); + ks_ssl->ct_out = getbio (BIO_s_mem (), "ct_out"); + +#ifdef BIO_DEBUG + bio_debug_oc ("open ssl_bio", ks_ssl->ssl_bio); + bio_debug_oc ("open ct_in", ks_ssl->ct_in); + bio_debug_oc ("open ct_out", ks_ssl->ct_out); +#endif + + if (is_server) + SSL_set_accept_state (ks_ssl->ssl); + else + SSL_set_connect_state (ks_ssl->ssl); + + SSL_set_bio (ks_ssl->ssl, ks_ssl->ct_in, ks_ssl->ct_out); + BIO_set_ssl (ks_ssl->ssl_bio, ks_ssl->ssl, BIO_NOCLOSE); +} + +void key_state_ssl_free(struct key_state_ssl *ks_ssl) +{ + if (ks_ssl->ssl) { +#ifdef BIO_DEBUG + bio_debug_oc ("close ssl_bio", ks_ssl->ssl_bio); + bio_debug_oc ("close ct_in", ks_ssl->ct_in); + bio_debug_oc ("close ct_out", ks_ssl->ct_out); +#endif + BIO_free_all(ks_ssl->ssl_bio); + SSL_free (ks_ssl->ssl); + } +} + +int +key_state_write_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf) +{ + int ret = 0; + perf_push (PERF_BIO_WRITE_PLAINTEXT); + +#ifdef ENABLE_CRYPTO_OPENSSL + ASSERT (NULL != ks_ssl); + + ret = bio_write (ks_ssl->ssl_bio, BPTR(buf), BLEN(buf), + "tls_write_plaintext"); + bio_write_post (ret, buf); +#endif /* ENABLE_CRYPTO_OPENSSL */ + + perf_pop (); + return ret; +} + +int +key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *data, int len) +{ + int ret = 0; + perf_push (PERF_BIO_WRITE_PLAINTEXT); + + ASSERT (NULL != ks_ssl); + + ret = bio_write (ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const"); + + perf_pop (); + return ret; +} + +int +key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf, + int maxlen) +{ + int ret = 0; + perf_push (PERF_BIO_READ_CIPHERTEXT); + + ASSERT (NULL != ks_ssl); + + ret = bio_read (ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext"); + + perf_pop (); + return ret; +} + +int +key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf) +{ + int ret = 0; + perf_push (PERF_BIO_WRITE_CIPHERTEXT); + + ASSERT (NULL != ks_ssl); + + ret = bio_write (ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); + bio_write_post (ret, buf); + + perf_pop (); + return ret; +} + +int +key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf, + int maxlen) +{ + int ret = 0; + perf_push (PERF_BIO_READ_PLAINTEXT); + + ASSERT (NULL != ks_ssl); + + ret = bio_read (ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext"); + + perf_pop (); + return ret; +} + +/* ************************************** + * + * Information functions + * + * Print information for the end user. + * + ***************************************/ +void +print_details (struct key_state_ssl * ks_ssl, const char *prefix) +{ + const SSL_CIPHER *ciph; + X509 *cert; + char s1[256]; + char s2[256]; + + s1[0] = s2[0] = 0; + ciph = SSL_get_current_cipher (ks_ssl->ssl); + openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s %s", + prefix, + SSL_get_version (ks_ssl->ssl), + SSL_CIPHER_get_version (ciph), + SSL_CIPHER_get_name (ciph)); + cert = SSL_get_peer_certificate (ks_ssl->ssl); + if (cert != NULL) + { + EVP_PKEY *pkey = X509_get_pubkey (cert); + if (pkey != NULL) + { + if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL + && pkey->pkey.rsa->n != NULL) + { + openvpn_snprintf (s2, sizeof (s2), ", %d bit RSA", + BN_num_bits (pkey->pkey.rsa->n)); + } + else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL + && pkey->pkey.dsa->p != NULL) + { + openvpn_snprintf (s2, sizeof (s2), ", %d bit DSA", + BN_num_bits (pkey->pkey.dsa->p)); + } + EVP_PKEY_free (pkey); + } + X509_free (cert); + } + /* The SSL API does not allow us to look at temporary RSA/DH keys, + * otherwise we should print their lengths too */ + msg (D_HANDSHAKE, "%s%s", s1, s2); +} + +void +show_available_tls_ciphers () +{ + SSL_CTX *ctx; + SSL *ssl; + const char *cipher_name; + int priority = 0; + + ctx = SSL_CTX_new (TLSv1_method ()); + if (!ctx) + msg (M_SSLERR, "Cannot create SSL_CTX object"); + + ssl = SSL_new (ctx); + if (!ssl) + msg (M_SSLERR, "Cannot create SSL object"); + + printf ("Available TLS Ciphers,\n"); + printf ("listed in order of preference:\n\n"); + while ((cipher_name = SSL_get_cipher_list (ssl, priority++))) + printf ("%s\n", cipher_name); + printf ("\n"); + + SSL_free (ssl); + SSL_CTX_free (ctx); +} + +void +get_highest_preference_tls_cipher (char *buf, int size) +{ + SSL_CTX *ctx; + SSL *ssl; + const char *cipher_name; + + ctx = SSL_CTX_new (TLSv1_method ()); + if (!ctx) + msg (M_SSLERR, "Cannot create SSL_CTX object"); + ssl = SSL_new (ctx); + if (!ssl) + msg (M_SSLERR, "Cannot create SSL object"); + + cipher_name = SSL_get_cipher_list (ssl, 0); + strncpynt (buf, cipher_name, size); + + SSL_free (ssl); + SSL_CTX_free (ctx); +} + +#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/src/openvpn/ssl_openssl.h b/src/openvpn/ssl_openssl.h new file mode 100644 index 0000000..fc2052c --- /dev/null +++ b/src/openvpn/ssl_openssl.h @@ -0,0 +1,58 @@ +/* + * 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 OpenSSL Backend + */ + +#ifndef SSL_OPENSSL_H_ +#define SSL_OPENSSL_H_ + +#include <openssl/ssl.h> + +/** + * Structure that wraps the TLS context. Contents differ depending on the + * SSL library used. + */ +struct tls_root_ctx { + SSL_CTX *ctx; +}; + +struct key_state_ssl { + SSL *ssl; /* SSL object -- new obj created for each new key */ + BIO *ssl_bio; /* read/write plaintext from here */ + BIO *ct_in; /* write ciphertext to here */ + BIO *ct_out; /* read ciphertext from here */ +}; + +/** + * Allocate space in SSL objects in which to store a struct tls_session + * pointer back to parent. + */ +extern int mydata_index; /* GLOBAL */ + +void openssl_set_mydata_index (void); + +#endif /* SSL_OPENSSL_H_ */ diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c new file mode 100644 index 0000000..12318b3 --- /dev/null +++ b/src/openvpn/ssl_polarssl.c @@ -0,0 +1,870 @@ +/* + * 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 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 "errlevel.h" +#include "ssl_backend.h" +#include "buffer.h" +#include "misc.h" +#include "manage.h" +#include "ssl_common.h" + +#include <polarssl/sha2.h> +#include <polarssl/havege.h> + +#include "ssl_verify_polarssl.h" +#include <polarssl/pem.h> + +void +tls_init_lib() +{ +} + +void +tls_free_lib() +{ +} + +void +tls_clear_error() +{ +} + +static int default_ciphersuites[] = +{ + SSL_EDH_RSA_AES_256_SHA, + SSL_EDH_RSA_CAMELLIA_256_SHA, + SSL_EDH_RSA_AES_128_SHA, + SSL_EDH_RSA_CAMELLIA_128_SHA, + SSL_EDH_RSA_DES_168_SHA, + SSL_RSA_AES_256_SHA, + SSL_RSA_CAMELLIA_256_SHA, + SSL_RSA_AES_128_SHA, + SSL_RSA_CAMELLIA_128_SHA, + SSL_RSA_DES_168_SHA, + SSL_RSA_RC4_128_SHA, + SSL_RSA_RC4_128_MD5, + 0 +}; + +void +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->priv_key, rsa_context); + + ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert); + ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert); + + + ctx->endpoint = SSL_IS_SERVER; + ctx->initialised = true; +} + +void +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->priv_key, rsa_context); + + ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert); + ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert); + + ctx->endpoint = SSL_IS_CLIENT; + ctx->initialised = true; +} + +void +tls_ctx_free(struct tls_root_ctx *ctx) +{ + if (ctx) + { + rsa_free(ctx->priv_key); + free(ctx->priv_key); + + x509_free(ctx->ca_chain); + free(ctx->ca_chain); + + x509_free(ctx->crt_chain); + free(ctx->crt_chain); + + dhm_free(ctx->dhm_ctx); + free(ctx->dhm_ctx); + +#if defined(ENABLE_PKCS11) + if (ctx->priv_key_pkcs11 != NULL) { + pkcs11_priv_key_free(ctx->priv_key_pkcs11); + free(ctx->priv_key_pkcs11); + } +#endif + + if (ctx->allowed_ciphers) + free(ctx->allowed_ciphers); + + CLEAR(*ctx); + + ctx->initialised = false; + + } +} + +bool +tls_ctx_initialised(struct tls_root_ctx *ctx) +{ + ASSERT(NULL != ctx); + return ctx->initialised; +} + +void +tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) +{ +} + +void +tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) +{ + char *tmp_ciphers, *tmp_ciphers_orig, *token; + int i, cipher_count; + int ciphers_len = strlen (ciphers); + + ASSERT (NULL != ctx); + ASSERT (0 != ciphers_len); + + /* Get number of ciphers */ + for (i = 0, cipher_count = 1; i < ciphers_len; i++) + if (ciphers[i] == ':') + cipher_count++; + + /* Allocate an array for them */ + ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1) + + /* Parse allowed ciphers, getting IDs */ + i = 0; + tmp_ciphers_orig = tmp_ciphers = strdup(ciphers); + + token = strtok (tmp_ciphers, ":"); + while(token) + { + ctx->allowed_ciphers[i] = ssl_get_ciphersuite_id (token); + if (0 != ctx->allowed_ciphers[i]) + i++; + token = strtok (NULL, ":"); + } + free(tmp_ciphers_orig); +} + +void +tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, + const char *dh_file_inline + ) +{ + if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline) + { + if (0 != x509parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline))) + msg (M_FATAL, "Cannot read inline DH parameters"); + } +else + { + if (0 != x509parse_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)); +} + +int +tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, + const char *pkcs12_file_inline, + bool load_ca_file + ) +{ + msg(M_FATAL, "PKCS #12 files not yet supported for PolarSSL."); + return 0; +} + +#ifdef ENABLE_CRYPTOAPI +void +tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) +{ + msg(M_FATAL, "Windows CryptoAPI not yet supported for PolarSSL."); +} +#endif /* WIN32 */ + +void +tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, + const char *cert_file_inline, + openvpn_x509_cert_t **x509 + ) +{ + ASSERT(NULL != ctx); + if (NULL != x509) + ASSERT(NULL == *x509); + + if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline) + { + if (0 != x509parse_crt(ctx->crt_chain, cert_file_inline, + strlen(cert_file_inline))) + msg (M_FATAL, "Cannot load inline certificate file"); + } + else + { + if (0 != x509parse_crtfile(ctx->crt_chain, cert_file)) + msg (M_FATAL, "Cannot load certificate file %s", cert_file); + } + if (x509) + { + *x509 = ctx->crt_chain; + } +} + +void +tls_ctx_free_cert_file (openvpn_x509_cert_t *x509) +{ + x509_free(x509); +} + +int +tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file, + const char *priv_key_file_inline + ) +{ + int status; + ASSERT(NULL != ctx); + + if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline) + { + status = x509parse_key(ctx->priv_key, + priv_key_file_inline, strlen(priv_key_file_inline), + NULL, 0); + if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status) + { + char passbuf[512] = {0}; + pem_password_callback(passbuf, 512, 0, NULL); + status = x509parse_key(ctx->priv_key, + priv_key_file_inline, strlen(priv_key_file_inline), + passbuf, strlen(passbuf)); + } + } + else + { + status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL); + if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status) + { + char passbuf[512] = {0}; + pem_password_callback(passbuf, 512, 0, NULL); + status = x509parse_keyfile(ctx->priv_key, priv_key_file, passbuf); + } + } + if (0 != status) + { +#ifdef ENABLE_MANAGEMENT + if (management && (POLARSSL_ERR_PEM_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); + + /* 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; +} + +#ifdef MANAGMENT_EXTERNAL_KEY + +int +tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, openvpn_x509_cert_t *cert) +{ + msg(M_FATAL, "Use of management external keys not yet supported for PolarSSL."); + return false; +} + +#endif + +void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, + const char *ca_file_inline, + const char *ca_path, bool tls_server + ) +{ + if (ca_path) + msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive"); + + if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline) + { + if (0 != x509parse_crt(ctx->ca_chain, ca_file_inline, strlen(ca_file_inline))) + msg (M_FATAL, "Cannot load inline CA certificates"); + } + else + { + /* Load CA file for verifying peer supplied certificate */ + if (0 != x509parse_crtfile(ctx->ca_chain, ca_file)) + msg (M_FATAL, "Cannot load CA certificate file %s", ca_file); + } +} + +void +tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file, + const char *extra_certs_file_inline + ) +{ + ASSERT(NULL != ctx); + + if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) + { + if (0 != x509parse_crt(ctx->crt_chain, extra_certs_file_inline, + strlen(extra_certs_file_inline))) + msg (M_FATAL, "Cannot load inline extra-certs file"); + } + else + { + if (0 != x509parse_crtfile(ctx->crt_chain, extra_certs_file)) + msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file); + } +} + +/* ************************************** + * + * Key-state specific functions + * + ***************************************/ + +/* + * "Endless buffer" + */ + +static inline void buf_free_entry(buffer_entry *entry) +{ + if (NULL != entry) + { + free(entry->data); + free(entry); + } +} + +static void buf_free_entries(endless_buffer *buf) +{ + while(buf->first_block) + { + buffer_entry *cur_block = buf->first_block; + buf->first_block = cur_block->next_block; + buf_free_entry(cur_block); + } + buf->last_block = NULL; +} + +static int endless_buf_read( void * ctx, 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; + + while (in->first_block != NULL && read_len < out_len) + { + int block_len = in->first_block->length - in->data_start; + if (block_len <= out_len - read_len) + { + buffer_entry *cur_entry = in->first_block; + memcpy(out + read_len, cur_entry->data + in->data_start, + block_len); + + read_len += block_len; + + in->first_block = cur_entry->next_block; + in->data_start = 0; + + if (in->first_block == NULL) + in->last_block = NULL; + + buf_free_entry(cur_entry); + } + else + { + memcpy(out + read_len, in->first_block->data + in->data_start, + out_len - read_len); + in->data_start += out_len - read_len; + read_len = out_len; + } + } + + return read_len; +} + +static int endless_buf_write( void *ctx, 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; + + new_block->data = malloc(len); + if (NULL == new_block->data) + { + free(new_block); + return POLARSSL_ERR_NET_SEND_FAILED; + } + + new_block->length = len; + new_block->next_block = NULL; + + memcpy(new_block->data, in, len); + + if (NULL == out->first_block) + out->first_block = new_block; + + if (NULL != out->last_block) + out->last_block->next_block = new_block; + + out->last_block = new_block; + + return len; +} + +static void my_debug( void *ctx, int level, const char *str ) +{ + if (level == 1) + { + dmsg (D_HANDSHAKE_VERBOSE, "PolarSSL alert: %s", str); + } +} + +/* + * Further personalise the RNG using a hash of the public key + */ +void tls_ctx_personalise_random(struct tls_root_ctx *ctx) +{ + static char old_sha256_hash[32] = {0}; + char sha256_hash[32] = {0}; + ctr_drbg_context *cd_ctx = rand_ctx_get(); + + if (NULL != ctx->crt_chain) + { + x509_cert *cert = ctx->crt_chain; + + sha2(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); + memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash)); + } + } +} + +void key_state_ssl_init(struct key_state_ssl *ks_ssl, + const struct tls_root_ctx *ssl_ctx, bool is_server, void *session) +{ + ASSERT(NULL != ssl_ctx); + ASSERT(ks_ssl); + CLEAR(*ks_ssl); + + ALLOC_OBJ_CLEAR(ks_ssl->ctx, ssl_context); + if (0 == ssl_init(ks_ssl->ctx)) + { + /* Initialise SSL context */ + 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()); + + ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session); + ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn ); + if (ssl_ctx->allowed_ciphers) + ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers); + else + ssl_set_ciphersuites (ks_ssl->ctx, default_ciphersuites); + + /* Initialise authentication information */ + if (is_server) + ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx ); +#if defined(ENABLE_PKCS11) + if (ssl_ctx->priv_key_pkcs11 != NULL) + ssl_set_own_cert_pkcs11( ks_ssl->ctx, ssl_ctx->crt_chain, + ssl_ctx->priv_key_pkcs11 ); + else +#endif + ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key ); + + /* Initialise SSL verification */ + ssl_set_authmode (ks_ssl->ctx, SSL_VERIFY_REQUIRED); + ssl_set_verify (ks_ssl->ctx, verify_callback, session); + /* 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 ); + + /* 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); + + } +} + +void +key_state_ssl_free(struct key_state_ssl *ks_ssl) +{ + if (ks_ssl) { + if (ks_ssl->ctx) + { + ssl_free(ks_ssl->ctx); + free(ks_ssl->ctx); + } + if (ks_ssl->ssn) + free(ks_ssl->ssn); + 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); + } + CLEAR(*ks_ssl); + } +} + +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) + { + return 0; + perf_pop (); + } + + 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; + } + + if (retval != buf->len) + { + msg (D_TLS_ERRORS, + "TLS ERROR: write tls_write_plaintext incomplete %d/%d", + retval, buf->len); + perf_pop (); + return -1; + } + + /* 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; +} + +int +key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, int len) +{ + int retval = 0; + perf_push (PERF_BIO_WRITE_PLAINTEXT); + + ASSERT (NULL != ks); + ASSERT (len >= 0); + + if (0 == len) + { + perf_pop (); + return 0; + } + + ASSERT (data); + + retval = ssl_write(ks->ctx, data, 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_const error"); + return -1; + } + + if (retval != len) + { + msg (D_TLS_ERRORS, + "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d", + retval, len); + perf_pop (); + return -1; + } + + /* successful write */ + dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval); + + perf_pop (); + return 1; +} + +int +key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf, + int maxlen) +{ + int retval = 0; + int len = 0; + + perf_push (PERF_BIO_READ_CIPHERTEXT); + + ASSERT (NULL != ks); + ASSERT (buf); + ASSERT (buf->len >= 0); + + if (buf->len) + { + perf_pop (); + return 0; + } + + len = buf_forward_capacity (buf); + if (maxlen < len) + len = maxlen; + + retval = endless_buf_read(ks->ct_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) + return 0; + msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error"); + buf->len = 0; + return -1; + } + /* Nothing read, try again */ + if (0 == retval) + { + buf->len = 0; + perf_pop (); + return 0; + } + + /* successful read */ + dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval); + buf->len = retval; + perf_pop (); + return 1; +} + +int +key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf) +{ + int retval = 0; + perf_push (PERF_BIO_WRITE_CIPHERTEXT); + + ASSERT (NULL != ks); + ASSERT (buf); + ASSERT (buf->len >= 0); + + if (0 == buf->len) + { + perf_pop (); + return 0; + } + + retval = endless_buf_write(ks->ct_in, 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_ciphertext error"); + return -1; + } + + if (retval != buf->len) + { + msg (D_TLS_ERRORS, + "TLS ERROR: write tls_write_ciphertext incomplete %d/%d", + retval, buf->len); + perf_pop (); + return -1; + } + + /* successful write */ + dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval); + + memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */ + buf->len = 0; + + perf_pop (); + return 1; +} + +int +key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf, + int maxlen) +{ + int retval = 0; + int len = 0; + + perf_push (PERF_BIO_READ_PLAINTEXT); + + ASSERT (NULL != ks); + ASSERT (buf); + ASSERT (buf->len >= 0); + + if (buf->len) + { + perf_pop (); + return 0; + } + + len = buf_forward_capacity (buf); + if (maxlen < len) + len = maxlen; + + retval = 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) + return 0; + msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error"); + buf->len = 0; + perf_pop (); + return -1; + } + /* Nothing read, try again */ + if (0 == retval) + { + buf->len = 0; + perf_pop (); + return 0; + } + + /* successful read */ + dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval); + buf->len = retval; + + perf_pop (); + return 1; +} + +/* ************************************** + * + * Information functions + * + * Print information for the end user. + * + ***************************************/ +void +print_details (struct key_state_ssl * ks_ssl, const char *prefix) +{ + x509_cert *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)); + + cert = ks_ssl->ctx->peer_cert; + if (cert != NULL) + { + openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) cert->rsa.len * 8); + } + + msg (D_HANDSHAKE, "%s%s", s1, s2); +} + +void +show_available_tls_ciphers () +{ + const int *ciphers = ssl_list_ciphersuites(); + +#ifndef ENABLE_SMALL + printf ("Available TLS Ciphers,\n"); + printf ("listed in order of preference:\n\n"); +#endif + + while (*ciphers != 0) + { + printf ("%s\n", ssl_get_ciphersuite_name(*ciphers)); + ciphers++; + } + printf ("\n"); +} + +void +get_highest_preference_tls_cipher (char *buf, int size) +{ + const char *cipher_name; + const int *ciphers = ssl_list_ciphersuites(); + if (*ciphers == 0) + msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers."); + + cipher_name = ssl_get_ciphersuite_name(*ciphers); + strncpynt (buf, cipher_name, size); +} + +#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/src/openvpn/ssl_polarssl.h b/src/openvpn/ssl_polarssl.h new file mode 100644 index 0000000..456573f --- /dev/null +++ b/src/openvpn/ssl_polarssl.h @@ -0,0 +1,82 @@ +/* + * 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 PolarSSL Backend + */ + +#ifndef SSL_POLARSSL_H_ +#define SSL_POLARSSL_H_ + +#include <polarssl/ssl.h> + +#if defined(ENABLE_PKCS11) +#include <polarssl/pkcs11.h> +#endif + +typedef struct _buffer_entry buffer_entry; + +struct _buffer_entry { + size_t length; + uint8_t *data; + buffer_entry *next_block; +}; + +typedef struct { + size_t data_start; + buffer_entry *first_block; + buffer_entry *last_block; +} endless_buffer; + +/** + * Structure that wraps the TLS context. Contents differ depending on the + * SSL library used. + * + * Either \c priv_key_pkcs11 or \c priv_key must be filled in. + */ +struct tls_root_ctx { + bool initialised; /**< True if the context has been initialised */ + + int endpoint; /**< Whether or not this is a server or a client */ + + dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */ + x509_cert *crt_chain; /**< Local Certificate chain */ + x509_cert *ca_chain; /**< CA chain for remote verification */ + rsa_context *priv_key; /**< Local private key */ +#if defined(ENABLE_PKCS11) + pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ +#endif + int * allowed_ciphers; /**< List of allowed ciphers for this connection */ +}; + +struct key_state_ssl { + ssl_context *ctx; + ssl_session *ssn; + endless_buffer *ct_in; + endless_buffer *ct_out; +}; + + +#endif /* SSL_POLARSSL_H_ */ diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c new file mode 100644 index 0000000..cac46e9 --- /dev/null +++ b/src/openvpn/ssl_verify.c @@ -0,0 +1,1265 @@ +/* + * 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 + */ + +#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_SSL) + +#include "misc.h" +#include "manage.h" +#include "ssl_verify.h" +#include "ssl_verify_backend.h" + +#ifdef ENABLE_CRYPTO_OPENSSL +#include "ssl_verify_openssl.h" +#endif + +/** Maximum length of common name */ +#define TLS_USERNAME_LEN 64 + +/** Legal characters in an X509 name with --compat-names */ +#define X509_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_SLASH|CC_COLON|CC_EQUAL) + +/** Legal characters in a common name with --compat-names */ +#define COMMON_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_SLASH) + +static void +string_mod_remap_name (char *str, const unsigned int restrictive_flags) +{ + if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES) + && !compat_flag (COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING)) + string_mod (str, restrictive_flags, 0, '_'); + else + string_mod (str, CC_PRINT, CC_CRLF, '_'); +} + +/* + * Export the untrusted IP address and port to the environment + */ +static void +setenv_untrusted (struct tls_session *session) +{ + setenv_link_socket_actual (session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT); +} + +/* + * Remove authenticated state from all sessions in the given tunnel + */ +static void +tls_deauthenticate (struct tls_multi *multi) +{ + if (multi) + { + int i, j; + for (i = 0; i < TM_SIZE; ++i) + for (j = 0; j < KS_SIZE; ++j) + multi->session[i].key[j].authenticated = false; + } +} + +/* + * Set the given session's common_name + */ +static void +set_common_name (struct tls_session *session, const char *common_name) +{ + if (session->common_name) + { + free (session->common_name); + session->common_name = NULL; +#ifdef ENABLE_PF + session->common_name_hashval = 0; +#endif + } + if (common_name) + { + /* FIXME: Last alloc will never be freed */ + session->common_name = string_alloc (common_name, NULL); +#ifdef ENABLE_PF + { + const uint32_t len = (uint32_t) strlen (common_name); + if (len) + session->common_name_hashval = hash_func ((const uint8_t*)common_name, len+1, 0); + else + session->common_name_hashval = 0; + } +#endif + } +} + +/* + * Retrieve the common name for the given tunnel's active session. If the + * common name is NULL or empty, return NULL if null is true, or "UNDEF" if + * null is false. + */ +const char * +tls_common_name (const struct tls_multi *multi, const bool null) +{ + const char *ret = NULL; + if (multi) + ret = multi->session[TM_ACTIVE].common_name; + if (ret && strlen (ret)) + return ret; + else if (null) + return NULL; + else + return "UNDEF"; +} + +/* + * Lock the common name for the given tunnel. + */ +void +tls_lock_common_name (struct tls_multi *multi) +{ + const char *cn = multi->session[TM_ACTIVE].common_name; + if (cn && !multi->locked_cn) + multi->locked_cn = string_alloc (cn, NULL); +} + +/* + * Lock the username for the given tunnel + */ +static bool +tls_lock_username (struct tls_multi *multi, const char *username) +{ + if (multi->locked_username) + { + if (!username || strcmp (username, multi->locked_username)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled", + multi->locked_username, + np(username)); + + /* disable the tunnel */ + tls_deauthenticate (multi); + return false; + } + } + else + { + if (username) + multi->locked_username = string_alloc (username, NULL); + } + return true; +} + +const char * +tls_username (const struct tls_multi *multi, const bool null) +{ + const char *ret = NULL; + if (multi) + ret = multi->locked_username; + if (ret && strlen (ret)) + return ret; + else if (null) + return NULL; + else + return "UNDEF"; +} + +void +cert_hash_remember (struct tls_session *session, const int error_depth, const unsigned char *sha1_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); + 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)); + } + } + gc_free (&gc); +} +#endif + +void +cert_hash_free (struct cert_hash_set *chs) +{ + if (chs) + { + int i; + for (i = 0; i < MAX_CERT_DEPTH; ++i) + free (chs->ch[i]); + free (chs); + } +} + +static bool +cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2) +{ + if (chs1 && chs2) + { + int i; + for (i = 0; i < MAX_CERT_DEPTH; ++i) + { + const struct cert_hash *ch1 = chs1->ch[i]; + const struct cert_hash *ch2 = chs2->ch[i]; + + if (!ch1 && !ch2) + continue; + else if (ch1 && ch2 && !memcmp (ch1->sha1_hash, ch2->sha1_hash, SHA_DIGEST_LENGTH)) + continue; + else + return false; + } + return true; + } + else if (!chs1 && !chs2) + return true; + else + return false; +} + +static struct cert_hash_set * +cert_hash_copy (const struct cert_hash_set *chs) +{ + struct cert_hash_set *dest = NULL; + if (chs) + { + int i; + ALLOC_OBJ_CLEAR (dest, struct cert_hash_set); + for (i = 0; i < MAX_CERT_DEPTH; ++i) + { + const struct cert_hash *ch = chs->ch[i]; + if (ch) + { + ALLOC_OBJ (dest->ch[i], struct cert_hash); + memcpy (dest->ch[i]->sha1_hash, ch->sha1_hash, SHA_DIGEST_LENGTH); + } + } + } + return dest; +} +void +tls_lock_cert_hash_set (struct tls_multi *multi) +{ + const struct cert_hash_set *chs = multi->session[TM_ACTIVE].cert_hash_set; + if (chs && !multi->locked_cert_hash_set) + multi->locked_cert_hash_set = cert_hash_copy (chs); +} + +/* + * Returns the string associated with the given certificate type. + */ +static const char * +print_nsCertType (int type) +{ + switch (type) + { + case NS_CERT_CHECK_SERVER: + return "SERVER"; + case NS_CERT_CHECK_CLIENT: + return "CLIENT"; + default: + return "?"; + } +} + +/* + * Verify the peer's certificate fields. + * + * @param opt the tls options to verify against + * @param peer_cert the peer's certificate + * @param subject the peer's extracted subject name + * @param subject the peer's extracted common name + */ +static result_t +verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert, + const char *subject, const char *common_name) +{ + /* verify certificate nsCertType */ + if (opt->ns_cert_type != NS_CERT_CHECK_NONE) + { + if (SUCCESS == x509_verify_ns_cert_type (peer_cert, opt->ns_cert_type)) + { + msg (D_HANDSHAKE, "VERIFY OK: nsCertType=%s", + print_nsCertType (opt->ns_cert_type)); + } + else + { + msg (D_HANDSHAKE, "VERIFY nsCertType ERROR: %s, require nsCertType=%s", + subject, print_nsCertType (opt->ns_cert_type)); + return FAILURE; /* Reject connection */ + } + } + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL + + /* verify certificate ku */ + if (opt->remote_cert_ku[0] != 0) + { + if (SUCCESS == x509_verify_cert_ku (peer_cert, opt->remote_cert_ku, MAX_PARMS)) + { + msg (D_HANDSHAKE, "VERIFY KU OK"); + } + else + { + msg (D_HANDSHAKE, "VERIFY KU ERROR"); + return FAILURE; /* Reject connection */ + } + } + + /* verify certificate eku */ + if (opt->remote_cert_eku != NULL) + { + if (SUCCESS == x509_verify_cert_eku (peer_cert, opt->remote_cert_eku)) + { + msg (D_HANDSHAKE, "VERIFY EKU OK"); + } + else + { + msg (D_HANDSHAKE, "VERIFY EKU ERROR"); + return FAILURE; /* Reject connection */ + } + } + +#endif /* OPENSSL_VERSION_NUMBER */ + + /* verify X509 name or common name against --tls-remote */ + if (opt->verify_x509name && strlen (opt->verify_x509name) > 0) + { + if (strcmp (opt->verify_x509name, subject) == 0 + || strncmp (opt->verify_x509name, common_name, strlen (opt->verify_x509name)) == 0) + msg (D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject); + else + { + msg (D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s", + subject, opt->verify_x509name); + return FAILURE; /* Reject connection */ + } + } + + return SUCCESS; +} + +/* + * Export the subject, common_name, and raw certificate fields to the + * environment for later verification by scripts and plugins. + */ +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 + ) +{ + 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 */ + openvpn_snprintf (envname, sizeof(envname), "tls_id_%d", cert_depth); + setenv_str (es, envname, subject); + +#if 0 + /* export common name string as environmental variable */ + openvpn_snprintf (envname, sizeof(envname), "tls_common_name_%d", cert_depth); + setenv_str (es, envname, common_name); +#endif + +#ifdef ENABLE_EUREPHIA + /* export X509 cert SHA1 fingerprint */ + { + unsigned char *sha1_hash = x509_get_sha1_hash(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)); + } +#endif + + /* export serial number as environmental variable */ + serial = x509_get_serial(peer_cert, &gc); + openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", cert_depth); + setenv_str (es, envname, serial); + + gc_free(&gc); +} + +/* + * call --tls-verify plug-in(s) + */ +static result_t +verify_cert_call_plugin(const struct plugin_list *plugins, struct env_set *es, + int cert_depth, openvpn_x509_cert_t *cert, char *subject) +{ + if (plugin_defined (plugins, OPENVPN_PLUGIN_TLS_VERIFY)) + { + int ret; + struct argv argv = argv_new (); + + argv_printf (&argv, "%d %s", cert_depth, subject); + + ret = plugin_call_ssl (plugins, OPENVPN_PLUGIN_TLS_VERIFY, &argv, NULL, es, cert_depth, cert); + + argv_reset (&argv); + + if (ret == OPENVPN_PLUGIN_FUNC_SUCCESS) + { + msg (D_HANDSHAKE, "VERIFY PLUGIN OK: depth=%d, %s", + cert_depth, subject); + } + else + { + msg (D_HANDSHAKE, "VERIFY PLUGIN ERROR: depth=%d, %s", + cert_depth, subject); + return FAILURE; /* Reject connection */ + } + } + return SUCCESS; +} + +static const char * +verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, struct gc_arena *gc) +{ + FILE *peercert_file; + const char *peercert_filename=""; + + if(!tmp_dir) + return NULL; + + /* create tmp file to store peer cert */ + peercert_filename = create_temp_file (tmp_dir, "pcf", gc); + + /* write peer-cert in tmp-file */ + peercert_file = fopen(peercert_filename, "w+"); + if(!peercert_file) + { + msg (M_ERR, "Failed to open temporary file : %s", peercert_filename); + return NULL; + } + + if (SUCCESS != x509_write_pem(peercert_file, peercert)) + msg (M_ERR, "Error writing PEM file containing certificate"); + + fclose(peercert_file); + return peercert_filename; +} + + +/* + * run --tls-verify script + */ +static result_t +verify_cert_call_command(const char *verify_command, struct env_set *es, + int cert_depth, openvpn_x509_cert_t *cert, char *subject, const char *verify_export_cert) +{ + const char *tmp_file = NULL; + int ret; + struct gc_arena gc = gc_new(); + struct argv argv = argv_new (); + + setenv_str (es, "script_type", "tls-verify"); + + if (verify_export_cert) + { + if ((tmp_file=verify_cert_export_cert(cert, verify_export_cert, &gc))) + { + setenv_str(es, "peer_cert", tmp_file); + } + } + + argv_printf (&argv, "%sc %d %s", verify_command, cert_depth, subject); + + argv_msg_prefix (D_TLS_DEBUG, &argv, "TLS: executing verify command"); + ret = openvpn_run_script (&argv, es, 0, "--tls-verify script"); + + if (verify_export_cert) + { + if (tmp_file) + platform_unlink(tmp_file); + } + + gc_free(&gc); + argv_reset (&argv); + + if (ret) + { + msg (D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s", + cert_depth, subject); + return SUCCESS; + } + + msg (D_HANDSHAKE, "VERIFY SCRIPT ERROR: depth=%d, %s", + cert_depth, subject); + return FAILURE; /* Reject connection */ +} + +/* + * check peer cert against CRL directory + */ +static result_t +verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert) +{ + result_t ret = FAILURE; + char fn[256]; + int fd = -1; + struct gc_arena gc = gc_new(); + + char *serial = x509_get_serial(cert, &gc); + + if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, OS_SPECIFIC_DIRSEP, serial)) + { + msg (D_HANDSHAKE, "VERIFY CRL: filename overflow"); + goto cleanup; + } + fd = platform_open (fn, O_RDONLY, 0); + if (fd >= 0) + { + msg (D_HANDSHAKE, "VERIFY CRL: certificate serial number %s is revoked", serial); + goto cleanup; + } + + ret = SUCCESS; + +cleanup: + + if (fd != -1) + close(fd); + gc_free(&gc); + return ret; +} + +result_t +verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth) +{ + result_t ret = FAILURE; + char *subject = NULL; + char common_name[TLS_USERNAME_LEN] = {0}; + const struct tls_options *opt; + struct gc_arena gc = gc_new(); + + opt = session->opt; + ASSERT (opt); + + session->verified = false; + + /* get the X509 name */ + subject = x509_get_subject(cert, &gc); + if (!subject) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 " + "subject string from certificate", cert_depth); + goto cleanup; + } + + /* enforce character class restrictions in X509 name */ + string_mod_remap_name (subject, X509_NAME_CHAR_CLASS); + string_replace_leading (subject, '-', '_'); + + /* extract the username (default is CN) */ + if (SUCCESS != x509_get_username (common_name, TLS_USERNAME_LEN, + opt->x509_username_field, cert)) + { + if (!cert_depth) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 " + "subject string ('%s') -- note that the username length is " + "limited to %d characters", + opt->x509_username_field, + subject, + TLS_USERNAME_LEN); + goto cleanup; + } + } + + /* enforce character class restrictions in common name */ + string_mod_remap_name (common_name, COMMON_NAME_CHAR_CLASS); + + /* warn if cert chain is too deep */ + if (cert_depth >= MAX_CERT_DEPTH) + { + msg (D_TLS_ERRORS, "TLS Error: Convoluted certificate chain detected with depth [%d] greater than %d", cert_depth, MAX_CERT_DEPTH); + goto cleanup; /* Reject connection */ + } + + /* 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)) + { + msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed"); + goto cleanup; + } + } + + /* save common name in session object */ + if (cert_depth == 0) + set_common_name (session, common_name); + + 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 + ); + + /* export current untrusted IP */ + setenv_untrusted (session); + + /* If this is the peer's own certificate, verify it */ + if (cert_depth == 0 && SUCCESS != verify_peer_cert(opt, cert, subject, common_name)) + goto cleanup; + + /* call --tls-verify plug-in(s), if registered */ + if (SUCCESS != verify_cert_call_plugin(opt->plugins, opt->es, cert_depth, cert, subject)) + goto cleanup; + + /* run --tls-verify script */ + if (opt->verify_command && SUCCESS != verify_cert_call_command(opt->verify_command, + opt->es, cert_depth, cert, subject, opt->verify_export_cert)) + goto cleanup; + + /* check peer cert against CRL */ + if (opt->crl_file) + { + if (opt->ssl_flags & SSLF_CRL_VERIFY_DIR) + { + 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; + } + } + + msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject); + session->verified = true; + ret = SUCCESS; + +cleanup: + + if (ret != SUCCESS) + { + tls_clear_error(); /* always? */ + session->verified = false; /* double sure? */ + } + gc_free(&gc); + + return ret; +} + +/* *************************************************************************** + * Functions for the management of deferred authentication when using + * user/password authentication. + *************************************************************************** */ + +#ifdef ENABLE_DEF_AUTH +/* key_state_test_auth_control_file return values, + NOTE: acf_merge indexing depends on these values */ +#define ACF_UNDEFINED 0 +#define ACF_SUCCEEDED 1 +#define ACF_DISABLED 2 +#define ACF_FAILED 3 +#endif + +#ifdef MANAGEMENT_DEF_AUTH +void +man_def_auth_set_client_reason (struct tls_multi *multi, const char *client_reason) +{ + if (multi->client_reason) + { + free (multi->client_reason); + multi->client_reason = NULL; + } + if (client_reason && strlen (client_reason)) + /* FIXME: Last alloc will never be freed */ + multi->client_reason = string_alloc (client_reason, NULL); +} + +static inline unsigned int +man_def_auth_test (const struct key_state *ks) +{ + if (management_enable_def_auth (management)) + return ks->mda_status; + else + return ACF_DISABLED; +} +#endif + +#ifdef PLUGIN_DEF_AUTH + +/* + * auth_control_file functions + */ + +void +key_state_rm_auth_control_file (struct key_state *ks) +{ + if (ks && ks->auth_control_file) + { + platform_unlink (ks->auth_control_file); + free (ks->auth_control_file); + ks->auth_control_file = NULL; + } +} + +static void +key_state_gen_auth_control_file (struct key_state *ks, const struct tls_options *opt) +{ + struct gc_arena gc = gc_new (); + const char *acf; + + key_state_rm_auth_control_file (ks); + acf = create_temp_file (opt->tmp_dir, "acf", &gc); + if (acf) { + ks->auth_control_file = string_alloc (acf, NULL); + setenv_str (opt->es, "auth_control_file", ks->auth_control_file); + } /* FIXME: Should have better error handling? */ + + gc_free (&gc); +} + +static unsigned int +key_state_test_auth_control_file (struct key_state *ks) +{ + if (ks && ks->auth_control_file) + { + unsigned int ret = ks->auth_control_status; + if (ret == ACF_UNDEFINED) + { + FILE *fp = fopen (ks->auth_control_file, "r"); + if (fp) + { + const int c = fgetc (fp); + if (c == '1') + ret = ACF_SUCCEEDED; + else if (c == '0') + ret = ACF_FAILED; + fclose (fp); + ks->auth_control_status = ret; + } + } + return ret; + } + return ACF_DISABLED; +} + +#endif + +/* + * Return current session authentication state. Return + * value is TLS_AUTHENTICATION_x. + */ + +int +tls_authentication_status (struct tls_multi *multi, const int latency) +{ + bool deferred = false; + bool success = false; + bool active = false; + +#ifdef ENABLE_DEF_AUTH + static const unsigned char acf_merge[] = + { + ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_UNDEFINED */ + ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_SUCCEEDED */ + ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_DISABLED */ + ACF_FAILED, /* s1=ACF_UNDEFINED s2=ACF_FAILED */ + ACF_UNDEFINED, /* s1=ACF_SUCCEEDED s2=ACF_UNDEFINED */ + ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_SUCCEEDED */ + ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_DISABLED */ + ACF_FAILED, /* s1=ACF_SUCCEEDED s2=ACF_FAILED */ + ACF_UNDEFINED, /* s1=ACF_DISABLED s2=ACF_UNDEFINED */ + ACF_SUCCEEDED, /* s1=ACF_DISABLED s2=ACF_SUCCEEDED */ + ACF_DISABLED, /* s1=ACF_DISABLED s2=ACF_DISABLED */ + ACF_FAILED, /* s1=ACF_DISABLED s2=ACF_FAILED */ + ACF_FAILED, /* s1=ACF_FAILED s2=ACF_UNDEFINED */ + ACF_FAILED, /* s1=ACF_FAILED s2=ACF_SUCCEEDED */ + ACF_FAILED, /* s1=ACF_FAILED s2=ACF_DISABLED */ + ACF_FAILED /* s1=ACF_FAILED s2=ACF_FAILED */ + }; +#endif /* ENABLE_DEF_AUTH */ + + if (multi) + { + int i; + +#ifdef ENABLE_DEF_AUTH + if (latency && multi->tas_last && multi->tas_last + latency >= now) + return TLS_AUTHENTICATION_UNDEFINED; + multi->tas_last = now; +#endif /* ENABLE_DEF_AUTH */ + + for (i = 0; i < KEY_SCAN_SIZE; ++i) + { + struct key_state *ks = multi->key_scan[i]; + if (DECRYPT_KEY_ENABLED (multi, ks)) + { + active = true; + if (ks->authenticated) + { +#ifdef ENABLE_DEF_AUTH + unsigned int s1 = ACF_DISABLED; + unsigned int s2 = ACF_DISABLED; +#ifdef PLUGIN_DEF_AUTH + s1 = key_state_test_auth_control_file (ks); +#endif /* PLUGIN_DEF_AUTH */ +#ifdef MANAGEMENT_DEF_AUTH + s2 = man_def_auth_test (ks); +#endif /* MANAGEMENT_DEF_AUTH */ + ASSERT (s1 < 4 && s2 < 4); + switch (acf_merge[(s1<<2) + s2]) + { + case ACF_SUCCEEDED: + case ACF_DISABLED: + success = true; + ks->auth_deferred = false; + break; + case ACF_UNDEFINED: + if (now < ks->auth_deferred_expire) + deferred = true; + break; + case ACF_FAILED: + ks->authenticated = false; + break; + default: + ASSERT (0); + } +#else /* !ENABLE_DEF_AUTH */ + success = true; +#endif /* ENABLE_DEF_AUTH */ + } + } + } + } + +#if 0 + dmsg (D_TLS_ERRORS, "TAS: a=%d s=%d d=%d", active, success, deferred); +#endif + + if (success) + return TLS_AUTHENTICATION_SUCCEEDED; + else if (!active || deferred) + return TLS_AUTHENTICATION_DEFERRED; + else + return TLS_AUTHENTICATION_FAILED; +} + +#ifdef MANAGEMENT_DEF_AUTH +/* + * For deferred auth, this is where the management interface calls (on server) + * to indicate auth failure/success. + */ +bool +tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason) +{ + bool ret = false; + if (multi) + { + int i; + man_def_auth_set_client_reason (multi, client_reason); + for (i = 0; i < KEY_SCAN_SIZE; ++i) + { + struct key_state *ks = multi->key_scan[i]; + if (ks->mda_key_id == mda_key_id) + { + ks->mda_status = auth ? ACF_SUCCEEDED : ACF_FAILED; + ret = true; + } + } + } + return ret; +} +#endif + + +/* **************************************************************************** + * Functions to verify username and password + * + * Authenticate a client using username/password. + * Runs on server. + * + * If you want to add new authentication methods, + * this is the place to start. + *************************************************************************** */ + +/* + * Verify the user name and password using a script + */ +static bool +verify_user_pass_script (struct tls_session *session, const struct user_pass *up) +{ + struct gc_arena gc = gc_new (); + struct argv argv = argv_new (); + const char *tmp_file = ""; + bool ret = false; + + /* Is username defined? */ + if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) + { + /* Set environmental variables prior to calling script */ + setenv_str (session->opt->es, "script_type", "user-pass-verify"); + + if (session->opt->auth_user_pass_verify_script_via_file) + { + struct status_output *so; + + tmp_file = create_temp_file (session->opt->tmp_dir, "up", &gc); + if( tmp_file ) { + so = status_open (tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE); + status_printf (so, "%s", up->username); + status_printf (so, "%s", up->password); + if (!status_close (so)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s", + tmp_file); + goto done; + } + } else { + msg (D_TLS_ERRORS, "TLS Auth Error: could not create write " + "username/password to temp file"); + } + } + else + { + setenv_str (session->opt->es, "username", up->username); + setenv_str (session->opt->es, "password", up->password); + } + + /* setenv incoming cert common name for script */ + setenv_str (session->opt->es, "common_name", session->common_name); + + /* setenv client real IP address */ + setenv_untrusted (session); + + /* format command line */ + argv_printf (&argv, "%sc %s", session->opt->auth_user_pass_verify_script, tmp_file); + + /* call command */ + ret = openvpn_run_script (&argv, session->opt->es, 0, + "--auth-user-pass-verify"); + + if (!session->opt->auth_user_pass_verify_script_via_file) + setenv_del (session->opt->es, "password"); + } + else + { + msg (D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username"); + } + + done: + if (tmp_file && strlen (tmp_file) > 0) + platform_unlink (tmp_file); + + argv_reset (&argv); + gc_free (&gc); + return ret; +} + +/* + * Verify the username and password using a plugin + */ +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; + struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + + /* Is username defined? */ + if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) + { + /* set username/password in private env space */ + setenv_str (session->opt->es, "username", (raw_username ? raw_username : up->username)); + setenv_str (session->opt->es, "password", up->password); + + /* setenv incoming cert common name for script */ + setenv_str (session->opt->es, "common_name", session->common_name); + + /* setenv client real IP address */ + setenv_untrusted (session); + +#ifdef PLUGIN_DEF_AUTH + /* generate filename for deferred auth control file */ + key_state_gen_auth_control_file (ks, session->opt); +#endif + + /* call command */ + retval = plugin_call (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); + +#ifdef PLUGIN_DEF_AUTH + /* purge auth control filename (and file itself) for non-deferred returns */ + if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) + key_state_rm_auth_control_file (ks); +#endif + + setenv_del (session->opt->es, "password"); + if (raw_username) + setenv_str (session->opt->es, "username", up->username); + } + else + { + msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username"); + } + + return retval; +} + + +#ifdef MANAGEMENT_DEF_AUTH +/* + * MANAGEMENT_DEF_AUTH internal ssl_verify.c status codes + */ +#define KMDA_ERROR 0 +#define KMDA_SUCCESS 1 +#define KMDA_UNDEF 2 +#define KMDA_DEF 3 + +static int +verify_user_pass_management (struct tls_session *session, const struct user_pass *up, const char *raw_username) +{ + int retval = KMDA_ERROR; + struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + + /* Is username defined? */ + if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen (up->username)) + { + /* set username/password in private env space */ + setenv_str (session->opt->es, "username", (raw_username ? raw_username : up->username)); + setenv_str (session->opt->es, "password", up->password); + + /* setenv incoming cert common name for script */ + setenv_str (session->opt->es, "common_name", session->common_name); + + /* setenv client real IP address */ + setenv_untrusted (session); + + if (management) + management_notify_client_needing_auth (management, ks->mda_key_id, session->opt->mda_context, session->opt->es); + + setenv_del (session->opt->es, "password"); + if (raw_username) + setenv_str (session->opt->es, "username", up->username); + + retval = KMDA_SUCCESS; + } + else + { + msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_management): peer provided a blank username"); + } + + return retval; +} +#endif + +/* + * Main username/password verification entry point + */ +void +verify_user_pass(struct user_pass *up, struct tls_multi *multi, + struct tls_session *session) +{ + int s1 = OPENVPN_PLUGIN_FUNC_SUCCESS; + bool s2 = true; + struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + + struct gc_arena gc = gc_new (); + char *raw_username = NULL; + +#ifdef MANAGEMENT_DEF_AUTH + int man_def_auth = KMDA_UNDEF; + + if (management_enable_def_auth (management)) + man_def_auth = KMDA_DEF; +#endif + + /* + * Preserve the raw username before string_mod remapping, for plugins + * and management clients when in --compat-names mode + */ + if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES)) + { + ALLOC_ARRAY_CLEAR_GC (raw_username, char, USER_PASS_LEN, &gc); + strcpy (raw_username, up->username); + string_mod (raw_username, CC_PRINT, CC_CRLF, '_'); + } + + /* enforce character class restrictions in username/password */ + string_mod_remap_name (up->username, COMMON_NAME_CHAR_CLASS); + string_mod (up->password, CC_PRINT, CC_CRLF, '_'); + + /* call plugin(s) and/or script */ +#ifdef MANAGEMENT_DEF_AUTH + if (man_def_auth == KMDA_DEF) + man_def_auth = verify_user_pass_management (session, up, raw_username); +#endif + if (plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)) + s1 = verify_user_pass_plugin (session, up, raw_username); + if (session->opt->auth_user_pass_verify_script) + s2 = verify_user_pass_script (session, up); + + /* check sizing of username if it will become our common name */ + if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_USERNAME_LEN) + { + msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_USERNAME_LEN); + s1 = OPENVPN_PLUGIN_FUNC_ERROR; + } + + /* auth succeeded? */ + if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS +#ifdef PLUGIN_DEF_AUTH + || s1 == OPENVPN_PLUGIN_FUNC_DEFERRED +#endif + ) && s2 +#ifdef MANAGEMENT_DEF_AUTH + && man_def_auth != KMDA_ERROR +#endif + && tls_lock_username (multi, up->username)) + { + ks->authenticated = true; +#ifdef PLUGIN_DEF_AUTH + if (s1 == OPENVPN_PLUGIN_FUNC_DEFERRED) + ks->auth_deferred = true; +#endif +#ifdef MANAGEMENT_DEF_AUTH + if (man_def_auth != KMDA_UNDEF) + ks->auth_deferred = true; +#endif + if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)) + set_common_name (session, up->username); +#ifdef ENABLE_DEF_AUTH + msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", + ks->auth_deferred ? "deferred" : "succeeded", + up->username, + (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : ""); +#else + msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", + "succeeded", + up->username, + (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : ""); +#endif + } + else + { + msg (D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer"); + } + + gc_free (&gc); +} + +void +verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session) +{ + struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + + /* While it shouldn't really happen, don't allow the common name to be NULL */ + if (!session->common_name) + set_common_name (session, ""); + + /* Don't allow the CN to change once it's been locked */ + if (ks->authenticated && multi->locked_cn) + { + const char *cn = session->common_name; + if (cn && strcmp (cn, multi->locked_cn)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled", + multi->locked_cn, + cn); + + /* change the common name back to its original value and disable the tunnel */ + set_common_name (session, multi->locked_cn); + tls_deauthenticate (multi); + } + } + + /* Don't allow the cert hashes to change once they have been locked */ + if (ks->authenticated && multi->locked_cert_hash_set) + { + const struct cert_hash_set *chs = session->cert_hash_set; + if (chs && !cert_hash_compare (chs, multi->locked_cert_hash_set)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth", + session->common_name); + + /* disable the tunnel */ + tls_deauthenticate (multi); + } + } + + /* verify --client-config-dir based authentication */ + if (ks->authenticated && session->opt->client_config_dir_exclusive) + { + struct gc_arena gc = gc_new (); + + const char *cn = session->common_name; + const char *path = gen_path (session->opt->client_config_dir_exclusive, cn, &gc); + if (!cn || !strcmp (cn, CCD_DEFAULT) || !test_file (path)) + { + ks->authenticated = false; + msg (D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'", + session->common_name, + path ? path : "UNDEF"); + } + + gc_free (&gc); + } +} +#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) */ diff --git a/src/openvpn/ssl_verify.h b/src/openvpn/ssl_verify.h new file mode 100644 index 0000000..1d20152 --- /dev/null +++ b/src/openvpn/ssl_verify.h @@ -0,0 +1,252 @@ +/* + * 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 + */ + +#ifndef SSL_VERIFY_H_ +#define SSL_VERIFY_H_ + +#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" +#endif + +#include "ssl_verify_backend.h" + +/* + * Keep track of certificate hashes at various depths + */ + +/** Maximum certificate depth we will allow */ +#define MAX_CERT_DEPTH 16 + +/** Structure containing the hash for a single certificate */ +struct cert_hash { + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; /**< The SHA1 hash for a certificate */ +}; + +/** Structure containing the hashes for a full certificate chain */ +struct cert_hash_set { + struct cert_hash *ch[MAX_CERT_DEPTH]; /**< Array of certificate hashes */ +}; + + +#define TLS_AUTHENTICATION_SUCCEEDED 0 +#define TLS_AUTHENTICATION_FAILED 1 +#define TLS_AUTHENTICATION_DEFERRED 2 +#define TLS_AUTHENTICATION_UNDEFINED 3 + +/* + * Return current session authentication state. Return + * value is TLS_AUTHENTICATION_x. + * + * TODO: document this function + */ +int tls_authentication_status (struct tls_multi *multi, const int latency); + +/** Check whether the \a ks \c key_state is ready to receive data channel + * packets. + * @ingroup data_crypto + * + * If true, it is safe to assume that this session has been authenticated + * by TLS. + * + * @note This macro only works if S_SENT_KEY + 1 == S_GOT_KEY. */ +#define DECRYPT_KEY_ENABLED(multi, ks) ((ks)->state >= (S_GOT_KEY - (multi)->opt.server)) + +/** + * Remove the given key state's auth control file, if it exists. + * + * @param ks The key state the remove the file for + */ +void key_state_rm_auth_control_file (struct key_state *ks); + +/** + * Frees the given set of certificate hashes. + * + * @param chs The certificate hash set to free. + */ +void cert_hash_free (struct cert_hash_set *chs); + +/** + * Locks the certificate hash set used in the given tunnel + * + * @param multi The tunnel to lock + */ +void tls_lock_cert_hash_set (struct tls_multi *multi); + +/** + * Locks the common name field for the given tunnel + * + * @param multi The tunnel to lock + */ +void tls_lock_common_name (struct tls_multi *multi); + +/** + * Returns the common name field for the given tunnel + * + * @param multi The tunnel to return the common name for + * @param null Whether null may be returned. If not, "UNDEF" will be returned. + */ +const char *tls_common_name (const struct tls_multi* multi, const bool null); + +/** + * Returns the username field for the given tunnel + * + * @param multi The tunnel to return the username for + * @param null Whether null may be returned. If not, "UNDEF" will be returned. + */ +const char *tls_username (const struct tls_multi *multi, const bool null); + +#ifdef ENABLE_PF + +/** + * Retrieve the given tunnel's common name and its hash value. + * + * @param multi The tunnel to use + * @param cn Common name's string + * @param cn_hash Common name's hash value + * + * @return true if the common name was set, false otherwise. + */ +static inline bool +tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t *cn_hash) +{ + if (multi) + { + const struct tls_session *s = &multi->session[TM_ACTIVE]; + if (s->common_name && s->common_name[0] != '\0') + { + *cn = s->common_name; + *cn_hash = s->common_name_hashval; + return true; + } + } + return false; +} + +#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. + * + * If authentication succeeds, the appropriate state is filled into the + * session's primary key state's authenticated field. Authentication may also + * be deferred, in which case the key state's auth_deferred field is filled in. + * + * @param up The username and password to verify. + * @param multi The TLS multi structure to verify usernames against. + * @param session The current TLS session + * + */ +void verify_user_pass(struct user_pass *up, struct tls_multi *multi, + struct tls_session *session); + +/** + * Perform final authentication checks, including locking of the cn, the allowed + * certificate hashes, and whether a client config entry exists in the + * client config directory. + * + * @param multi The TLS multi structure to verify locked structures. + * @param session The current TLS session + * + */ +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; + const char *name; +# define XT_FULL_CHAIN (1<<0) + unsigned int flags; + 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 + */ +/** Do not perform Netscape certificate type verification */ +#define NS_CERT_CHECK_NONE (0) +/** Do not perform Netscape certificate type verification */ +#define NS_CERT_CHECK_SERVER (1<<0) +/** Do not perform Netscape certificate type verification */ +#define NS_CERT_CHECK_CLIENT (1<<1) + +/* + * TODO: document + */ +#ifdef MANAGEMENT_DEF_AUTH +bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason); +void man_def_auth_set_client_reason (struct tls_multi *multi, const char *client_reason); +#endif + +static inline const char * +tls_client_reason (struct tls_multi *multi) +{ +#ifdef ENABLE_DEF_AUTH + return multi->client_reason; +#else + return NULL; +#endif +} + +#endif /* SSL_VERIFY_H_ */ + diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h new file mode 100644 index 0000000..1658cc0 --- /dev/null +++ b/src/openvpn/ssl_verify_backend.h @@ -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) 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 library-specific backend interface + */ + +#ifndef SSL_VERIFY_BACKEND_H_ +#define SSL_VERIFY_BACKEND_H_ + +/** + * Result of verification function + */ +typedef enum { SUCCESS=0, FAILURE=1 } result_t; + +/* + * Backend support functions. + * + * The following functions are needed by the backend, but defined in the main + * file. + */ + +/* + * Verify certificate for the given session. Performs OpenVPN-specific + * verification. + * + * This function must be called for every certificate in the certificate + * chain during the certificate verification stage of the handshake. + * + * @param session TLS Session associated with this tunnel + * @param cert Certificate to process + * @param cert_depth Depth of the current certificate + * + * @return \c SUCCESS if verification was successful, \c FAILURE on failure. + */ +result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth); + +/* + * Remember the given certificate hash, allowing the certificate chain to be + * locked between sessions. + * + * Must be called for every certificate in the verification chain, whether it + * is valid or not. + * + * @param session TLS Session associated with this tunnel + * @param cert_depth Depth of the current certificate + * @param sha1_hash Hash of the current certificate + */ +void cert_hash_remember (struct tls_session *session, const int cert_depth, + const unsigned char *sha1_hash); + +/* + * Library-specific functions. + * + * The following functions must be implemented on a library-specific basis. + */ + +/* + * Retrieve certificate's subject name. + * + * @param cert Certificate to retrieve the subject from. + * @param gc Garbage collection arena to use when allocating string. + * + * @return a string containing the subject + */ +char *x509_get_subject (openvpn_x509_cert_t *cert, struct gc_arena *gc); + +/* Retrieve the certificate's SHA1 hash. + * + * @param cert Certificate to retrieve the hash from. + * @param gc Garbage collection arena to use when allocating string. + * + * @return a string containing the SHA1 hash of the certificate + */ +unsigned char *x509_get_sha1_hash (openvpn_x509_cert_t *cert, struct gc_arena *gc); + +/* + * Retrieve the certificate's username from the specified field. + * + * If the field is prepended with ext: and ENABLE_X509ALTUSERNAME is enabled, + * it will be loaded from an X.509 extension + * + * @param cn Buffer to return the common name in. + * @param cn_len Length of the cn buffer. + * @param x509_username_field Name of the field to load from + * @param cert Certificate to retrieve the common name from. + * + * @return \c FAILURE, \c or SUCCESS + */ +result_t x509_get_username (char *common_name, int cn_len, + char * x509_username_field, openvpn_x509_cert_t *peer_cert); + +/* + * Return the certificate's serial number. + * + * The serial number is returned as a string, since it might be a bignum. + * + * @param cert Certificate to retrieve the serial number from. + * @param gc Garbage collection arena to use when allocating string. + * + * @return The certificate's serial number. + */ +char *x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc); + +/* + * Save X509 fields to environment, using the naming convention: + * + * X509_{cert_depth}_{name}={value} + * + * @param es Environment set to save variables in + * @param cert_depth Depth of the certificate + * @param cert Certificate to set the environment for + */ +void x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert); + +#ifdef ENABLE_X509_TRACK + +/* + * Start tracking the given attribute. + * + * The tracked attributes are stored in ll_head. + * + * @param ll_head The x509_track to store tracked atttributes in + * @param name Name of the attribute to track + * @param msglevel Message level for errors + * @param gc Garbage collection arena for temp data + * + */ +void x509_track_add (const struct x509_track **ll_head, const char *name, + int msglevel, struct gc_arena *gc); + +/* + * Save X509 fields to environment, using the naming convention: + * + * X509_{cert_depth}_{name}={value} + * + * This function differs from setenv_x509 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. + * + * @param xt + * @param es Environment set to save variables in + * @param cert_depth Depth of the certificate + * @param cert Certificate to set the environment for + */ +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. + * + * @param cert Certificate to check. + * @param usage One of \c NS_CERT_CHECK_CLIENT, \c NS_CERT_CHECK_SERVER, + * or \c NS_CERT_CHECK_NONE. + * + * @return \c SUCCESS if NS_CERT_CHECK_NONE or if the certificate has + * the expected bit set. \c FAILURE if the certificate does + * not have NS cert type verification or the wrong bit set. + */ +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. + * + * @param cert Certificate to check. + * @param expected_ku Array of valid key usage values + * @param expected_len Length of the key usage array + * + * @return \c SUCCESS if one of the key usage values matches, \c FAILURE + * if key usage is not enabled, or the values do not match. + */ +result_t x509_verify_cert_ku (openvpn_x509_cert_t *x509, const unsigned * const expected_ku, + int expected_len); + +/* + * Verify X.509 extended key usage extension field. + * + * @param cert Certificate to check. + * @param expected_oid String representation of the expected Object ID. May be + * either the string representation of the numeric OID + * (e.g. \c "1.2.3.4", or the descriptive string matching + * the OID. + * + * @return \c SUCCESS if one of the expected OID matches one of the + * extended key usage fields, \c FAILURE if extended key + * usage is not enabled, or the values do not match. + */ +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 + * + * @param cert Certificate to store + * @param tmp_dir Temporary directory to store the directory + * @param gc gc_arena to store temporary objects in + * + * + */ +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. + */ +result_t x509_verify_crl(const char *crl_file, openvpn_x509_cert_t *cert, + const char *subject); + +#endif /* SSL_VERIFY_BACKEND_H_ */ diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c new file mode 100644 index 0000000..658f5f3 --- /dev/null +++ b/src/openvpn/ssl_verify_openssl.c @@ -0,0 +1,622 @@ +/* + * 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 OpenSSL implementation + */ + +#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_OPENSSL) + +#include "ssl_verify.h" +#include "ssl_verify_backend.h" +#include "ssl_openssl.h" +#include <openssl/x509v3.h> +#include <openssl/err.h> + +int +verify_callback (int preverify_ok, X509_STORE_CTX * ctx) +{ + int ret = 0; + struct tls_session *session; + SSL *ssl; + struct gc_arena gc = gc_new(); + + /* get the tls_session pointer */ + ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + ASSERT (ssl); + 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)); + + /* did peer present cert which was signed by our root cert? */ + if (!preverify_ok) + { + /* get the X509 name */ + char *subject = x509_get_subject(ctx->current_cert, &gc); + + if (subject) + { + /* 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; + goto cleanup; + } + + if (SUCCESS != verify_cert(session, ctx->current_cert, ctx->error_depth)) + goto cleanup; + + ret = 1; + +cleanup: + gc_free(&gc); + + return ret; +} + +#ifdef ENABLE_X509ALTUSERNAME +static +bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) +{ + bool retval = false; + X509_EXTENSION *pExt; + char *buf = 0; + int length = 0; + GENERAL_NAMES *extensions; + int nid = OBJ_txt2nid(fieldname); + + extensions = (GENERAL_NAMES *)X509_get_ext_d2i(cert, nid, NULL, NULL); + if ( extensions ) + { + int numalts; + int i; + /* get amount of alternatives, + * RFC2459 claims there MUST be at least + * one, but we don't depend on it... + */ + + numalts = sk_GENERAL_NAME_num(extensions); + + /* loop through all alternatives */ + for (i=0; i<numalts; i++) + { + /* get a handle to alternative name number i */ + const GENERAL_NAME *name = sk_GENERAL_NAME_value (extensions, i ); + + switch (name->type) + { + case GEN_EMAIL: + ASN1_STRING_to_UTF8((unsigned char**)&buf, name->d.ia5); + if ( strlen (buf) != name->d.ia5->length ) + { + msg (D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero"); + OPENSSL_free (buf); + } else { + strncpynt(out, buf, size); + OPENSSL_free(buf); + retval = true; + } + break; + default: + msg (D_TLS_ERRORS, "ASN1 ERROR: can not handle field type %i", + name->type); + break; + } + } + sk_GENERAL_NAME_free (extensions); + } + return retval; +} +#endif /* ENABLE_X509ALTUSERNAME */ + +/* + * Extract a field from an X509 subject name. + * + * Example: + * + * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net + * + * The common name is 'Test-CA' + * + * Return true on success, false on error (insufficient buffer size in 'out' + * to contain result is grounds for error). + */ +static result_t +extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, + int size) +{ + int lastpos = -1; + 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); + + ASSERT (size > 0); + *out = '\0'; + do { + lastpos = tmp; + tmp = X509_NAME_get_index_by_NID(x509, nid, lastpos); + } while (tmp > -1); + + /* Nothing found */ + if (lastpos == -1) + return FAILURE; + + x509ne = X509_NAME_get_entry(x509, lastpos); + if (!x509ne) + return FAILURE; + + asn1 = X509_NAME_ENTRY_get_data(x509ne); + if (!asn1) + return FAILURE; + tmp = ASN1_STRING_to_UTF8(&buf, asn1); + if (tmp <= 0) + return FAILURE; + + strncpynt(out, (char *)buf, size); + + { + const result_t ret = (strlen ((char *)buf) < size) ? SUCCESS: FAILURE; + OPENSSL_free (buf); + return ret; + } +} + +result_t +x509_get_username (char *common_name, int cn_len, + char * x509_username_field, X509 *peer_cert) +{ +#ifdef ENABLE_X509ALTUSERNAME + if (strncmp("ext:",x509_username_field,4) == 0) + { + if (!extract_x509_extension (peer_cert, x509_username_field+4, common_name, cn_len)) + return FAILURE; + } else +#endif + if (FAILURE == extract_x509_field_ssl (X509_get_subject_name (peer_cert), + x509_username_field, common_name, cn_len)) + return FAILURE; + + return SUCCESS; +} + +char * +x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) +{ + ASN1_INTEGER *asn1_i; + BIGNUM *bignum; + char *openssl_serial, *serial; + + asn1_i = X509_get_serialNumber(cert); + bignum = ASN1_INTEGER_to_BN(asn1_i, NULL); + openssl_serial = BN_bn2dec(bignum); + + serial = string_alloc(openssl_serial, gc); + + BN_free(bignum); + OPENSSL_free(openssl_serial); + + return serial; +} + +unsigned char * +x509_get_sha1_hash (X509 *cert, struct gc_arena *gc) +{ + char *hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc); + memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH); + return hash; +} + +char * +x509_get_subject (X509 *cert, struct gc_arena *gc) +{ + BIO *subject_bio = NULL; + BUF_MEM *subject_mem; + char *subject = NULL; + int maxlen = 0; + + /* + * Generate the subject string in OpenSSL proprietary format, + * when in --compat-names mode + */ + if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES)) + { + subject = gc_malloc (256, false, gc); + X509_NAME_oneline (X509_get_subject_name (cert), subject, 256); + subject[255] = '\0'; + return subject; + } + + subject_bio = BIO_new (BIO_s_mem ()); + if (subject_bio == NULL) + goto err; + + X509_NAME_print_ex (subject_bio, X509_get_subject_name (cert), + 0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | + ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL); + + if (BIO_eof (subject_bio)) + goto err; + + BIO_get_mem_ptr (subject_bio, &subject_mem); + + maxlen = subject_mem->length + 1; + subject = gc_malloc (maxlen, false, gc); + + memcpy (subject, subject_mem->data, maxlen); + subject[maxlen - 1] = '\0'; + +err: + if (subject_bio) + BIO_free (subject_bio); + + return subject; +} + + +#ifdef ENABLE_X509_TRACK + +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->nid = OBJ_txt2nid(name); + if (xt->nid != NID_undef) + { + xt->next = *ll_head; + *ll_head = xt; + } + else + msg(msglevel, "x509_track: no such attribute '%s'", name); +} + +/* worker method for setenv_x509_track */ +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); +} + +void +x509_setenv_track (const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509) +{ + 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 + { + 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; + } +} +#endif + +/* + * 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 *peer_cert) +{ + int i, n; + int fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME_ENTRY *ent; + const char *objbuf; + unsigned char *buf; + char *name_expand; + size_t name_expand_size; + X509_NAME *x509 = X509_get_subject_name (peer_cert); + + n = X509_NAME_entry_count (x509); + for (i = 0; i < n; ++i) + { + ent = X509_NAME_get_entry (x509, i); + if (!ent) + continue; + fn = X509_NAME_ENTRY_get_object (ent); + if (!fn) + continue; + val = X509_NAME_ENTRY_get_data (ent); + if (!val) + continue; + fn_nid = OBJ_obj2nid (fn); + if (fn_nid == NID_undef) + continue; + objbuf = OBJ_nid2sn (fn_nid); + if (!objbuf) + continue; + 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) + continue; + name_expand_size = 64 + strlen (objbuf); + name_expand = (char *) malloc (name_expand_size); + check_malloc_return (name_expand); + openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", cert_depth, + objbuf); + string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); + string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_'); + setenv_str (es, name_expand, (char*)buf); + free (name_expand); + OPENSSL_free (buf); + } +} + +result_t +x509_verify_ns_cert_type(const openvpn_x509_cert_t *peer_cert, const int usage) +{ + if (usage == NS_CERT_CHECK_NONE) + return SUCCESS; + if (usage == NS_CERT_CHECK_CLIENT) + return ((peer_cert->ex_flags & EXFLAG_NSCERT) + && (peer_cert->ex_nscert & NS_SSL_CLIENT)) ? SUCCESS: FAILURE; + if (usage == NS_CERT_CHECK_SERVER) + return ((peer_cert->ex_flags & EXFLAG_NSCERT) + && (peer_cert->ex_nscert & NS_SSL_SERVER)) ? SUCCESS: FAILURE; + + return FAILURE; +} + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + +result_t +x509_verify_cert_ku (X509 *x509, const unsigned * const expected_ku, + int expected_len) +{ + ASN1_BIT_STRING *ku = NULL; + result_t fFound = FAILURE; + + if ((ku = (ASN1_BIT_STRING *) X509_get_ext_d2i (x509, NID_key_usage, NULL, + NULL)) == NULL) + { + msg (D_HANDSHAKE, "Certificate does not have key usage extension"); + } + else + { + unsigned nku = 0; + int i; + for (i = 0; i < 8; i++) + { + if (ASN1_BIT_STRING_get_bit (ku, i)) + nku |= 1 << (7 - i); + } + + /* + * Fixup if no LSB bits + */ + if ((nku & 0xff) == 0) + { + nku >>= 8; + } + + msg (D_HANDSHAKE, "Validating certificate key usage"); + for (i = 0; fFound != SUCCESS && 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; + } + } + } + + if (ku != NULL) + ASN1_BIT_STRING_free (ku); + + return fFound; +} + +result_t +x509_verify_cert_eku (X509 *x509, const char * const expected_oid) +{ + EXTENDED_KEY_USAGE *eku = NULL; + result_t fFound = FAILURE; + + if ((eku = (EXTENDED_KEY_USAGE *) X509_get_ext_d2i (x509, NID_ext_key_usage, + NULL, NULL)) == NULL) + { + msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); + } + else + { + int i; + + msg (D_HANDSHAKE, "Validating certificate extended key usage"); + for (i = 0; SUCCESS != fFound && i < sk_ASN1_OBJECT_num (eku); i++) + { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value (eku, i); + char szOid[1024]; + + if (SUCCESS != fFound && OBJ_obj2txt (szOid, sizeof(szOid), oid, 0) != -1) + { + msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", + szOid, expected_oid); + if (!strcmp (expected_oid, szOid)) + fFound = SUCCESS; + } + if (SUCCESS != fFound && OBJ_obj2txt (szOid, sizeof(szOid), oid, 1) != -1) + { + msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", + szOid, expected_oid); + if (!strcmp (expected_oid, szOid)) + fFound = SUCCESS; + } + } + } + + if (eku != NULL) + sk_ASN1_OBJECT_pop_free (eku, ASN1_OBJECT_free); + + return fFound; +} + +result_t +x509_write_pem(FILE *peercert_file, X509 *peercert) +{ + if (PEM_write_X509(peercert_file, peercert) < 0) + { + msg (M_ERR, "Failed to write peer certificate in PEM format"); + return FAILURE; + } + 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) +{ + X509_CRL *crl=NULL; + X509_REVOKED *revoked; + BIO *in=NULL; + int n,i; + result_t retval = FAILURE; + + in = BIO_new_file (crl_file, "r"); + + if (in == NULL) { + msg (M_ERR, "CRL: cannot read: %s", crl_file); + goto end; + } + crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); + if (crl == NULL) { + msg (M_ERR, "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) { + msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED",subject); + goto end; + } + } + + retval = SUCCESS; + msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); + +end: + BIO_free(in); + if (crl) + X509_CRL_free (crl); + + return retval; +} + +#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/src/openvpn/ssl_verify_openssl.h b/src/openvpn/ssl_verify_openssl.h new file mode 100644 index 0000000..5a7e0a1 --- /dev/null +++ b/src/openvpn/ssl_verify_openssl.h @@ -0,0 +1,76 @@ +/* + * 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 OpenSSL backend + */ + + +#ifndef SSL_VERIFY_OPENSSL_H_ +#define SSL_VERIFY_OPENSSL_H_ + +#include <openssl/x509.h> + +#ifndef __OPENVPN_X509_CERT_T_DECLARED +#define __OPENVPN_X509_CERT_T_DECLARED +typedef X509 openvpn_x509_cert_t; +#endif + +/** @name Function for authenticating a new connection from a remote OpenVPN peer + * @{ */ + +/** + * Verify that the remote OpenVPN peer's certificate allows setting up a + * VPN tunnel. + * @ingroup control_tls + * + * This callback function is called every time a new TLS session is being + * setup to 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 OpenSSL library's \c SSL_CTX_set_verify() function with \c + * verify_callback() as its callback argument. + * + * It checks preverify_ok, and registers the certificate hash. If these steps + * succeed, it calls the \c verify_cert() function, which performs + * OpenVPN-specific verification. + * + * @param preverify_ok - Whether the remote OpenVPN peer's certificate + * past verification. A value of 1 means it + * verified successfully, 0 means it failed. + * @param ctx - The complete context used by the OpenSSL library + * to verify the certificate chain. + * + * @return The return value indicates whether the supplied certificate is + * allowed to set up a VPN tunnel. The following values can be + * returned: + * - \c 0: failure, this certificate is not allowed to connect. + * - \c 1: success, this certificate is allowed to connect. + */ +int verify_callback (int preverify_ok, X509_STORE_CTX * ctx); + +/** @} name Function for authenticating a new connection from a remote OpenVPN peer */ + +#endif /* SSL_VERIFY_OPENSSL_H_ */ diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c new file mode 100644 index 0000000..a32db8d --- /dev/null +++ b/src/openvpn/ssl_verify_polarssl.c @@ -0,0 +1,409 @@ +/* + * 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/sha1.h> + +#define MAX_SUBJECT_LENGTH 256 + +int +verify_callback (void *session_obj, x509_cert *cert, int cert_depth, + int preverify_ok) +{ + struct tls_session *session = (struct tls_session *) session_obj; + struct gc_arena gc = gc_new(); + int ret = 1; + + 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 (!preverify_ok) + { + char *subject = x509_get_subject(cert, &gc); + + if (subject) + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, %s", cert_depth, subject); + else + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 " + "subject string from certificate", cert_depth); + + goto cleanup; + } + + if (SUCCESS != verify_cert(session, cert, cert_depth)) + goto cleanup; + + ret = 0; + +cleanup: + gc_free(&gc); + + /* + * PolarSSL expects 1 on failure, 0 on success + */ + return ret; +} + +#ifdef ENABLE_X509ALTUSERNAME +# warning "X509 alt user name not yet supported for PolarSSL" +#endif + +result_t +x509_get_username (char *cn, int cn_len, + char *x509_username_field, x509_cert *cert) +{ + x509_name *name; + + ASSERT( cn != NULL ); + + name = &cert->subject; + + /* Find common name */ + while( name != NULL ) + { + if( memcmp( name->oid.p, OID_CN, OID_SIZE(OID_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 * +x509_get_serial (x509_cert *cert, struct gc_arena *gc) +{ + int ret = 0; + int i = 0; + char *buf = NULL; + size_t len = cert->serial.len * 3 + 1; + + buf = gc_malloc(len, true, gc); + + if(x509parse_serial_gets(buf, len-1, &cert->serial) < 0) + buf = NULL; + + return buf; +} + +unsigned char * +x509_get_sha1_hash (x509_cert *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_cert *cert, struct gc_arena *gc) +{ + char tmp_subject[MAX_SUBJECT_LENGTH] = {0}; + char *subject = NULL; + + int ret = 0; + + ret = x509parse_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]; + + if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 ) + { + switch( name->oid.p[2] ) + { + case X520_COMMON_NAME: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN", + cert_depth); break; + + case X520_COUNTRY: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C", + cert_depth); break; + + case X520_LOCALITY: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L", + cert_depth); break; + + case X520_STATE: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST", + cert_depth); break; + + case X520_ORGANIZATION: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O", + cert_depth); break; + + case X520_ORG_UNIT: + openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU", + cert_depth); break; + + default: + openvpn_snprintf (name_expand, sizeof(name_expand), + "X509_%d_0x%02X", cert_depth, name->oid.p[2]); + break; + } + } + else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 ) + { + switch( name->oid.p[8] ) + { + case PKCS9_EMAIL: + openvpn_snprintf (name_expand, sizeof(name_expand), + "X509_%d_emailAddress", cert_depth); break; + + default: + openvpn_snprintf (name_expand, sizeof(name_expand), + "X509_%d_0x%02X", cert_depth, name->oid.p[8]); + break; + } + } + 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_cert *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_cert *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_cert *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; + + oid_str = x509_oid_get_description(oid); + if (oid_str != NULL) + { + 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 == x509_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_cert *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_cert *cert, const char *subject) +{ + result_t retval = FAILURE; + x509_crl crl = {0}; + + if (x509parse_crlfile(&crl, crl_file) != 0) + { + msg (M_ERR, "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 (0 != x509parse_revoked(cert, &crl)) + { + msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject); + goto end; + } + + retval = SUCCESS; + msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); + +end: + x509_crl_free(&crl); + return retval; +} + +#endif /* #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/src/openvpn/ssl_verify_polarssl.h b/src/openvpn/ssl_verify_polarssl.h new file mode 100644 index 0000000..fceee66 --- /dev/null +++ b/src/openvpn/ssl_verify_polarssl.h @@ -0,0 +1,82 @@ +/* + * 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 + */ + +#ifndef SSL_VERIFY_POLARSSL_H_ +#define SSL_VERIFY_POLARSSL_H_ + +#include "syshead.h" +#include "misc.h" +#include "manage.h" +#include <polarssl/x509.h> + +#ifndef __OPENVPN_X509_CERT_T_DECLARED +#define __OPENVPN_X509_CERT_T_DECLARED +typedef x509_cert openvpn_x509_cert_t; +#endif + +/** @name Function for authenticating a new connection from a remote OpenVPN peer + * @{ */ + +/** + * Verify that the remote OpenVPN peer's certificate allows setting up a + * VPN tunnel. + * @ingroup control_tls + * + * This callback function is called when a new TLS session is being setup to + * 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 + * verify_callback() as its callback argument. + * + * It checks preverify_ok, and registers the certificate hash. If these steps + * succeed, it calls the \c verify_cert() function, which performs + * OpenVPN-specific verification. + * + * @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_depth - The depth of the current certificate in the chain, with + * 0 being the actual certificate. + * @param preverify_ok - Whether the remote OpenVPN peer's certificate + * past verification. A value of 1 means it + * verified successfully, 0 means it failed. + * + * @return The return value indicates whether the supplied certificate is + * allowed to set up a VPN tunnel. The following values can be + * returned: + * - \c 0: failure, this certificate is not allowed to connect. + * - \c 1: success, this certificate is allowed to connect. + */ +int verify_callback (void *session_obj, x509_cert *cert, int cert_depth, + int preverify_ok); + +/** @} name Function for authenticating a new connection from a remote OpenVPN peer */ + +#endif /* SSL_VERIFY_POLARSSL_H_ */ diff --git a/status.c b/src/openvpn/status.c index 4bbea28..5f9ab9e 100644 --- a/status.c +++ b/src/openvpn/status.c @@ -22,10 +22,17 @@ * 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" #include "status.h" #include "perf.h" +#include "misc.h" #include "memdbg.h" @@ -67,45 +74,27 @@ status_open (const char *filename, buf_reset (&so->read_buf); event_timeout_clear (&so->et); if (filename) - { - switch (so->flags) - { -#ifdef _MSC_VER + { + switch (so->flags) + { case STATUS_OUTPUT_WRITE: - so->fd = open (filename, - O_CREAT | O_TRUNC | O_WRONLY, - _S_IREAD | _S_IWRITE); + so->fd = platform_open (filename, + O_CREAT | O_TRUNC | O_WRONLY, + S_IRUSR | S_IWUSR); break; case STATUS_OUTPUT_READ: - so->fd = open (filename, - O_RDONLY, - _S_IREAD | _S_IWRITE); + so->fd = platform_open (filename, + O_RDONLY, + S_IRUSR | S_IWUSR); break; case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: - so->fd = open (filename, - O_CREAT | O_RDWR, - _S_IREAD | _S_IWRITE); + so->fd = platform_open (filename, + O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR); break; -#else - case STATUS_OUTPUT_WRITE: - so->fd = open (filename, - O_CREAT | O_TRUNC | O_WRONLY, - S_IRUSR | S_IWUSR); - break; - case STATUS_OUTPUT_READ: - so->fd = open (filename, - O_RDONLY, - S_IRUSR | S_IWUSR); - break; - case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: - so->fd = open (filename, - O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR); - break; -#endif - default: - ASSERT (0); - } + default: + ASSERT (0); + } if (so->fd >= 0) { so->filename = string_alloc (filename, NULL); diff --git a/status.h b/src/openvpn/status.h index 0bdad4e..af16fd2 100644 --- a/status.h +++ b/src/openvpn/status.h @@ -77,7 +77,11 @@ void status_flush (struct status_output *so); bool status_close (struct status_output *so); void status_printf (struct status_output *so, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 2, 3))) +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format (gnu_printf, 2, 3))) +#else + __attribute__ ((format (__printf__, 2, 3))) +#endif #endif ; diff --git a/syshead.h b/src/openvpn/syshead.h index b81ce59..c81f08a 100644 --- a/syshead.h +++ b/src/openvpn/syshead.h @@ -25,12 +25,8 @@ #ifndef SYSHEAD_H #define SYSHEAD_H -/* - * Only include if not during configure - */ -#ifndef PACKAGE_NAME -#include "config.h" -#endif +#include "compat.h" +#include "compat-stdbool.h" /* branch prediction hints */ #if defined(__GNUC__) @@ -41,10 +37,6 @@ # define unlikely(x) (x) #endif -#if defined(_WIN32) && !defined(WIN32) -#define WIN32 -#endif - #ifdef WIN32 #include <windows.h> #include <winsock2.h> @@ -53,6 +45,12 @@ #define srandom srand #endif +#if defined(__APPLE__) +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070 +#define __APPLE_USE_RFC_3542 1 +#endif +#endif + #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -70,22 +68,15 @@ #endif #endif -#ifdef TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef HAVE_TIME_H +#include <time.h> #endif #ifdef HAVE_SYS_SOCKET_H -# if defined(TARGET_LINUX) && !defined(_GNU_SOURCE) - /* needed for peercred support on glibc-2.8 */ -# define _GNU_SOURCE -# endif #include <sys/socket.h> #endif @@ -105,6 +96,14 @@ #include <fcntl.h> #endif +#ifdef HAVE_DIRECT_H +#include <direct.h> +#endif + +#ifdef HAVE_IO_H +#include <io.h> +#endif + #ifdef HAVE_SYS_FILE_H #include <sys/file.h> #endif @@ -113,7 +112,9 @@ #include <stdlib.h> #endif -#ifdef HAVE_STDINT_H +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#elif defined(HAVE_STDINT_H) #include <stdint.h> #endif @@ -129,6 +130,10 @@ #include <signal.h> #endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + #ifdef HAVE_STDIO_H #include <stdio.h> #endif @@ -157,10 +162,6 @@ #include <grp.h> #endif -#ifdef USE_LIBDL -#include <dlfcn.h> -#endif - #ifdef HAVE_NETDB_H #include <netdb.h> #endif @@ -181,10 +182,14 @@ #include <sys/epoll.h> #endif -#ifdef HAVE_SETCON +#ifdef ENABLE_SELINUX #include <selinux/selinux.h> #endif +#if defined(HAVE_LIBGEN_H) +#include <libgen.h> +#endif + #ifdef TARGET_SOLARIS #ifdef HAVE_STRINGS_H #include <strings.h> @@ -203,6 +208,10 @@ #include <net/if.h> #endif +#ifdef TARGET_NETBSD +#include <net/if_tap.h> +#endif + #ifdef TARGET_LINUX #if defined(HAVE_NETINET_IF_ETHER_H) @@ -338,7 +347,12 @@ #ifdef WIN32 #include <iphlpapi.h> +#include <ntddndis.h> #include <wininet.h> +#include <shellapi.h> +/* The following two headers are needed of PF_INET6 */ +#include <winsock2.h> +#include <ws2tcpip.h> #endif #ifdef HAVE_SYS_MMAN_H @@ -374,6 +388,13 @@ #endif /* + * Do we have nanoseconds gettimeofday? + */ +#if defined(HAVE_GETTIMEOFDAY) || defined(WIN32) +#define HAVE_GETTIMEOFDAY_NANOSECONDS 1 +#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) @@ -383,15 +404,24 @@ #endif /* - * Does this platform support linux-style IP_PKTINFO? + * Does this platform support linux-style IP_PKTINFO + * or bsd-style IP_RECVDSTADDR ? */ -#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG) +#if defined(ENABLE_MULTIHOME) && ((defined(HAVE_IN_PKTINFO)&&defined(IP_PKTINFO)) || defined(IP_RECVDSTADDR)) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG) #define ENABLE_IP_PKTINFO 1 #else #define ENABLE_IP_PKTINFO 0 #endif /* + * Does this platform define SOL_IP + * or only bsd-style IPPROTO_IP ? + */ +#ifndef SOL_IP +#define SOL_IP IPPROTO_IP +#endif + +/* * Disable ESEC */ #if 0 @@ -461,14 +491,14 @@ socket_defined (const socket_descriptor_t sd) * instead of system()? */ #if defined(HAVE_EXECVE) && defined(HAVE_FORK) -#define ENABLE_EXECVE +#define ENABLE_FEATURE_EXECVE #endif /* * Do we have point-to-multipoint capability? */ -#if defined(ENABLE_CLIENT_SERVER) && defined(USE_CRYPTO) && defined(USE_SSL) && defined(HAVE_GETTIMEOFDAY) +#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS) #define P2MP 1 #else #define P2MP 0 @@ -490,36 +520,49 @@ socket_defined (const socket_descriptor_t sd) #endif /* - * Do we have a plug-in capability? - */ -#if defined(USE_LIBDL) || defined(USE_LOAD_LIBRARY) -#define ENABLE_PLUGIN -#endif - -/* * Enable deferred authentication? */ -#if defined(CONFIGURE_DEF_AUTH) && P2MP_SERVER && defined(ENABLE_PLUGIN) +#if defined(ENABLE_DEF_AUTH) && P2MP_SERVER && defined(ENABLE_PLUGIN) #define PLUGIN_DEF_AUTH #endif -#if defined(CONFIGURE_DEF_AUTH) && P2MP_SERVER && defined(ENABLE_MANAGEMENT) +#if defined(ENABLE_DEF_AUTH) && P2MP_SERVER && defined(ENABLE_MANAGEMENT) #define MANAGEMENT_DEF_AUTH #endif -#if defined(PLUGIN_DEF_AUTH) || defined(MANAGEMENT_DEF_AUTH) -#define ENABLE_DEF_AUTH +#if !defined(PLUGIN_DEF_AUTH) && !defined(MANAGEMENT_DEF_AUTH) +#undef ENABLE_DEF_AUTH +#endif + +/* + * Enable external private key + */ +#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_SSL) && !defined(ENABLE_CRYPTO_POLARSSL) +#define MANAGMENT_EXTERNAL_KEY +#endif + +/* Enable PolarSSL RNG prediction resistance support */ +#ifdef ENABLE_CRYPTO_POLARSSL +#define ENABLE_PREDICTION_RESISTANCE +#endif /* ENABLE_CRYPTO_POLARSSL */ + +/* + * MANAGEMENT_IN_EXTRA allows the management interface to + * read multi-line inputs from clients. + */ +#if defined(MANAGEMENT_DEF_AUTH) || defined(MANAGMENT_EXTERNAL_KEY) +#define MANAGEMENT_IN_EXTRA #endif /* * Enable packet filter? */ -#if defined(CONFIGURE_PF) && P2MP_SERVER && defined(ENABLE_PLUGIN) && defined(HAVE_STAT) +#if defined(ENABLE_PF) && P2MP_SERVER && defined(ENABLE_PLUGIN) && defined(HAVE_STAT) #define PLUGIN_PF #endif -#if defined(CONFIGURE_PF) && P2MP_SERVER && defined(MANAGEMENT_DEF_AUTH) +#if defined(ENABLE_PF) && P2MP_SERVER && defined(MANAGEMENT_DEF_AUTH) #define MANAGEMENT_PF #endif -#if defined(PLUGIN_PF) || defined(MANAGEMENT_PF) -#define ENABLE_PF +#if !defined(PLUGIN_PF) && !defined(MANAGEMENT_PF) +#undef ENABLE_PF #endif /* @@ -546,7 +589,7 @@ socket_defined (const socket_descriptor_t sd) /* * Should we include NTLM proxy functionality */ -#if defined(USE_CRYPTO) && defined(ENABLE_HTTP_PROXY) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY) #define NTLM 1 #else #define NTLM 0 @@ -555,7 +598,7 @@ socket_defined (const socket_descriptor_t sd) /* * Should we include proxy digest auth functionality */ -#if defined(USE_CRYPTO) && defined(ENABLE_HTTP_PROXY) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY) #define PROXY_DIGEST_AUTH 1 #else #define PROXY_DIGEST_AUTH 0 @@ -569,10 +612,17 @@ socket_defined (const socket_descriptor_t sd) #endif /* - * Do we have PKCS11 capability? + * Do we have CryptoAPI capability? + */ +#if defined(WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) +#define ENABLE_CRYPTOAPI +#endif + +/* + * Enable x509-track feature? */ -#if defined(USE_PKCS11) && defined(USE_CRYPTO) && defined(USE_SSL) -#define ENABLE_PKCS11 +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined (ENABLE_CRYPTO_OPENSSL) +#define ENABLE_X509_TRACK #endif /* @@ -600,32 +650,28 @@ socket_defined (const socket_descriptor_t sd) #endif /* - * Should we allow ca/cert/key files to be - * included inline, in the configuration file? + * Should we include http proxy override functionality */ -#define ENABLE_INLINE_FILES 1 - -/* - * Support "connection" directive - */ -#if ENABLE_INLINE_FILES -#define ENABLE_CONNECTION 1 -#endif - -/* - * Should we include http proxy fallback functionality - */ -#if defined(ENABLE_CONNECTION) && defined(ENABLE_MANAGEMENT) && defined(ENABLE_HTTP_PROXY) -#define HTTP_PROXY_FALLBACK 1 +#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_HTTP_PROXY) +#define HTTP_PROXY_OVERRIDE 1 #else -#define HTTP_PROXY_FALLBACK 0 +#define HTTP_PROXY_OVERRIDE 0 #endif /* * Reduce sensitivity to system clock instability * and backtracks. */ +#if defined(HAVE_GETTIMEOFDAY_NANOSECONDS) #define TIME_BACKTRACK_PROTECTION 1 +#endif + +/* + * Enable traffic shaper. + */ +#if defined(HAVE_GETTIMEOFDAY_NANOSECONDS) +#define ENABLE_FEATURE_SHAPER 1 +#endif /* * Is non-blocking connect() supported? @@ -644,15 +690,29 @@ socket_defined (const socket_descriptor_t sd) #endif /* - * Do we support challenge/response authentication, as a console-based client? + * Do we support challenge/response authentication as client? */ +#if defined(ENABLE_MANAGEMENT) #define ENABLE_CLIENT_CR +#endif /* * Do we support pushing peer info? */ -#if defined(USE_CRYPTO) && defined(USE_SSL) +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) #define ENABLE_PUSH_PEER_INFO #endif +/* + * Do we support internal client-side NAT? + */ +#define ENABLE_CLIENT_NAT + +/* + * Enable --memstats option + */ +#ifdef TARGET_LINUX +#define ENABLE_MEMSTATS +#endif + #endif diff --git a/tun.c b/src/openvpn/tun.c index 28aa368..4b0365d 100644 --- a/tun.c +++ b/src/openvpn/tun.c @@ -30,6 +30,12 @@ * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #include "tun.h" @@ -56,13 +62,14 @@ 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 const char *netsh_get_id (const char *dev_node, struct gc_arena *gc); #endif #ifdef TARGET_SOLARIS -static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual); +static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6); #include <stropts.h> #endif @@ -129,30 +136,6 @@ guess_tuntap_dev (const char *dev, return dev; } -/* - * Called by the open_tun function of OSes to check if we - * explicitly support IPv6. - * - * In this context, explicit means that the OS expects us to - * do something special to the tun socket in order to support - * IPv6, i.e. it is not transparent. - * - * ipv6_explicitly_supported should be set to false if we don't - * have any explicit IPv6 code in the tun device handler. - * - * If ipv6_explicitly_supported is true, then we have explicit - * OS-specific tun dev code for handling IPv6. If so, tt->ipv6 - * is set according to the --tun-ipv6 command line option. - */ -static void -ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt) -{ - tt->ipv6 = false; - if (ipv6_explicitly_supported) - tt->ipv6 = ipv6; - else if (ipv6) - msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS"); -} /* --ifconfig-nowarn disables some options sanity checking */ static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)"; @@ -271,11 +254,12 @@ check_subnet_conflict (const in_addr_t ip, const in_addr_t netmask, const char *prefix) { +#if 0 /* too many false positives */ struct gc_arena gc = gc_new (); in_addr_t lan_gw = 0; in_addr_t lan_netmask = 0; - if (get_default_gateway (&lan_gw, &lan_netmask)) + if (get_default_gateway (&lan_gw, &lan_netmask) && lan_netmask) { const in_addr_t lan_network = lan_gw & lan_netmask; const in_addr_t network = ip & netmask; @@ -293,18 +277,20 @@ check_subnet_conflict (const in_addr_t ip, } } gc_free (&gc); +#endif } void warn_on_use_of_common_subnets (void) { struct gc_arena gc = gc_new (); - in_addr_t lan_gw = 0; - in_addr_t lan_netmask = 0; + struct route_gateway_info rgi; + const int needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); - if (get_default_gateway (&lan_gw, &lan_netmask)) + get_default_gateway (&rgi); + if ((rgi.flags & needed) == needed) { - const in_addr_t lan_network = lan_gw & lan_netmask; + const in_addr_t lan_network = rgi.gateway.addr & rgi.gateway.netmask; if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100) msg (M_WARN, "NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x. Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet."); } @@ -423,6 +409,9 @@ init_tun (const char *dev, /* --dev option */ int topology, /* one of the TOP_x values */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + 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, const bool strict_warn, @@ -500,7 +489,7 @@ init_tun (const char *dev, /* --dev option */ 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"); else if (tt->type == DEV_TYPE_TUN) - check_subnet_conflict (tt->local, ~0, "TUN/TAP adapter"); + check_subnet_conflict (tt->local, IPV4_NETMASK_HOST, "TUN/TAP adapter"); } /* @@ -537,6 +526,41 @@ init_tun (const char *dev, /* --dev option */ tt->did_ifconfig_setup = true; } + + if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm) + { + const char *ifconfig_ipv6_local = NULL; + const char *ifconfig_ipv6_remote = NULL; + + /* + * Convert arguments to binary IPv6 addresses. + */ + + if ( inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1 || + inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1 ) + { + msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm ); + } + tt->netbits_ipv6 = ifconfig_ipv6_netbits_parm; + + /* + * Set ifconfig parameters + */ + ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc); + ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc); + + /* + * Set environmental variables with ifconfig parameters. + */ + if (es) + { + setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local); + setenv_int (es, "ifconfig_ipv6_netbits", tt->netbits_ipv6); + setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote); + } + tt->did_ifconfig_ipv6_setup = true; + } + gc_free (&gc); return tt; } @@ -555,10 +579,48 @@ init_tun_post (struct tuntap *tt, overlapped_io_init (&tt->writes, frame, TRUE, true); tt->rw_handle.read = tt->reads.overlapped.hEvent; tt->rw_handle.write = tt->writes.overlapped.hEvent; - tt->adapter_index = ~0; + tt->adapter_index = TUN_ADAPTER_INDEX_INVALID; #endif } +#if defined(WIN32) || \ + defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) + +/* some of the platforms will auto-add a "network route" pointing + * to the interface on "ifconfig tunX 2001:db8::1/64", others need + * an extra call to "route add..." + * -> helper function to simplify code below + */ +void add_route_connected_v6_net(struct tuntap * tt, + const struct env_set *es) +{ + struct route_ipv6 r6; + + r6.defined = true; + r6.network = tt->local_ipv6; + r6.netbits = tt->netbits_ipv6; + r6.gateway = tt->local_ipv6; + r6.metric = 0; /* connected route */ + r6.metric_defined = true; + add_route_ipv6 (&r6, tt, 0, es); +} + +void delete_route_connected_v6_net(struct tuntap * tt, + const struct env_set *es) +{ + struct route_ipv6 r6; + + r6.defined = true; + r6.network = tt->local_ipv6; + r6.netbits = tt->netbits_ipv6; + r6.gateway = tt->local_ipv6; + r6.metric = 0; /* connected route */ + r6.metric_defined = true; + delete_route_ipv6 (&r6, tt, 0, es); +} +#endif + + /* execute the ifconfig command through the shell */ void do_ifconfig (struct tuntap *tt, @@ -574,10 +636,16 @@ do_ifconfig (struct tuntap *tt, const char *ifconfig_local = NULL; 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); + msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d", + tt->ipv6, tt->did_ifconfig_ipv6_setup ); + /* * We only handle TUN/TAP devices here, not --dev null devices. */ @@ -589,6 +657,13 @@ 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 ) + { + 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; + } + /* * If TAP-style device, generate broadcast address. */ @@ -608,7 +683,7 @@ do_ifconfig (struct tuntap *tt, #if defined(TARGET_LINUX) -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE /* * Set the MTU for the device */ @@ -647,7 +722,19 @@ do_ifconfig (struct tuntap *tt, argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed"); } - tt->did_ifconfig = true; + if ( do_ipv6 ) + { + argv_printf( &argv, + "%s -6 addr add %s/%d dev %s", + iproute_path, + ifconfig_ipv6_local, + tt->netbits_ipv6, + actual + ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed"); + } + tt->did_ifconfig = true; #else if (tun) argv_printf (&argv, @@ -670,9 +757,21 @@ do_ifconfig (struct tuntap *tt, ); argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed"); + if ( do_ipv6 ) + { + argv_printf (&argv, + "%s %s add %s/%d", + IFCONFIG_PATH, + actual, + ifconfig_ipv6_local, + tt->netbits_ipv6 + ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed"); + } tt->did_ifconfig = true; -#endif /*CONFIG_FEATURE_IPROUTE*/ +#endif /*ENABLE_IPROUTE*/ #elif defined(TARGET_SOLARIS) /* Solaris 2.6 (and 7?) cannot set all parameters in one go... @@ -693,7 +792,7 @@ do_ifconfig (struct tuntap *tt, argv_msg (M_INFO, &argv); if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed")) - solaris_error_close (tt, es, actual); + solaris_error_close (tt, es, actual, false); argv_printf (&argv, "%s %s netmask 255.255.255.255", @@ -725,20 +824,65 @@ do_ifconfig (struct tuntap *tt, argv_msg (M_INFO, &argv); if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed")) - solaris_error_close (tt, es, actual); + solaris_error_close (tt, es, actual, false); + + if ( do_ipv6 ) + { + argv_printf (&argv, "%s %s inet6 unplumb", + IFCONFIG_PATH, actual ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, es, 0, NULL); + + if ( tt->type == DEV_TYPE_TUN ) + { + argv_printf (&argv, + "%s %s inet6 plumb %s/%d %s up", + IFCONFIG_PATH, + actual, + ifconfig_ipv6_local, + tt->netbits_ipv6, + ifconfig_ipv6_remote + ); + } + else /* tap mode */ + { + /* base IPv6 tap interface needs to be brought up first + */ + argv_printf (&argv, "%s %s inet6 plumb up", + IFCONFIG_PATH, actual ); + argv_msg (M_INFO, &argv); + if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed")) + solaris_error_close (tt, es, actual, true); + + /* we might need to do "ifconfig %s inet6 auto-dhcp drop" + * after the system has noticed the interface and fired up + * the DHCPv6 client - but this takes quite a while, and the + * server will ignore the DHCPv6 packets anyway. So we don't. + */ + + /* static IPv6 addresses need to go to a subinterface (tap0:1) + */ + argv_printf (&argv, + "%s %s inet6 addif %s/%d up", + IFCONFIG_PATH, actual, + ifconfig_ipv6_local, tt->netbits_ipv6 ); + } + argv_msg (M_INFO, &argv); + if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed")) + solaris_error_close (tt, es, actual, true); + } if (!tun && tt->topology == TOP_SUBNET) { /* Add a network route for the local tun interface */ struct route r; CLEAR (r); - r.defined = true; + r.flags = RT_DEFINED | RT_METRIC_DEFINED; r.network = tt->local & tt->remote_netmask; r.netmask = tt->remote_netmask; r.gateway = tt->local; - r.metric_defined = true; r.metric = 0; - add_route (&r, tt, 0, es); + add_route (&r, tt, 0, NULL, es); } tt->did_ifconfig = true; @@ -746,29 +890,15 @@ do_ifconfig (struct tuntap *tt, #elif defined(TARGET_OPENBSD) /* - * OpenBSD tun devices appear to be persistent by default. It seems in order - * to make this work correctly, we need to delete the previous instance - * (if it exists), and re-ifconfig. Let me know if you know a better way. + * On OpenBSD, tun interfaces are persistent if created with + * "ifconfig tunX create", and auto-destroyed if created by + * opening "/dev/tunX" (so we just use the /dev/tunX) */ - argv_printf (&argv, - "%s %s destroy", - IFCONFIG_PATH, - actual); - argv_msg (M_INFO, &argv); - openvpn_execve_check (&argv, es, 0, NULL); - argv_printf (&argv, - "%s %s create", - IFCONFIG_PATH, - actual); - argv_msg (M_INFO, &argv); - openvpn_execve_check (&argv, es, 0, NULL); - msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure"); - /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ if (tun) argv_printf (&argv, - "%s %s %s %s mtu %d netmask 255.255.255.255 up", + "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0", IFCONFIG_PATH, actual, ifconfig_local, @@ -776,6 +906,19 @@ do_ifconfig (struct tuntap *tt, tun_mtu ); else + if ( tt->topology == TOP_SUBNET ) + { + argv_printf (&argv, + "%s %s %s %s mtu %d netmask %s up -link0", + IFCONFIG_PATH, + actual, + ifconfig_local, + ifconfig_local, + tun_mtu, + ifconfig_remote_netmask + ); + } + else argv_printf (&argv, "%s %s %s netmask %s mtu %d broadcast %s link0", IFCONFIG_PATH, @@ -787,10 +930,32 @@ do_ifconfig (struct tuntap *tt, ); argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed"); + if ( do_ipv6 ) + { + 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, es, S_FATAL, "OpenBSD ifconfig inet6 failed"); + + /* and, hooray, we explicitely need to add a route... */ + add_route_connected_v6_net(tt, es); + } tt->did_ifconfig = true; #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", @@ -801,6 +966,19 @@ do_ifconfig (struct tuntap *tt, tun_mtu ); else + if ( tt->topology == TOP_SUBNET ) + { + argv_printf (&argv, + "%s %s %s %s mtu %d netmask %s up", + IFCONFIG_PATH, + actual, + ifconfig_local, + ifconfig_local, + tun_mtu, + ifconfig_remote_netmask + ); + } + else /* * NetBSD has distinct tun and tap devices * so we don't need the "link0" extra parameter to specify we want to do @@ -817,10 +995,30 @@ do_ifconfig (struct tuntap *tt, ); argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed"); + + if ( do_ipv6 ) + { +#ifdef NETBSD_MULTI_AF + 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, es, S_FATAL, "NetBSD ifconfig inet6 failed"); + + /* 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; #elif defined(TARGET_DARWIN) - /* * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD... */ @@ -866,6 +1064,7 @@ do_ifconfig (struct tuntap *tt, tun_mtu ); } + argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "Mac OS X ifconfig failed"); tt->did_ifconfig = true; @@ -875,11 +1074,27 @@ do_ifconfig (struct tuntap *tt, { struct route r; CLEAR (r); - r.defined = true; + r.flags = RT_DEFINED; r.network = tt->local & tt->remote_netmask; r.netmask = tt->remote_netmask; r.gateway = tt->local; - add_route (&r, tt, 0, es); + add_route (&r, tt, 0, NULL, es); + } + + if ( do_ipv6 ) + { + 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, es, S_FATAL, "MacOS X ifconfig inet6 failed"); + + /* and, hooray, we explicitely need to add a route... */ + add_route_connected_v6_net(tt, es); } #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY) @@ -894,6 +1109,18 @@ do_ifconfig (struct tuntap *tt, ifconfig_remote_netmask, tun_mtu ); + else if ( tt->topology == TOP_SUBNET ) + { + argv_printf (&argv, + "%s %s %s %s mtu %d netmask %s up", + IFCONFIG_PATH, + actual, + ifconfig_local, + ifconfig_local, + tun_mtu, + ifconfig_remote_netmask + ); + } else argv_printf (&argv, "%s %s %s netmask %s mtu %d up", @@ -903,23 +1130,36 @@ do_ifconfig (struct tuntap *tt, ifconfig_remote_netmask, tun_mtu ); - + argv_msg (M_INFO, &argv); openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig failed"); tt->did_ifconfig = true; /* Add a network route for the local tun interface */ if (!tun && tt->topology == TOP_SUBNET) - { + { struct route r; - CLEAR (r); - r.defined = true; + CLEAR (r); + r.flags = RT_DEFINED; r.network = tt->local & tt->remote_netmask; r.netmask = tt->remote_netmask; - r.gateway = tt->local; - add_route (&r, tt, 0, es); + r.gateway = tt->local; + add_route (&r, tt, 0, NULL, es); } + if ( do_ipv6 ) + { + 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, es, S_FATAL, "FreeBSD ifconfig inet6 failed"); + } + #elif defined (WIN32) { /* @@ -946,7 +1186,7 @@ do_ifconfig (struct tuntap *tt, 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-Win32 adapter, you must also specify --dev-node"); + 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, @@ -959,6 +1199,34 @@ do_ifconfig (struct tuntap *tt, tt->did_ifconfig = true; } + /* IPv6 always uses "netsh" interface */ + if ( do_ipv6 ) + { + char * saved_actual; + + 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"); + + /* example: netsh interface ipv6 set address MyTap 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, + actual, + ifconfig_ipv6_local ); + + netsh_command (&argv, 4); + + /* 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; + 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."); #endif @@ -967,7 +1235,7 @@ do_ifconfig (struct tuntap *tt, gc_free (&gc); } -void +static void clear_tuntap (struct tuntap *tuntap) { CLEAR (*tuntap); @@ -991,14 +1259,16 @@ open_null (struct tuntap *tt) #ifndef WIN32 static void open_tun_generic (const char *dev, const char *dev_type, const char *dev_node, - bool ipv6, bool ipv6_explicitly_supported, bool dynamic, + bool ipv6_explicitly_supported, bool dynamic, struct tuntap *tt) { char tunname[256]; char dynamic_name[256]; bool dynamic_opened = false; - ipv6_support (ipv6, ipv6_explicitly_supported, tt); + + 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) { @@ -1020,6 +1290,30 @@ open_tun_generic (const char *dev, const char *dev_type, const char *dev_node, * explicit unit number. Try opening /dev/[dev]n * where n = [0, 255]. */ +#ifdef TARGET_NETBSD + /* on NetBSD, tap (but not tun) devices are opened by + * opening /dev/tap and then querying the system about the + * actual device name (tap0, tap1, ...) assigned + */ + if ( dynamic && strcmp( dev, "tap" ) == 0 ) + { + struct ifreq ifr; + if ((tt->fd = open ( "/dev/tap", O_RDWR)) < 0) + { + msg (M_FATAL, "Cannot allocate NetBSD TAP dev dynamically"); + } + if ( ioctl( tt->fd, TAPGIFNAME, (void*)&ifr ) < 0 ) + { + msg (M_FATAL, "Cannot query NetBSD TAP device name"); + } + CLEAR(dynamic_name); + strncpy( dynamic_name, ifr.ifr_name, sizeof(dynamic_name)-1 ); + dynamic_opened = true; + openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dynamic_name ); + } + else +#endif + if (dynamic && !has_digit((unsigned char *)dev)) { int i; @@ -1050,6 +1344,13 @@ open_tun_generic (const char *dev, const char *dev_type, const char *dev_node, if (!dynamic_opened) { + /* has named device existed before? if so, don't destroy at end */ + if ( if_nametoindex( dev ) > 0 ) + { + msg (M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev ); + tt->persistent_if = true; + } + if ((tt->fd = open (tunname, O_RDWR)) < 0) msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname); } @@ -1083,29 +1384,14 @@ close_tun_generic (struct tuntap *tt) #error header file linux/sockios.h required #endif -#if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV) -#define LINUX_IPV6 1 -/* #warning IPv6 ON */ -#else -#define LINUX_IPV6 0 -/* #warning IPv6 OFF */ -#endif - #if !PEDANTIC void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { struct ifreq ifr; /* - * Set tt->ipv6 to true if - * (a) we have the capability of supporting --tun-ipv6, and - * (b) --tun-ipv6 was specified. - */ - ipv6_support (ipv6, LINUX_IPV6, tt); - - /* * We handle --dev null specially, we do not open /dev/null for this. */ if (tt->type == DEV_TYPE_NULL) @@ -1126,8 +1412,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 */ if ((tt->fd = open (node, O_RDWR)) < 0) { - msg (M_WARN | M_ERRNO, "Note: Cannot open TUN/TAP dev %s", node); - return; + msg (M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node); } /* @@ -1170,8 +1455,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 */ if (ioctl (tt->fd, TUNSETIFF, (void *) &ifr) < 0) { - msg (M_WARN | M_ERRNO, "Note: Cannot ioctl TUNSETIFF %s", dev); - return; + msg (M_ERR, "ERROR: Cannot ioctl TUNSETIFF %s", dev); } msg (M_INFO, "TUN/TAP device %s opened", ifr.ifr_name); @@ -1212,7 +1496,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 #else void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { ASSERT (0); } @@ -1222,14 +1506,14 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 #else void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt); + open_tun_generic (dev, dev_type, dev_node, false, true, tt); } #endif /* HAVE_LINUX_IF_TUN_H */ -#ifdef TUNSETPERSIST +#ifdef ENABLE_FEATURE_TUN_PERSIST /* * This can be removed in future @@ -1244,7 +1528,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 #endif void -tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options) +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) { struct tuntap *tt; @@ -1252,34 +1536,34 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, clear_tuntap (tt); tt->type = dev_type_enum (dev, dev_type); tt->options = *options; - open_tun (dev, dev_type, dev_node, ipv6, tt); + open_tun (dev, dev_type, dev_node, tt); if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0) msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); if (username != NULL) { - struct user_state user_state; + struct platform_state_user platform_state_user; - if (!get_user (username, &user_state)) + if (!platform_user_get (username, &platform_state_user)) msg (M_ERR, "Cannot get user entry for %s", username); else - if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0) + if (ioctl (tt->fd, TUNSETOWNER, platform_state_user.pw->pw_uid) < 0) msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev); } if (groupname != NULL) { - struct group_state group_state; + struct platform_state_group platform_state_group; - if (!get_group (groupname, &group_state)) + if (!platform_group_get (groupname, &platform_state_group)) msg (M_ERR, "Cannot get group entry for %s", groupname); else - if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0) + if (ioctl (tt->fd, TUNSETGROUP, platform_state_group.gr->gr_gid) < 0) msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev); } close_tun (tt); msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF")); } -#endif /* TUNSETPERSIST */ +#endif /* ENABLE_FEATURE_TUN_PERSIST */ void close_tun (struct tuntap *tt) @@ -1292,7 +1576,7 @@ close_tun (struct tuntap *tt) struct gc_arena gc = gc_new (); argv_init (&argv); -#ifdef CONFIG_FEATURE_IPROUTE +#ifdef ENABLE_IPROUTE if (is_tun_p2p (tt)) { argv_printf (&argv, @@ -1335,7 +1619,6 @@ close_tun (struct tuntap *tt) int write_tun (struct tuntap* tt, uint8_t *buf, int len) { -#if LINUX_IPV6 if (tt->ipv6) { struct tun_pi pi; @@ -1361,14 +1644,12 @@ write_tun (struct tuntap* tt, uint8_t *buf, int len) return(ret - sizeof(pi)); } else -#endif return write (tt->fd, buf, len); } int read_tun (struct tuntap* tt, uint8_t *buf, int len) { -#if LINUX_IPV6 if (tt->ipv6) { struct iovec vect[2]; @@ -1384,7 +1665,6 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) return(ret - sizeof(pi)); } else -#endif return read (tt->fd, buf, len); } @@ -1395,7 +1675,7 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) #endif void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1; struct lifreq ifr; @@ -1406,8 +1686,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 bool is_tun; struct strioctl strioc_if, strioc_ppa; - ipv6_support (ipv6, true, tt); - memset(&ifr, 0x0, sizeof(ifr)); + /* improved generic TUN/TAP driver from + * http://www.whiteboard.ne.jp/~admin2/tuntap/ + * has IPv6 support + */ + CLEAR(ifr); if (tt->type == DEV_TYPE_NULL) { @@ -1439,6 +1722,12 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 msg (M_FATAL, "I don't recognize device %s as a tun or tap device", dev); } + + if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0) + msg (M_ERR, "Can't open %s", ip_node); + + if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0) + msg (M_ERR, "Can't open %s", dev_node); /* get unit number */ if (*dev) @@ -1449,19 +1738,37 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 ppa = atoi (ptr); } - if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0) - msg (M_ERR, "Can't open %s", ip_node); - - if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0) - msg (M_ERR, "Can't open %s", dev_node); - /* Assign a new PPA and get its unit number. */ strioc_ppa.ic_cmd = TUNNEWPPA; strioc_ppa.ic_timout = 0; strioc_ppa.ic_len = sizeof(ppa); strioc_ppa.ic_dp = (char *)&ppa; - if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0) - msg (M_ERR, "Can't assign new interface"); + + if ( *ptr == '\0' ) /* no number given, try dynamic */ + { + bool found_one = false; + while( ! found_one && ppa < 64 ) + { + int new_ppa = ioctl (tt->fd, I_STR, &strioc_ppa); + if ( new_ppa >= 0 ) + { + msg( M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa ); + ppa = new_ppa; + found_one = true; + break; + } + if ( errno != EEXIST ) + msg (M_ERR, "open_tun: unexpected error trying to find free %s interface", dev_tuntap_type ); + ppa++; + } + if ( !found_one ) + msg (M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type ); + } + else /* try this particular one */ + { + if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0) + msg (M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa ); + } if ((if_fd = open (dev_node, O_RDWR, 0)) < 0) msg (M_ERR, "Can't open %s (2)", dev_node); @@ -1561,6 +1868,18 @@ solaris_close_tun (struct tuntap *tt) { if (tt) { + /* IPv6 interfaces need to be 'manually' de-configured */ + if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) + { + struct argv argv; + argv_init (&argv); + argv_printf( &argv, "%s %s inet6 unplumb", + IFCONFIG_PATH, tt->actual_name ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed"); + argv_reset (&argv); + } + if (tt->ip_fd >= 0) { struct lifreq ifr; @@ -1613,11 +1932,20 @@ close_tun (struct tuntap *tt) } static void -solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual) +solaris_error_close (struct tuntap *tt, const struct env_set *es, + const char *actual, bool unplumb_inet6 ) { struct argv argv; argv_init (&argv); + if (unplumb_inet6) + { + argv_printf( &argv, "%s %s inet6 unplumb", + IFCONFIG_PATH, actual ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed"); + } + argv_printf (&argv, "%s %s unplumb", IFCONFIG_PATH, @@ -1652,10 +1980,6 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) #elif defined(TARGET_OPENBSD) -#if !defined(HAVE_READV) || !defined(HAVE_WRITEV) -#error openbsd build requires readv & writev library functions -#endif - /* * OpenBSD has a slightly incompatible TUN device from * the rest of the world, in that it prepends a @@ -1674,9 +1998,9 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) */ void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); + open_tun_generic (dev, dev_type, dev_node, true, true, tt); /* Enable multicast on the interface */ if (tt->fd >= 0) @@ -1688,7 +2012,9 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 strerror(errno)); } +#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */ info.flags |= IFF_MULTICAST; +#endif if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) { msg (M_WARN | M_ERRNO, "Can't set interface info: %s", @@ -1697,12 +2023,42 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 } } +/* tun(4): "If the device was created by opening /dev/tunN, it will be + * automatically destroyed. Devices created via ifconfig(8) are + * only marked as not running and traffic will be dropped + * returning EHOSTDOWN." + * --> no special handling should be needed - *but* OpenBSD is misbehaving + * here: if the interface was put in tap mode ("ifconfig tunN link0"), it + * *will* stay around, and needs to be cleaned up manually + */ + void close_tun (struct tuntap* tt) { - if (tt) + /* only *TAP* devices need destroying, tun devices auto-self-destruct + */ + if (tt && (tt->type == DEV_TYPE_TUN || tt->persistent_if ) ) { close_tun_generic (tt); + free(tt); + } + else if (tt) + { + struct gc_arena gc = gc_new (); + struct argv argv; + + /* 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); + + close_tun_generic (tt); + + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)"); + free (tt); } } @@ -1765,40 +2121,142 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) #elif defined(TARGET_NETBSD) /* - * NetBSD does not support IPv6 on tun out of the box, - * but there exists a patch. When this patch is applied, - * only two things are left to openvpn: - * 1. Activate multicasting (this has already been done - * before by the kernel, but we make sure that nobody - * has deactivated multicasting inbetween. - * 2. Deactivate "link layer mode" (otherwise NetBSD - * prepends the address family to the packet, and we - * would run into the same trouble as with OpenBSD. + * NetBSD before 4.0 does not support IPv6 on tun out of the box, + * but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944). + * + * NetBSD 4.0 and up do, but we need to put the tun interface into + * "multi_af" mode, which will prepend the address family to all packets + * (same as OpenBSD and FreeBSD). If this is not enabled, the kernel + * silently drops all IPv6 packets on output and gets confused on input. + * + * On earlier versions, multi_af is not available at all, so we have + * two different NetBSD code variants here :-( + * */ void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, 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 + if (tt->fd >= 0) { int i = IFF_POINTOPOINT|IFF_MULTICAST; ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */ i = 0; ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */ + +#ifdef NETBSD_MULTI_AF + if ( tt->type == DEV_TYPE_TUN ) + { + i = 1; + if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ + { + msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); + } + } +#endif } } +/* the current way OpenVPN handles tun devices on NetBSD leads to + * lingering tunX interfaces after close -> for a full cleanup, they + * need to be explicitely destroyed + */ void close_tun (struct tuntap *tt) { - if (tt) + /* only tun devices need destroying, tap devices auto-self-destruct + */ + if (tt && ( tt->type != DEV_TYPE_TUN || tt->persistent_if ) ) + { + close_tun_generic (tt); + free(tt); + } + else if (tt) { + struct gc_arena gc = gc_new (); + struct argv argv; + + /* 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); + close_tun_generic (tt); + + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)"); + free (tt); } } +#ifdef NETBSD_MULTI_AF + +static inline int +netbsd_modify_read_write_return (int len) +{ + if (len > 0) + return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0; + else + return len; +} + +int +write_tun (struct tuntap* tt, uint8_t *buf, int len) +{ + if (tt->type == DEV_TYPE_TUN) + { + u_int32_t type; + struct iovec iv[2]; + struct openvpn_iphdr *iph; + + iph = (struct openvpn_iphdr *) buf; + + if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6) + type = htonl (AF_INET6); + else + type = htonl (AF_INET); + + iv[0].iov_base = (char *)&type; + iv[0].iov_len = sizeof (type); + iv[1].iov_base = buf; + iv[1].iov_len = len; + + return netbsd_modify_read_write_return (writev (tt->fd, iv, 2)); + } + else + return write (tt->fd, buf, len); +} + +int +read_tun (struct tuntap* tt, uint8_t *buf, int len) +{ + if (tt->type == DEV_TYPE_TUN) + { + u_int32_t type; + struct iovec iv[2]; + + iv[0].iov_base = (char *)&type; + iv[0].iov_len = sizeof (type); + iv[1].iov_base = buf; + iv[1].iov_len = len; + + return netbsd_modify_read_write_return (readv (tt->fd, iv, 2)); + } + else + 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) { @@ -1810,6 +2268,7 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) { return read (tt->fd, buf, len); } +#endif /* NETBSD_MULTI_AF */ #elif defined(TARGET_FREEBSD) @@ -1823,16 +2282,14 @@ freebsd_modify_read_write_return (int len) } void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); + open_tun_generic (dev, dev_type, dev_node, true, true, tt); if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN) { - int i = 0; + int i = IFF_POINTOPOINT | IFF_MULTICAST; - i = tt->topology == TOP_SUBNET ? IFF_BROADCAST : IFF_POINTOPOINT; - i |= IFF_MULTICAST; if (ioctl (tt->fd, TUNSIFMODE, &i) < 0) { msg (M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno)); } @@ -1843,12 +2300,38 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 } } +/* tun(4): "These network interfaces persist until the if_tun.ko module is + * unloaded, or until removed with the ifconfig(8) command." + * (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4)) + * + * so, to avoid lingering tun/tap interfaces after OpenVPN quits, + * we need to call "ifconfig ... destroy" for cleanup + */ void close_tun (struct tuntap *tt) { - if (tt) + if (tt && tt->persistent_if ) /* keep pre-existing if around */ + { + close_tun_generic (tt); + free (tt); + } + else if (tt) /* close and destroy */ { + struct gc_arena gc = gc_new (); + struct argv argv; + + /* 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); + close_tun_generic (tt); + + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, NULL, 0, "FreeBSD 'destroy tun interface' failed (non-critical)"); + free (tt); } } @@ -1911,9 +2394,9 @@ dragonfly_modify_read_write_return (int len) } void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); + open_tun_generic (dev, dev_type, dev_node, true, true, tt); if (tt->fd >= 0) { @@ -1982,6 +2465,61 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) return read (tt->fd, buf, len); } +#elif defined(TARGET_DARWIN) + +/* Darwin (MacOS X) is mostly "just use the generic stuff", but there + * is always one caveat...: + * + * If IPv6 is configured, and the tun device is closed, the IPv6 address + * configured to the tun interface changes to a lingering /128 route + * pointing to lo0. Need to unconfigure... (observed on 10.5) + */ + +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); +} + +void +close_tun (struct tuntap* tt) +{ + if (tt) + { + struct gc_arena gc = gc_new (); + struct argv argv; + argv_init (&argv); + + if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) + { + const char * ifconfig_ipv6_local = + print_in6_addr (tt->local_ipv6, 0, &gc); + + argv_printf (&argv, "%s delete -inet6 %s", + ROUTE_PATH, ifconfig_ipv6_local ); + argv_msg (M_INFO, &argv); + openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)"); + } + + close_tun_generic (tt); + free (tt); + argv_reset (&argv); + gc_free (&gc); + } +} + +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 @@ -2275,7 +2813,7 @@ get_tap_reg (struct gc_arena *gc) if (status == ERROR_SUCCESS && data_type == REG_SZ) { - if (!strcmp (component_id, TAP_COMPONENT_ID)) + if (!strcmp (component_id, TAP_WIN_COMPONENT_ID)) { struct tap_reg *reg; ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc); @@ -2442,7 +2980,7 @@ void show_valid_win32_tun_subnets (void) int col = 0; printf ("On Windows, point-to-point IP support (i.e. --dev tun)\n"); - printf ("is emulated by the TAP-Win32 driver. The major limitation\n"); + printf ("is emulated by the TAP-Windows driver. The major limitation\n"); printf ("imposed by this approach is that the --ifconfig local and\n"); printf ("remote endpoints must be part of the same 255.255.255.252\n"); printf ("subnet. The following list shows examples of endpoint\n"); @@ -2467,7 +3005,7 @@ void show_valid_win32_tun_subnets (void) } void -show_tap_win32_adapters (int msglev, int warnlev) +show_tap_win_adapters (int msglev, int warnlev) { struct gc_arena gc = gc_new (); @@ -2486,7 +3024,7 @@ show_tap_win32_adapters (int msglev, int warnlev) msg (msglev, "Available TAP-WIN32 adapters [name, GUID]:"); - /* loop through each TAP-Win32 adapter registry entry */ + /* loop through each TAP-Windows adapter registry entry */ for (tr = tap_reg; tr != NULL; tr = tr->next) { links = 0; @@ -2514,7 +3052,7 @@ show_tap_win32_adapters (int msglev, int warnlev) } } - /* check for TAP-Win32 adapter duplicated GUIDs */ + /* check for TAP-Windows adapter duplicated GUIDs */ for (tr = tap_reg; tr != NULL; tr = tr->next) { for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next) @@ -2526,22 +3064,22 @@ show_tap_win32_adapters (int msglev, int warnlev) /* warn on registry inconsistencies */ if (warn_tap_dup) - msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate GUIDs"); + msg (warnlev, "WARNING: Some TAP-Windows adapters have duplicate GUIDs"); if (warn_panel_dup) - msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate links from the Network Connections control panel"); + msg (warnlev, "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel"); if (warn_panel_null) - msg (warnlev, "WARNING: Some TAP-Win32 adapters have no link from the Network Connections control panel"); + msg (warnlev, "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel"); gc_free (&gc); } /* - * Confirm that GUID is a TAP-Win32 adapter. + * Confirm that GUID is a TAP-Windows adapter. */ static bool -is_tap_win32 (const char *guid, const struct tap_reg *tap_reg) +is_tap_win (const char *guid, const struct tap_reg *tap_reg) { const struct tap_reg *tr; @@ -2575,7 +3113,7 @@ name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct pane for (pr = panel_reg; pr != NULL; pr = pr->next) { - if (name && !strcmp (pr->name, name) && is_tap_win32 (pr->guid, tap_reg)) + if (name && !strcmp (pr->name, name) && is_tap_win (pr->guid, tap_reg)) return pr->guid; } @@ -2583,10 +3121,10 @@ name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct pane } static void -at_least_one_tap_win32 (const struct tap_reg *tap_reg) +at_least_one_tap_win (const struct tap_reg *tap_reg) { if (!tap_reg) - msg (M_FATAL, "There are no TAP-Win32 adapters on this system. You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Win32 virtual ethernet adapter."); + msg (M_FATAL, "There are no TAP-Windows adapters on this system. You should be able to create a TAP-Windows adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Windows virtual ethernet adapter."); } /* @@ -2670,7 +3208,7 @@ get_device_guid (const char *name, } /* Check if GUID was explicitly specified as --dev-node parameter */ - if (is_tap_win32 (name, tap_reg)) + if (is_tap_win (name, tap_reg)) { const char *act = guid_to_name (name, panel_reg); buf_printf (&ret, "%s", name); @@ -2733,7 +3271,7 @@ get_per_adapter_info (const DWORD index, struct gc_arena *gc) IP_PER_ADAPTER_INFO *pi = NULL; DWORD status; - if (index != ~0) + if (index != TUN_ADAPTER_INDEX_INVALID) { if ((status = GetPerAdapterInfo (index, NULL, &size)) != ERROR_BUFFER_OVERFLOW) { @@ -2810,7 +3348,7 @@ get_interface_info (DWORD index, struct gc_arena *gc) const IP_ADAPTER_INFO * get_adapter (const IP_ADAPTER_INFO *ai, DWORD index) { - if (ai && index != (DWORD)~0) + if (ai && index != TUN_ADAPTER_INDEX_INVALID) { const IP_ADAPTER_INFO *a; @@ -2987,7 +3525,7 @@ adapter_index_of_ip (const IP_ADAPTER_INFO *list, in_addr_t *netmask) { struct gc_arena gc = gc_new (); - DWORD ret = ~0; + DWORD ret = TUN_ADAPTER_INDEX_INVALID; in_addr_t highest_netmask = 0; bool first = true; @@ -3023,7 +3561,7 @@ adapter_index_of_ip (const IP_ADAPTER_INFO *list, (int)ret, count ? *count : -1); - if (ret == ~0 && count) + if (ret == TUN_ADAPTER_INDEX_INVALID && count) *count = 0; if (netmask) @@ -3047,7 +3585,7 @@ dhcp_status (DWORD index) { struct gc_arena gc = gc_new (); int ret = DHCP_STATUS_UNDEF; - if (index != ~0) + if (index != TUN_ADAPTER_INDEX_INVALID) { const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc); @@ -3109,15 +3647,15 @@ delete_temp_addresses (DWORD index) static DWORD get_adapter_index_method_1 (const char *guid) { - struct gc_arena gc = gc_new (); - ULONG index = ~0; - DWORD status; + DWORD index; + ULONG aindex; wchar_t wbuf[256]; - snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid); + _snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid); wbuf [SIZE(wbuf) - 1] = 0; - if ((status = GetAdapterIndex (wbuf, &index)) != NO_ERROR) - index = ~0; - gc_free (&gc); + if (GetAdapterIndex (wbuf, &aindex) != NO_ERROR) + index = TUN_ADAPTER_INDEX_INVALID; + else + index = (DWORD)aindex; return index; } @@ -3125,7 +3663,7 @@ static DWORD get_adapter_index_method_2 (const char *guid) { struct gc_arena gc = gc_new (); - DWORD index = ~0; + DWORD index = TUN_ADAPTER_INDEX_INVALID; const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc); @@ -3148,9 +3686,9 @@ get_adapter_index (const char *guid) { DWORD index; index = get_adapter_index_method_1 (guid); - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) index = get_adapter_index_method_2 (guid); - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) msg (M_INFO, "NOTE: could not get adapter index for %s", guid); return index; } @@ -3161,18 +3699,18 @@ get_adapter_index_flexible (const char *name) /* actual name or GUID */ struct gc_arena gc = gc_new (); DWORD index; index = get_adapter_index_method_1 (name); - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) index = get_adapter_index_method_2 (name); - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) { const struct tap_reg *tap_reg = get_tap_reg (&gc); const struct panel_reg *panel_reg = get_panel_reg (&gc); const char *guid = name_to_guid (name, tap_reg, panel_reg); index = get_adapter_index_method_1 (guid); - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) index = get_adapter_index_method_2 (guid); } - if (index == ~0) + if (index == TUN_ADAPTER_INDEX_INVALID) msg (M_INFO, "NOTE: could not get adapter index for name/GUID '%s'", name); gc_free (&gc); return index; @@ -3256,7 +3794,7 @@ show_adapters (int msglev) } /* - * Set a particular TAP-Win32 adapter (or all of them if + * Set a particular TAP-Windows adapter (or all of them if * adapter_name == NULL) to allow it to be opened from * a non-admin account. This setting will only persist * for the lifetime of the device object. @@ -3278,7 +3816,7 @@ tap_allow_nonadmin_access_handle (const char *device_path, HANDLE hand) } else { - msg (M_INFO|M_NOPREFIX, "TAP-Win32 device: %s [Non-admin access allowed]", device_path); + msg (M_INFO|M_NOPREFIX, "TAP-Windows device: %s [Non-admin access allowed]", device_path); } } @@ -3293,7 +3831,7 @@ tap_allow_nonadmin_access (const char *dev_node) char actual_buffer[256]; char device_path[256]; - at_least_one_tap_win32 (tap_reg); + at_least_one_tap_win (tap_reg); if (dev_node) { @@ -3301,13 +3839,13 @@ tap_allow_nonadmin_access (const char *dev_node) device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc); if (!device_guid) - msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node); + msg (M_FATAL, "TAP-Windows adapter '%s' not found", dev_node); - /* Open Windows TAP-Win32 adapter */ + /* Open Windows TAP-Windows adapter */ openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid, - TAPSUFFIX); + TAP_WIN_SUFFIX); hand = CreateFile ( device_path, @@ -3342,11 +3880,11 @@ tap_allow_nonadmin_access (const char *dev_node) if (!device_guid) break; - /* Open Windows TAP-Win32 adapter */ + /* Open Windows TAP-Windows adapter */ openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid, - TAPSUFFIX); + TAP_WIN_SUFFIX); hand = CreateFile ( device_path, @@ -3391,7 +3929,7 @@ dhcp_release_by_adapter_index(const DWORD adapter_index) ret = true; } else - msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)", + msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)", strerror_win32 (status, &gc), (unsigned int)status); } @@ -3403,7 +3941,7 @@ dhcp_release_by_adapter_index(const DWORD adapter_index) static bool dhcp_release (const struct tuntap *tt) { - if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0) + if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != TUN_ADAPTER_INDEX_INVALID) return dhcp_release_by_adapter_index (tt->adapter_index); else return false; @@ -3425,7 +3963,7 @@ dhcp_renew_by_adapter_index (const DWORD adapter_index) ret = true; } else - msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)", + msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)", strerror_win32 (status, &gc), (unsigned int)status); } @@ -3436,7 +3974,7 @@ dhcp_renew_by_adapter_index (const DWORD adapter_index) static bool dhcp_renew (const struct tuntap *tt) { - if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0) + if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != TUN_ADAPTER_INDEX_INVALID) return dhcp_renew_by_adapter_index (tt->adapter_index); else return false; @@ -3770,7 +4308,7 @@ netsh_get_id (const char *dev_node, struct gc_arena *gc) struct buffer actual = alloc_buf_gc (256, gc); const char *guid; - at_least_one_tap_win32 (tap_reg); + at_least_one_tap_win (tap_reg); if (dev_node) { @@ -3780,7 +4318,7 @@ netsh_get_id (const char *dev_node, struct gc_arena *gc) { guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc); - if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */ + if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Windows adapter */ guid = NULL; } @@ -3793,7 +4331,7 @@ netsh_get_id (const char *dev_node, struct gc_arena *gc) } /* - * Called iteratively on TAP-Win32 wait-for-initialization polling loop + * Called iteratively on TAP-Windows wait-for-initialization polling loop */ void tun_standby_init (struct tuntap *tt) @@ -3966,8 +4504,29 @@ fork_register_dns_action (struct tuntap *tt) } } +static uint32_t +dhcp_masq_addr (const in_addr_t local, const in_addr_t netmask, const int offset) +{ + struct gc_arena gc = gc_new (); + in_addr_t dsa; /* DHCP server addr */ + + if (offset < 0) + dsa = (local | (~netmask)) + offset; + else + dsa = (local & netmask) + offset; + + if (dsa == local) + msg (M_FATAL, "ERROR: There is a clash between the --ifconfig local address and the internal DHCP server address -- both are set to %s -- please use the --ip-win32 dynamic option to choose a different free address from the --ifconfig subnet for the internal DHCP server", print_in_addr_t (dsa, 0, &gc)); + + if ((local & netmask) != (dsa & netmask)) + msg (M_FATAL, "ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet"); + + gc_free (&gc); + return htonl(dsa); +} + void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { struct gc_arena gc = gc_new (); char device_path[256]; @@ -3978,7 +4537,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 /*netcmd_semaphore_lock ();*/ - ipv6_support (ipv6, false, tt); + msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 ); if (tt->type == DEV_TYPE_NULL) { @@ -4003,7 +4562,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 const struct panel_reg *panel_reg = get_panel_reg (&gc); char actual_buffer[256]; - at_least_one_tap_win32 (tap_reg); + at_least_one_tap_win (tap_reg); if (dev_node) { @@ -4011,13 +4570,13 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc); if (!device_guid) - msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node); + msg (M_FATAL, "TAP-Windows adapter '%s' not found", dev_node); - /* Open Windows TAP-Win32 adapter */ + /* Open Windows TAP-Windows adapter */ openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid, - TAPSUFFIX); + TAP_WIN_SUFFIX); tt->hand = CreateFile ( device_path, @@ -4047,13 +4606,13 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 &gc); if (!device_guid) - msg (M_FATAL, "All TAP-Win32 adapters on this system are currently in use."); + msg (M_FATAL, "All TAP-Windows adapters on this system are currently in use."); - /* Open Windows TAP-Win32 adapter */ + /* Open Windows TAP-Windows adapter */ openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid, - TAPSUFFIX); + TAP_WIN_SUFFIX); tt->hand = CreateFile ( device_path, @@ -4086,36 +4645,54 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 { ULONG info[3]; CLEAR (info); - if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_VERSION, + if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_VERSION, &info, sizeof (info), &info, sizeof (info), &len, NULL)) { - msg (D_TUNTAP_INFO, "TAP-Win32 Driver Version %d.%d %s", + msg (D_TUNTAP_INFO, "TAP-Windows Driver Version %d.%d %s", (int) info[0], (int) info[1], (info[2] ? "(DEBUG)" : "")); } - if (!(info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) - msg (M_FATAL, "ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.", - TAP_WIN32_MIN_MAJOR, - TAP_WIN32_MIN_MINOR); + if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR)) + msg (M_FATAL, "ERROR: This version of " PACKAGE_NAME " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.", + TAP_WIN_MIN_MAJOR, + TAP_WIN_MIN_MINOR); + + /* 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 && + 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; + } + + /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy + */ + 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] ); + } } /* get driver MTU */ { ULONG mtu; - if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_MTU, + if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_MTU, &mtu, sizeof (mtu), &mtu, sizeof (mtu), &len, NULL)) { tt->post_open_mtu = (int) mtu; - msg (D_MTU_INFO, "TAP-Win32 MTU=%d", (int) mtu); + msg (D_MTU_INFO, "TAP-Windows MTU=%d", (int) mtu); } } /* - * Preliminaries for setting TAP-Win32 adapter TCP/IP + * Preliminaries for setting TAP-Windows adapter TCP/IP * properties via --ip-win32 dynamic or --ip-win32 adaptive. */ if (tt->did_ifconfig_setup) @@ -4168,11 +4745,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 ep[1] = htonl (tt->local & tt->remote_netmask); ep[2] = htonl (tt->remote_netmask); - status = DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_TUN, + status = DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_TUN, ep, sizeof (ep), ep, sizeof (ep), &len, NULL); - msg (status ? M_INFO : M_FATAL, "Set TAP-Win32 TUN subnet mode network/local/netmask = %s/%s/%s [%s]", + msg (status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]", print_in_addr_t (ep[1], IA_NET_ORDER, &gc), print_in_addr_t (ep[0], IA_NET_ORDER, &gc), print_in_addr_t (ep[2], IA_NET_ORDER, &gc), @@ -4184,14 +4761,14 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 ep[0] = htonl (tt->local); ep[1] = htonl (tt->remote_netmask); - if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_POINT_TO_POINT, + if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep, sizeof (ep), ep, sizeof (ep), &len, NULL)) - msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun"); + msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun"); } } - /* should we tell the TAP-Win32 driver to masquerade as a DHCP server as a means + /* should we tell the TAP-Windows driver to masquerade as a DHCP server as a means of setting the adapter address? */ if (dhcp_masq) { @@ -4206,33 +4783,18 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 { if (tt->topology == TOP_SUBNET) { - const in_addr_t netmask_inv = ~tt->remote_netmask; - ep[2] = netmask_inv ? htonl ((tt->local | netmask_inv) - 1) : 0; + if (tt->options.dhcp_masq_custom_offset) + ep[2] = dhcp_masq_addr (tt->local, tt->remote_netmask, tt->options.dhcp_masq_offset); + else + ep[2] = dhcp_masq_addr (tt->local, tt->remote_netmask, -1); } else ep[2] = htonl (tt->remote_netmask); - - if (tt->options.dhcp_masq_custom_offset) - msg (M_WARN, "WARNING: because you are using '--dev tun' mode, the '--ip-win32 dynamic [offset]' option is ignoring the offset parameter"); } else { - in_addr_t dsa; /* DHCP server addr */ - ASSERT (tt->type == DEV_TYPE_TAP); - - if (tt->options.dhcp_masq_offset < 0) - dsa = (tt->local | (~tt->adapter_netmask)) + tt->options.dhcp_masq_offset; - else - dsa = (tt->local & tt->adapter_netmask) + tt->options.dhcp_masq_offset; - - if (dsa == tt->local) - msg (M_FATAL, "ERROR: There is a clash between the --ifconfig local address and the internal DHCP server address -- both are set to %s -- please use the --ip-win32 dynamic option to choose a different free address from the --ifconfig subnet for the internal DHCP server", print_in_addr_t (dsa, 0, &gc)); - - if ((tt->local & tt->adapter_netmask) != (dsa & tt->adapter_netmask)) - msg (M_FATAL, "ERROR: --tap-win32 dynamic [offset] : offset is outside of --ifconfig subnet"); - - ep[2] = htonl (dsa); + ep[2] = dhcp_masq_addr (tt->local, tt->adapter_netmask, tt->options.dhcp_masq_custom_offset ? tt->options.dhcp_masq_offset : 0); } /* lease time in seconds */ @@ -4241,12 +4803,12 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 ASSERT (ep[3] > 0); #ifndef SIMULATE_DHCP_FAILED /* this code is disabled to simulate bad DHCP negotiation */ - if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_MASQ, + if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep, sizeof (ep), ep, sizeof (ep), &len, NULL)) - msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set TAP_IOCTL_CONFIG_DHCP_MASQ mode"); + msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode"); - msg (M_INFO, "Notified TAP-Win32 driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]", + msg (M_INFO, "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]", print_in_addr_t (tt->local, 0, &gc), print_in_addr_t (tt->adapter_netmask, 0, &gc), device_guid, @@ -4261,10 +4823,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 if (build_dhcp_options_string (&buf, &tt->options)) { msg (D_DHCP_OPT, "DHCP option string: %s", format_hex (BPTR (&buf), BLEN (&buf), 0, &gc)); - if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_SET_OPT, + if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT, BPTR (&buf), BLEN (&buf), BPTR (&buf), BLEN (&buf), &len, NULL)) - msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a TAP_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call"); + msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call"); } else msg (M_WARN, "DHCP option string not set due to error"); @@ -4276,10 +4838,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 /* set driver media status to 'connected' */ { ULONG status = TRUE; - if (!DeviceIoControl (tt->hand, TAP_IOCTL_SET_MEDIA_STATUS, + if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS, &status, sizeof (status), &status, sizeof (status), &len, NULL)) - msg (M_WARN, "WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call."); + msg (M_WARN, "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call."); } /* possible wait for adapter to come up */ @@ -4297,7 +4859,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 const DWORD index = tt->adapter_index; /* flush arp cache */ - if (index != (DWORD)~0) + if (index != TUN_ADAPTER_INDEX_INVALID) { DWORD status; @@ -4314,7 +4876,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 } /* - * If the TAP-Win32 driver is masquerading as a DHCP server + * If the TAP-Windows driver is masquerading as a DHCP server * make sure the TCP/IP properties for the adapter are * set correctly. */ @@ -4322,7 +4884,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 { /* check dhcp enable status */ if (dhcp_status (index) == DHCP_STATUS_DISABLED) - msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'"); + msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Windows TCP/IP properties are set to 'Obtain an IP address automatically'"); /* force an explicit DHCP lease renewal on TAP adapter? */ if (tt->options.dhcp_pre_release) @@ -4339,7 +4901,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 const char *error_suffix = "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')"; /* couldn't get adapter index */ - if (index == (DWORD)~0) + if (index == TUN_ADAPTER_INDEX_INVALID) { msg (M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s", device_guid, @@ -4348,7 +4910,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 /* check dhcp enable status */ if (dhcp_status (index) == DHCP_STATUS_DISABLED) - msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'"); + msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Windows TCP/IP properties are set to 'Obtain an IP address automatically'"); /* delete previously added IP addresses which were not correctly deleted */ @@ -4382,13 +4944,13 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 } const char * -tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc) +tap_win_getinfo (const struct tuntap *tt, struct gc_arena *gc) { if (tt && tt->hand != NULL) { struct buffer out = alloc_buf_gc (256, gc); DWORD len; - if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_INFO, + if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_INFO, BSTR (&out), BCAP (&out), BSTR (&out), BCAP (&out), &len, NULL)) @@ -4406,12 +4968,12 @@ tun_show_debug (struct tuntap *tt) { struct buffer out = alloc_buf (1024); DWORD len; - while (DeviceIoControl (tt->hand, TAP_IOCTL_GET_LOG_LINE, + while (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_LOG_LINE, BSTR (&out), BCAP (&out), BSTR (&out), BCAP (&out), &len, NULL)) { - msg (D_TAP_WIN32_DEBUG, "TAP-Win32: %s", BSTR (&out)); + msg (D_TAP_WIN_DEBUG, "TAP-Windows: %s", BSTR (&out)); } free_buf (&out); } @@ -4424,13 +4986,34 @@ close_tun (struct tuntap *tt) if (tt) { + if ( tt->ipv6 && 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); + + /* 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", + get_win_sys_path(), + NETSH_PATH_SUFFIX, + tt->actual_name, + ifconfig_ipv6_local ); + + netsh_command (&argv, 1); + argv_reset (&argv); + } #if 1 if (tt->ipapi_context_defined) { DWORD status; if ((status = DeleteIPAddress (tt->ipapi_context)) != NO_ERROR) { - msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Win32 adapter, status=%u : %s", + msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s", (unsigned int)tt->ipapi_context, (unsigned int)status, strerror_win32 (status, &gc)); @@ -4443,22 +5026,22 @@ close_tun (struct tuntap *tt) if (tt->hand != NULL) { - dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Win32 adapter"); + dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Windows adapter"); if (!CancelIo (tt->hand)) - msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Win32 adapter"); + msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Windows adapter"); } - dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Win32 adapter"); + dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Windows adapter"); overlapped_io_close (&tt->reads); - dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Win32 adapter"); + dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Windows adapter"); overlapped_io_close (&tt->writes); if (tt->hand != NULL) { - dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Win32 adapter"); + dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Windows adapter"); if (!CloseHandle (tt->hand)) - msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Win32 adapter"); + msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Windows adapter"); } if (tt->actual_name) @@ -4527,9 +5110,9 @@ ipset2ascii_all (struct gc_arena *gc) #else /* generic */ void -open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) { - open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt); + open_tun_generic (dev, dev_type, dev_node, false, true, tt); } void diff --git a/tun.h b/src/openvpn/tun.h index 011ab54..8622bf8 100644 --- a/tun.h +++ b/src/openvpn/tun.h @@ -27,7 +27,7 @@ #ifdef WIN32 #include <winioctl.h> -#include "tap-win32/common.h" +#include <tap-windows.h> #endif #include "buffer.h" @@ -40,6 +40,8 @@ #ifdef WIN32 +#define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1) + /* time constants for --ip-win32 adaptive */ #define IPW32_SET_ADAPTIVE_DELAY_WINDOW 300 #define IPW32_SET_ADAPTIVE_TRY_NETSH 20 @@ -130,10 +132,13 @@ struct tuntap int topology; /* one of the TOP_x values */ bool did_ifconfig_setup; + 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 */ char *actual_name; /* actual name of TUN/TAP dev, usually including unit number */ @@ -146,6 +151,10 @@ struct tuntap in_addr_t remote_netmask; in_addr_t broadcast; + struct in6_addr local_ipv6; + struct in6_addr remote_ipv6; + int netbits_ipv6; + #ifdef WIN32 HANDLE hand; struct overlapped_io reads; @@ -159,7 +168,7 @@ struct tuntap ULONG ipapi_instance; in_addr_t adapter_netmask; - /* Windows adapter index for TAP-Win32 adapter, + /* Windows adapter index for TAP-Windows adapter, ~0 if undefined */ DWORD adapter_index; @@ -194,10 +203,10 @@ tuntap_defined (const struct tuntap *tt) * Function prototypes */ -void clear_tuntap (struct tuntap *tuntap); +static void clear_tuntap (struct tuntap *tuntap); void open_tun (const char *dev, const char *dev_type, const char *dev_node, - bool ipv6, struct tuntap *tt); + struct tuntap *tt); void close_tun (struct tuntap *tt); @@ -206,7 +215,7 @@ int write_tun (struct tuntap* tt, uint8_t *buf, int len); int read_tun (struct tuntap* tt, uint8_t *buf, int len); void tuncfg (const char *dev, const char *dev_type, const char *dev_node, - bool ipv6, int persist_mode, const char *username, + int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options); const char *guess_tuntap_dev (const char *dev, @@ -219,6 +228,9 @@ struct tuntap *init_tun (const char *dev, /* --dev option */ int topology, /* one of the TOP_x values */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + 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, const bool strict_warn, @@ -275,7 +287,7 @@ ifconfig_order(void) #elif defined(TARGET_SOLARIS) return IFCONFIG_AFTER_TUN_OPEN; #elif defined(TARGET_OPENBSD) - return IFCONFIG_BEFORE_TUN_OPEN; + return IFCONFIG_AFTER_TUN_OPEN; #elif defined(TARGET_DARWIN) return IFCONFIG_AFTER_TUN_OPEN; #elif defined(TARGET_NETBSD) @@ -325,13 +337,13 @@ DWORD adapter_index_of_ip (const IP_ADAPTER_INFO *list, int *count, in_addr_t *netmask); -void show_tap_win32_adapters (int msglev, int warnlev); +void show_tap_win_adapters (int msglev, int warnlev); void show_adapters (int msglev); void tap_allow_nonadmin_access (const char *dev_node); void show_valid_win32_tun_subnets (void); -const char *tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc); +const char *tap_win_getinfo (const struct tuntap *tt, struct gc_arena *gc); void tun_show_debug (struct tuntap *tt); bool dhcp_release_by_adapter_index(const DWORD adapter_index); diff --git a/win32.c b/src/openvpn/win32.c index 2b7bf7b..2db96a8 100644 --- a/win32.c +++ b/src/openvpn/win32.c @@ -26,6 +26,13 @@ * Win32-specific OpenVPN code, targetted at the mingw * development environment. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + #include "syshead.h" #ifdef WIN32 @@ -75,51 +82,6 @@ struct semaphore netcmd_semaphore; /* GLOBAL */ */ static char *win_sys_path = NULL; /* GLOBAL */ -/* - * Configure PATH. On Windows, sometimes PATH is not set correctly - * by default. - */ -static void -configure_win_path (void) -{ - static bool done = false; /* GLOBAL */ - if (!done) - { - FILE *fp; - fp = fopen ("c:\\windows\\system32\\route.exe", "rb"); - if (fp) - { - const int bufsiz = 4096; - struct gc_arena gc = gc_new (); - struct buffer oldpath = alloc_buf_gc (bufsiz, &gc); - struct buffer newpath = alloc_buf_gc (bufsiz, &gc); - const char* delim = ";"; - DWORD status; - fclose (fp); - status = GetEnvironmentVariable ("PATH", BPTR(&oldpath), (DWORD)BCAP(&oldpath)); -#if 0 - status = 0; -#endif - if (!status) - { - *BPTR(&oldpath) = '\0'; - delim = ""; - } - buf_printf (&newpath, "C:\\WINDOWS\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem%s%s", - delim, - BSTR(&oldpath)); - SetEnvironmentVariable ("PATH", BSTR(&newpath)); -#if 0 - status = GetEnvironmentVariable ("PATH", BPTR(&oldpath), (DWORD)BCAP(&oldpath)); - if (status > 0) - printf ("PATH: %s\n", BSTR(&oldpath)); -#endif - gc_free (&gc); - done = true; - } - } -} - void init_win32 (void) { @@ -250,7 +212,7 @@ init_net_event_win32 (struct rw_handle *event, long network_events, socket_descr /* setup network events to change read event state */ if (WSAEventSelect (sd, event->read, network_events) != 0) - msg (M_FATAL | M_ERRNO_SOCK, "Error: init_net_event_win32: WSAEventSelect call failed"); + msg (M_FATAL | M_ERRNO, "Error: init_net_event_win32: WSAEventSelect call failed"); } long @@ -259,7 +221,7 @@ reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd) WSANETWORKEVENTS wne; if (WSAEnumNetworkEvents (sd, event->read, &wne) != 0) { - msg (M_FATAL | M_ERRNO_SOCK, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed"); + msg (M_FATAL | M_ERRNO, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed"); return 0; /* NOTREACHED */ } else @@ -274,7 +236,7 @@ close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned if (socket_defined (sd)) { if (WSAEventSelect (sd, event->read, 0) != 0) - msg (M_WARN | M_ERRNO_SOCK, "Warning: close_net_event_win32: WSAEventSelect call failed"); + msg (M_WARN | M_ERRNO, "Warning: close_net_event_win32: WSAEventSelect call failed"); } if (!ResetEvent (event->read)) msg (M_WARN | M_ERRNO, "Warning: ResetEvent (read) failed in close_net_event_win32"); @@ -507,7 +469,7 @@ win32_signal_close (struct win32_signal *ws) /* * Return true if interrupt occurs in service mode. */ -static bool +bool win32_service_interrupt (struct win32_signal *ws) { if (ws->mode == WSO_MODE_SERVICE) @@ -611,7 +573,7 @@ window_title_generate (const char *title) struct buffer out = alloc_buf_gc (256, &gc); if (!title) title = ""; - buf_printf (&out, "[%s] " PACKAGE_NAME " " VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title); + buf_printf (&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title); SetConsoleTitle (BSTR (&out)); gc_free (&gc); } @@ -733,79 +695,6 @@ netcmd_semaphore_release (void) } /* - * Get input from console. - * - * Return false on input error, or if service - * exit event is signaled. - */ - -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; - - 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; - } - - 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; -} - -/* get password from console */ - -char * -getpass (const char *prompt) -{ - static char line[256]; - if (get_console_input_win32 (prompt, false, line, sizeof (line))) - return line; - else - return NULL; -} - -/* * Return true if filename is safe to be used on Windows, * by avoiding the following reserved names: * @@ -874,16 +763,21 @@ win_safe_filename (const char *fn) static char * env_block (const struct env_set *es) { + char * force_path = "PATH=C:\\Windows\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem"; + if (es) { struct env_item *e; char *ret; char *p; size_t nchars = 1; + bool path_seen = false; for (e = es->list; e != NULL; e = e->next) nchars += strlen (e->string) + 1; + nchars += strlen(force_path)+1; + ret = (char *) malloc (nchars); check_malloc_return (ret); @@ -895,7 +789,18 @@ env_block (const struct env_set *es) strcpy (p, e->string); p += strlen (e->string) + 1; } + if ( strncmp(e->string, "PATH=", 5 ) == 0 ) + path_seen = true; } + + /* make sure PATH is set */ + if ( !path_seen ) + { + msg( M_INFO, "env_block: add %s", force_path ); + strcpy( p, force_path ); + p += strlen(force_path) + 1; + } + *p = '\0'; return ret; } @@ -903,8 +808,8 @@ env_block (const struct env_set *es) return NULL; } -static char * -cmd_line (const struct argv *a) +static WCHAR * +wide_cmd_line (const struct argv *a, struct gc_arena *gc) { size_t nchars = 1; size_t maxlen = 0; @@ -924,9 +829,9 @@ cmd_line (const struct argv *a) maxlen = len; } - work = (char *) malloc (maxlen + 1); + work = gc_malloc (maxlen + 1, false, gc); check_malloc_return (work); - buf = alloc_buf (nchars); + buf = alloc_buf_gc (nchars, gc); for (i = 0; i < a->argc; ++i) { @@ -941,8 +846,7 @@ cmd_line (const struct argv *a) buf_printf (&buf, "\"%s\"", work); } - free (work); - return BSTR(&buf); + return wide_string (BSTR (&buf), gc); } /* @@ -958,52 +862,41 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i { if (openvpn_execve_allowed (flags)) { - if (script_method == SM_EXECVE) - { - STARTUPINFO start_info; - PROCESS_INFORMATION proc_info; - - char *env = env_block (es); - char *cl = cmd_line (a); - char *cmd = a->argv[0]; - - CLEAR (start_info); - CLEAR (proc_info); - - /* fill in STARTUPINFO struct */ - GetStartupInfo(&start_info); - start_info.cb = sizeof(start_info); - start_info.dwFlags = STARTF_USESHOWWINDOW; - start_info.wShowWindow = SW_HIDE; - - if (CreateProcess (cmd, cl, NULL, NULL, FALSE, 0, env, NULL, &start_info, &proc_info)) - { - DWORD exit_status = 0; - CloseHandle (proc_info.hThread); - WaitForSingleObject (proc_info.hProcess, INFINITE); - if (GetExitCodeProcess (proc_info.hProcess, &exit_status)) - ret = (int)exit_status; - else - msg (M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %s failed", cmd); - CloseHandle (proc_info.hProcess); - } - else - { - msg (M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %s failed", cmd); - } - free (cl); - free (env); - } - else if (script_method == SM_SYSTEM) - { - configure_win_path (); - ret = openvpn_system (argv_system_str (a), es, flags); - } - else - { - ASSERT (0); - } - } + struct gc_arena gc = gc_new (); + STARTUPINFOW start_info; + PROCESS_INFORMATION proc_info; + + char *env = env_block (es); + WCHAR *cl = wide_cmd_line (a, &gc); + WCHAR *cmd = wide_string (a->argv[0], &gc); + + CLEAR (start_info); + CLEAR (proc_info); + + /* fill in STARTUPINFO struct */ + GetStartupInfoW(&start_info); + start_info.cb = sizeof(start_info); + start_info.dwFlags = STARTF_USESHOWWINDOW; + start_info.wShowWindow = SW_HIDE; + + if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, 0, env, NULL, &start_info, &proc_info)) + { + DWORD exit_status = 0; + CloseHandle (proc_info.hThread); + WaitForSingleObject (proc_info.hProcess, INFINITE); + if (GetExitCodeProcess (proc_info.hProcess, &exit_status)) + ret = (int)exit_status; + else + msg (M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd); + CloseHandle (proc_info.hProcess); + } + else + { + msg (M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd); + } + free (env); + gc_free (&gc); + } else if (!exec_warn && (script_security < SSEC_SCRIPTS)) { msg (M_WARN, SCRIPT_SECURITY_WARNING); @@ -1017,6 +910,15 @@ openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned i return ret; } +WCHAR * +wide_string (const char* utf8, struct gc_arena *gc) +{ + int n = MultiByteToWideChar (CP_UTF8, 0, utf8, -1, NULL, 0); + WCHAR *ucs16 = gc_malloc (n * sizeof (WCHAR), false, gc); + MultiByteToWideChar (CP_UTF8, 0, utf8, -1, ucs16, n); + return ucs16; +} + /* * call ourself in another process */ @@ -1087,12 +989,6 @@ set_win_sys_path_via_env (struct env_set *es) set_win_sys_path (buf, es); } -void -env_set_add_win32 (struct env_set *es) -{ - set_win_sys_path (DEFAULT_WIN_SYS_PATH, es); -} - const char * win_get_tempdir() diff --git a/win32.h b/src/openvpn/win32.h index b6a162e..cc18f02 100644 --- a/win32.h +++ b/src/openvpn/win32.h @@ -30,7 +30,6 @@ /* location of executables */ #define SYS_PATH_ENV_VAR_NAME "SystemRoot" /* environmental variable name that normally contains the system path */ -#define DEFAULT_WIN_SYS_PATH "C:\\WINDOWS" /* --win-sys default value */ #define NETSH_PATH_SUFFIX "\\system32\\netsh.exe" #define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe" #define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe" @@ -41,22 +40,17 @@ * development environment. */ +/* MSVC headers do not define this macro, so do it here */ +#ifndef IN6_ARE_ADDR_EQUAL +#define IN6_ARE_ADDR_EQUAL(a,b) \ + (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0) +#endif + void init_win32 (void); void uninit_win32 (void); void set_pause_exit_win32 (void); -/* - * Use keyboard input or events - * to simulate incoming signals - */ - -#define SIGUSR1 1 -#define SIGUSR2 2 -#define SIGHUP 3 -#define SIGTERM 4 -#define SIGINT 5 - struct security_attributes { SECURITY_ATTRIBUTES sa; @@ -172,6 +166,8 @@ int win32_signal_get (struct win32_signal *ws); void win32_pause (struct win32_signal *ws); +bool win32_service_interrupt (struct win32_signal *ws); + /* * Set the text on the window title bar */ @@ -195,7 +191,10 @@ struct overlapped_io { DWORD flags; int status; bool addr_defined; - struct sockaddr_in addr; + union { + struct sockaddr_in addr; + struct sockaddr_in6 addr6; + }; int addrlen; struct buffer buf_init; struct buffer buf; @@ -249,9 +248,6 @@ void netcmd_semaphore_close (void); void netcmd_semaphore_lock (void); void netcmd_semaphore_release (void); -bool get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity); -char *getpass (const char *prompt); - /* Set Win32 security attributes structure to allow all access */ bool init_security_attributes_allow_all (struct security_attributes *obj); @@ -260,7 +256,6 @@ bool win_safe_filename (const char *fn); /* add constant environmental variables needed by Windows */ struct env_set; -void env_set_add_win32 (struct env_set *es); /* get and set the current windows system path */ void set_win_sys_path (const char *newpath, struct env_set *es); @@ -273,5 +268,8 @@ void fork_to_self (const char *cmdline); /* Find temporary directory */ const char *win_get_tempdir(); +/* Convert a string from UTF-8 to UCS-2 */ +WCHAR *wide_string (const char* utf8, struct gc_arena *gc); + #endif #endif diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am new file mode 100644 index 0000000..a989c25 --- /dev/null +++ b/src/openvpnserv/Makefile.am @@ -0,0 +1,27 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +include $(top_srcdir)/build/ltrc.inc + +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +EXTRA_DIST = \ + openvpnserv.vcxproj \ + openvpnserv.vcxproj.filters + +if WIN32 +sbin_PROGRAMS = openvpnserv +endif + +openvpnserv_SOURCES = \ + openvpnserv.c \ + service.h service.c \ + openvpnserv_resources.rc diff --git a/service-win32/Makefile.in b/src/openvpnserv/Makefile.in index 88ef15b..b47d092 100644 --- a/service-win32/Makefile.in +++ b/src/openvpnserv/Makefile.in @@ -23,22 +23,19 @@ # packet compression. # # Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@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. +# 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. # -# 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 +# Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com> # - +# Required to build Windows resource file VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ @@ -59,13 +56,18 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/build/ltrc.inc @WIN32_TRUE@sbin_PROGRAMS = openvpnserv$(EXEEXT) -subdir = service-win32 -DIST_COMMON = $(am__dist_noinst_DATA_DIST) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +subdir = src/openvpnserv ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac +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 @@ -74,9 +76,8 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) -am__openvpnserv_SOURCES_DIST = openvpnserv.c service.h service.c -@WIN32_TRUE@am_openvpnserv_OBJECTS = openvpnserv.$(OBJEXT) \ -@WIN32_TRUE@ service.$(OBJEXT) +am_openvpnserv_OBJECTS = openvpnserv.$(OBJEXT) service.$(OBJEXT) \ + openvpnserv_resources.$(OBJEXT) openvpnserv_OBJECTS = $(am_openvpnserv_OBJECTS) openvpnserv_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) @@ -85,17 +86,22 @@ am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ SOURCES = $(openvpnserv_SOURCES) -DIST_SOURCES = $(am__openvpnserv_SOURCES_DIST) -am__dist_noinst_DATA_DIST = openvpnserv.c service.h service.c -DATA = $(dist_noinst_DATA) +DIST_SOURCES = $(openvpnserv_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -108,11 +114,17 @@ 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@ @@ -121,15 +133,40 @@ 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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ MAKEINFO = @MAKEINFO@ MAN2HTML = @MAN2HTML@ 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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -138,19 +175,35 @@ 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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ -TAP_ID = @TAP_ID@ -TAP_WIN32_MIN_MAJOR = @TAP_WIN32_MIN_MAJOR@ -TAP_WIN32_MIN_MINOR = @TAP_WIN32_MIN_MINOR@ +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@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ @@ -185,9 +238,11 @@ 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@ @@ -196,21 +251,25 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -win32datadir = @win32datadir@ +RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) + +LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -@WIN32_TRUE@openvpnserv_SOURCES = \ -@WIN32_TRUE@ openvpnserv.c \ -@WIN32_TRUE@ service.h service.c +EXTRA_DIST = \ + openvpnserv.vcxproj \ + openvpnserv.vcxproj.filters -@WIN32_FALSE@dist_noinst_DATA = \ -@WIN32_FALSE@ openvpnserv.c \ -@WIN32_FALSE@ service.h service.c +openvpnserv_SOURCES = \ + openvpnserv.c \ + service.h service.c \ + openvpnserv_resources.rc all: all-am .SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +.SUFFIXES: .c .lo .mc .o .obj .rc +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -219,9 +278,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu service-win32/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/openvpnserv/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu service-win32/Makefile + $(AUTOMAKE) --gnu src/openvpnserv/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -246,7 +305,7 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ + while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ @@ -260,8 +319,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done @@ -276,7 +335,13 @@ uninstall-sbinPROGRAMS: cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + @list='$(sbin_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 openvpnserv$(EXEEXT): $(openvpnserv_OBJECTS) $(openvpnserv_DEPENDENCIES) @rm -f openvpnserv$(EXEEXT) $(LINK) $(openvpnserv_OBJECTS) $(openvpnserv_LDADD) $(LIBS) @@ -304,6 +369,19 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -388,7 +466,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) $(DATA) +all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -421,7 +499,8 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -476,7 +555,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf: pdf-am @@ -491,18 +571,28 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS ctags distclean distclean-compile \ - distclean-generic 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-sbinPROGRAMS install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ + clean-libtool clean-sbinPROGRAMS ctags 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-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-sbinPROGRAMS + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-sbinPROGRAMS + + +.rc.lo: + $(LTRCCOMPILE) -i "$<" -o "$@" + +.rc.o: + $(RCCOMPILE) -i "$<" -o "$@" +.mc.rc: + $(WINDMC) "$<" # 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/service-win32/openvpnserv.c b/src/openvpnserv/openvpnserv.c index 5b0eb6e..56f5a02 100755 --- a/service-win32/openvpnserv.c +++ b/src/openvpnserv/openvpnserv.c @@ -33,7 +33,11 @@ * 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> @@ -83,9 +87,9 @@ static HANDLE exit_event = NULL; /* * 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 +#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, ...) \ @@ -133,15 +137,15 @@ static HANDLE exit_event = NULL; int openvpn_snprintf(char *str, size_t size, const char *format, ...) { va_list arglist; - int ret = 0; + int len = -1; if (size > 0) { va_start (arglist, format); - ret = vsnprintf (str, size, format, arglist); + len = vsnprintf (str, size, format, arglist); va_end (arglist); str[size - 1] = 0; } - return ret; + return (len >= 0 && len < size); } @@ -196,7 +200,7 @@ match (const WIN32_FIND_DATA *find, const char *ext) if (i < 1) return false; - return find->cFileName[i] == '.' && !strcasecmp (find->cFileName + i + 1, ext); + return find->cFileName[i] == '.' && !_stricmp (find->cFileName + i + 1, ext); } /* @@ -331,15 +335,15 @@ VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) /* set process priority */ priority = NORMAL_PRIORITY_CLASS; - if (!strcasecmp (priority_string, "IDLE_PRIORITY_CLASS")) + if (!_stricmp (priority_string, "IDLE_PRIORITY_CLASS")) priority = IDLE_PRIORITY_CLASS; - else if (!strcasecmp (priority_string, "BELOW_NORMAL_PRIORITY_CLASS")) + else if (!_stricmp (priority_string, "BELOW_NORMAL_PRIORITY_CLASS")) priority = BELOW_NORMAL_PRIORITY_CLASS; - else if (!strcasecmp (priority_string, "NORMAL_PRIORITY_CLASS")) + else if (!_stricmp (priority_string, "NORMAL_PRIORITY_CLASS")) priority = NORMAL_PRIORITY_CLASS; - else if (!strcasecmp (priority_string, "ABOVE_NORMAL_PRIORITY_CLASS")) + else if (!_stricmp (priority_string, "ABOVE_NORMAL_PRIORITY_CLASS")) priority = ABOVE_NORMAL_PRIORITY_CLASS; - else if (!strcasecmp (priority_string, "HIGH_PRIORITY_CLASS")) + else if (!_stricmp (priority_string, "HIGH_PRIORITY_CLASS")) priority = HIGH_PRIORITY_CLASS; else { diff --git a/src/openvpnserv/openvpnserv.vcxproj b/src/openvpnserv/openvpnserv.vcxproj new file mode 100644 index 0000000..0b75ed0 --- /dev/null +++ b/src/openvpnserv/openvpnserv.vcxproj @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9C91EE0B-817D-420A-A1E6-15A5A9D98BAD}</ProjectGuid> + <RootNamespace>openvpnserv</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-Output\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;$(CPPFLAGS);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="openvpnserv.c" /> + <ClCompile Include="service.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="service.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="openvpnserv_resources.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\build\msvc\msvc-generate\msvc-generate.vcxproj"> + <Project>{8598c2c8-34c4-47a1-99b0-7c295a890615}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/openvpnserv/openvpnserv.vcxproj.filters b/src/openvpnserv/openvpnserv.vcxproj.filters new file mode 100644 index 0000000..0c89b4f --- /dev/null +++ b/src/openvpnserv/openvpnserv.vcxproj.filters @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="openvpnserv.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="service.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="service.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="openvpnserv_resources.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/openvpnserv/openvpnserv_resources.rc b/src/openvpnserv/openvpnserv_resources.rc new file mode 100644 index 0000000..7980193 --- /dev/null +++ b/src/openvpnserv/openvpnserv_resources.rc @@ -0,0 +1,43 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#else +#include <config-msvc-version.h> +#endif +#include <winresrc.h> + +#pragma code_page(65001) /* UTF8 */ + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENVPN_VERSION_RESOURCE + PRODUCTVERSION OPENVPN_VERSION_RESOURCE + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The OpenVPN Project" + VALUE "FileDescription", "OpenVPN Service" + VALUE "FileVersion", PACKAGE_VERSION ".0" + VALUE "InternalName", "OpenVPN" + VALUE "LegalCopyright", "Copyright © The OpenVPN Project" + VALUE "OriginalFilename", "openvpnserv.exe" + VALUE "ProductName", "OpenVPN" + VALUE "ProductVersion", PACKAGE_VERSION ".0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/service-win32/service.c b/src/openvpnserv/service.c index 91b5821..d7562b3 100644 --- a/service-win32/service.c +++ b/src/openvpnserv/service.c @@ -23,6 +23,11 @@ FUNCTIONS: ---------------------------------------------------------------------------*/ +#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> diff --git a/service-win32/service.h b/src/openvpnserv/service.h index 028d075..e89a89f 100644 --- a/service-win32/service.h +++ b/src/openvpnserv/service.h @@ -57,8 +57,6 @@ Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved. extern "C" { #endif -#include "config.h" - ////////////////////////////////////////////////////////////////////////////// //// todo: change to desired strings //// @@ -69,7 +67,7 @@ extern "C" { // displayed name of the service #define SZSERVICEDISPLAYNAME PACKAGE_NAME " Service" // list of service dependencies - "dep1\0dep2\0\0" -#define SZDEPENDENCIES TAP_ID "\0Dhcp\0\0" +#define SZDEPENDENCIES TAP_WIN_COMPONENT_ID "\0Dhcp\0\0" ////////////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am new file mode 100644 index 0000000..17b72b9 --- /dev/null +++ b/src/plugins/Makefile.am @@ -0,0 +1,15 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = auth-pam down-root diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in new file mode 100644 index 0000000..805a7f6 --- /dev/null +++ b/src/plugins/Makefile.in @@ -0,0 +1,613 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# +VPATH = @srcdir@ +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 = src/plugins +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +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@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +SUBDIRS = auth-pam down-root +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) --gnu src/plugins/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/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. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive 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-recursive \ + 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/src/plugins/auth-pam/Makefile.am b/src/plugins/auth-pam/Makefile.am new file mode 100644 index 0000000..701a749 --- /dev/null +++ b/src/plugins/auth-pam/Makefile.am @@ -0,0 +1,27 @@ +# +# OpenVPN (TM) PAM Auth Plugin -- OpenVPN Plugin +# +# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +AM_CFLAGS = \ + -I$(top_srcdir)/include + $(PLUGIN_AUTH_PAM_CFLAGS) + +if ENABLE_PLUGIN_AUTH_PAM +plugin_LTLIBRARIES = openvpn-plugin-auth-pam.la +dist_doc_DATA = README.auth-pam +endif + +openvpn_plugin_auth_pam_la_SOURCES = \ + auth-pam.c \ + pamdl.c pamdl.h \ + auth-pam.exports +openvpn_plugin_auth_pam_la_LIBADD = \ + $(PLUGIN_AUTH_PAM_LIBS) +openvpn_plugin_auth_pam_la_LDFLAGS = $(AM_LDFLAGS) \ + -export-symbols "$(srcdir)/auth-pam.exports" \ + -module -shared -avoid-version -no-undefined diff --git a/src/plugins/auth-pam/Makefile.in b/src/plugins/auth-pam/Makefile.in new file mode 100644 index 0000000..49e4063 --- /dev/null +++ b/src/plugins/auth-pam/Makefile.in @@ -0,0 +1,619 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# OpenVPN (TM) PAM Auth Plugin -- OpenVPN Plugin +# +# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + + +VPATH = @srcdir@ +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 = src/plugins/auth-pam +DIST_COMMON = $(am__dist_doc_DATA_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +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 +openvpn_plugin_auth_pam_la_OBJECTS = \ + $(am_openvpn_plugin_auth_pam_la_OBJECTS) +openvpn_plugin_auth_pam_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(openvpn_plugin_auth_pam_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@ENABLE_PLUGIN_AUTH_PAM_TRUE@am_openvpn_plugin_auth_pam_la_rpath = \ +@ENABLE_PLUGIN_AUTH_PAM_TRUE@ -rpath $(plugindir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(openvpn_plugin_auth_pam_la_SOURCES) +DIST_SOURCES = $(openvpn_plugin_auth_pam_la_SOURCES) +am__dist_doc_DATA_DIST = README.auth-pam +DATA = $(dist_doc_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +AM_CFLAGS = \ + -I$(top_srcdir)/include + +@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 = \ + auth-pam.c \ + pamdl.c pamdl.h \ + auth-pam.exports + +openvpn_plugin_auth_pam_la_LIBADD = \ + $(PLUGIN_AUTH_PAM_LIBS) + +openvpn_plugin_auth_pam_la_LDFLAGS = $(AM_LDFLAGS) \ + -export-symbols "$(srcdir)/auth-pam.exports" \ + -module -shared -avoid-version -no-undefined + +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) --gnu src/plugins/auth-pam/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/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): +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +openvpn-plugin-auth-pam.la: $(openvpn_plugin_auth_pam_la_OBJECTS) $(openvpn_plugin_auth_pam_la_DEPENDENCIES) + $(openvpn_plugin_auth_pam_la_LINK) $(am_openvpn_plugin_auth_pam_la_rpath) $(openvpn_plugin_auth_pam_la_OBJECTS) $(openvpn_plugin_auth_pam_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth-pam.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pamdl.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(docdir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-dist_docDATA install-pluginLTLIBRARIES + +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: uninstall-dist_docDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES ctags 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-dist_docDATA 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-pluginLTLIBRARIES 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 uninstall uninstall-am \ + uninstall-dist_docDATA uninstall-pluginLTLIBRARIES + + $(PLUGIN_AUTH_PAM_CFLAGS) + +# 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/plugin/auth-pam/README b/src/plugins/auth-pam/README.auth-pam index c957c02..e123690 100644 --- a/plugin/auth-pam/README +++ b/src/plugins/auth-pam/README.auth-pam @@ -48,7 +48,7 @@ For example, suppose you were using a PAM module called plugin openvpn-auth-pam.so "test name USERNAME password PASSWORD" -While "USERNAME" and "PASSWORD" are special strings which substitute +While "USERNAME" "COMMONNAME" and "PASSWORD" are special strings which substitute to client-supplied values, it is also possible to name literal values to use as PAM module query responses. For example, suppose that the login module queried for a third parameter, "domain" which diff --git a/plugin/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c index 0454ee1..bd71792 100644 --- a/plugin/auth-pam/auth-pam.c +++ b/src/plugins/auth-pam/auth-pam.c @@ -26,12 +26,14 @@ * OpenVPN plugin module to do PAM authentication using a split * privilege model. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif -#if DLOPEN_PAM -#include <dlfcn.h> -#include "pamdl.h" -#else #include <security/pam_appl.h> + +#ifdef USE_PAM_DLOPEN +#include "pamdl.h" #endif #include <stdio.h> @@ -46,7 +48,7 @@ #include <signal.h> #include <syslog.h> -#include "openvpn-plugin.h" +#include <openvpn-plugin.h> #define DEBUG(verb) ((verb) >= 4) @@ -81,6 +83,7 @@ struct auth_pam_context * * "USERNAME" -- substitute client-supplied username * "PASSWORD" -- substitute client-specified password + * "COMMONNAME" -- substitute client certificate common name */ #define N_NAME_VALUE 16 @@ -104,6 +107,7 @@ struct user_pass { char username[128]; char password[128]; + char common_name[128]; const struct name_value_list *name_value_list; }; @@ -470,12 +474,14 @@ openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const ch /* get username/password from envp string array */ const char *username = get_env ("username", envp); const char *password = get_env ("password", envp); + const char *common_name = get_env ("common_name", envp) ? get_env ("common_name", envp) : ""; if (username && strlen (username) > 0 && password) { if (send_control (context->foreground_fd, COMMAND_VERIFY) == -1 || send_string (context->foreground_fd, username) == -1 - || send_string (context->foreground_fd, password) == -1) + || send_string (context->foreground_fd, password) == -1 + || send_string (context->foreground_fd, common_name) == -1) { fprintf (stderr, "AUTH-PAM: Error sending auth info to background process\n"); } @@ -592,6 +598,8 @@ my_conv (int n, const struct pam_message **msg_array, aresp[i].resp = searchandreplace(match_value, "USERNAME", up->username); else if (strstr(match_value, "PASSWORD")) aresp[i].resp = searchandreplace(match_value, "PASSWORD", up->password); + else if (strstr(match_value, "COMMONNAME")) + aresp[i].resp = searchandreplace(match_value, "COMMONNAME", up->common_name); else aresp[i].resp = strdup (match_value); @@ -687,7 +695,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list { struct user_pass up; int command; -#if DLOPEN_PAM +#ifdef USE_PAM_DLOPEN static const char pam_so[] = "libpam.so"; #endif @@ -697,7 +705,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list if (DEBUG (verb)) fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service); -#if DLOPEN_PAM +#ifdef USE_PAM_DLOPEN /* * Load PAM shared object */ @@ -737,7 +745,8 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list { case COMMAND_VERIFY: if (recv_string (fd, up.username, sizeof (up.username)) == -1 - || recv_string (fd, up.password, sizeof (up.password)) == -1) + || recv_string (fd, up.password, sizeof (up.password)) == -1 + || recv_string (fd, up.common_name, sizeof (up.common_name)) == -1) { fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel: code=%d, exiting\n", command); @@ -787,7 +796,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list } done: -#if DLOPEN_PAM +#ifdef USE_PAM_DLOPEN dlclose_pam (); #endif if (DEBUG (verb)) diff --git a/src/plugins/auth-pam/auth-pam.exports b/src/plugins/auth-pam/auth-pam.exports new file mode 100644 index 0000000..b07937c --- /dev/null +++ b/src/plugins/auth-pam/auth-pam.exports @@ -0,0 +1,4 @@ +openvpn_plugin_open_v1 +openvpn_plugin_func_v1 +openvpn_plugin_close_v1 +openvpn_plugin_abort_v1 diff --git a/plugin/auth-pam/pamdl.c b/src/plugins/auth-pam/pamdl.c index 8636a8e..26e9821 100644 --- a/plugin/auth-pam/pamdl.c +++ b/src/plugins/auth-pam/pamdl.c @@ -1,4 +1,8 @@ -#if DLOPEN_PAM +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef USE_PAM_DLOPEN /* * If you want to dynamically load libpam using dlopen() or something, * then dlopen( ' this shared object ' ); It takes care of exporting @@ -73,7 +77,7 @@ int pam_set_item(pam_handle_t *pamh, int item_type, const void *item) return real_pam_set_item(pamh, item_type, item); } -int pam_get_item(pam_handle_t *pamh, int item_type, const void **item) +int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item) { int (*real_pam_get_item)(const pam_handle_t *, int, const void **); RESOLVE_PAM_FUNCTION(pam_get_item, int, diff --git a/plugin/auth-pam/pamdl.h b/src/plugins/auth-pam/pamdl.h index b10b035..12ba068 100644 --- a/plugin/auth-pam/pamdl.h +++ b/src/plugins/auth-pam/pamdl.h @@ -1,6 +1,4 @@ -#if DLOPEN_PAM -#include <security/pam_appl.h> - +#ifdef USE_PAM_DLOPEN /* Dynamically load and unload the PAM library */ int dlopen_pam (const char *so); void dlclose_pam (void); diff --git a/src/plugins/down-root/Makefile.am b/src/plugins/down-root/Makefile.am new file mode 100644 index 0000000..064aa30 --- /dev/null +++ b/src/plugins/down-root/Makefile.am @@ -0,0 +1,23 @@ +# +# OpenVPN (TM) Down Root Plugin -- OpenVPN Plugin +# +# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +AM_CFLAGS = \ + -I$(top_srcdir)/include + +if ENABLE_PLUGIN_DOWN_ROOT +plugin_LTLIBRARIES = openvpn-plugin-down-root.la +dist_doc_DATA = README.down-root +endif + +openvpn_plugin_down_root_la_SOURCES = \ + down-root.c \ + down-root.exports +openvpn_plugin_down_root_la_LDFLAGS = $(AM_LDFLAGS) \ + -export-symbols "$(srcdir)/down-root.exports" \ + -module -shared -avoid-version -no-undefined diff --git a/src/plugins/down-root/Makefile.in b/src/plugins/down-root/Makefile.in new file mode 100644 index 0000000..2f95e42 --- /dev/null +++ b/src/plugins/down-root/Makefile.in @@ -0,0 +1,612 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# OpenVPN (TM) Down Root Plugin -- OpenVPN Plugin +# +# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + + +VPATH = @srcdir@ +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 = src/plugins/down-root +DIST_COMMON = $(am__dist_doc_DATA_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +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 +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(docdir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +openvpn_plugin_down_root_la_LIBADD = +am_openvpn_plugin_down_root_la_OBJECTS = down-root.lo +openvpn_plugin_down_root_la_OBJECTS = \ + $(am_openvpn_plugin_down_root_la_OBJECTS) +openvpn_plugin_down_root_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(openvpn_plugin_down_root_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@ENABLE_PLUGIN_DOWN_ROOT_TRUE@am_openvpn_plugin_down_root_la_rpath = \ +@ENABLE_PLUGIN_DOWN_ROOT_TRUE@ -rpath $(plugindir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(openvpn_plugin_down_root_la_SOURCES) +DIST_SOURCES = $(openvpn_plugin_down_root_la_SOURCES) +am__dist_doc_DATA_DIST = README.down-root +DATA = $(dist_doc_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +AM_CFLAGS = \ + -I$(top_srcdir)/include + +@ENABLE_PLUGIN_DOWN_ROOT_TRUE@plugin_LTLIBRARIES = openvpn-plugin-down-root.la +@ENABLE_PLUGIN_DOWN_ROOT_TRUE@dist_doc_DATA = README.down-root +openvpn_plugin_down_root_la_SOURCES = \ + down-root.c \ + down-root.exports + +openvpn_plugin_down_root_la_LDFLAGS = $(AM_LDFLAGS) \ + -export-symbols "$(srcdir)/down-root.exports" \ + -module -shared -avoid-version -no-undefined + +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) --gnu src/plugins/down-root/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/plugins/down-root/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): +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +openvpn-plugin-down-root.la: $(openvpn_plugin_down_root_la_OBJECTS) $(openvpn_plugin_down_root_la_DEPENDENCIES) + $(openvpn_plugin_down_root_la_LINK) $(am_openvpn_plugin_down_root_la_rpath) $(openvpn_plugin_down_root_la_OBJECTS) $(openvpn_plugin_down_root_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/down-root.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(docdir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-dist_docDATA install-pluginLTLIBRARIES + +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: uninstall-dist_docDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES ctags 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-dist_docDATA 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-pluginLTLIBRARIES 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 uninstall uninstall-am \ + uninstall-dist_docDATA uninstall-pluginLTLIBRARIES + + +# 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/plugin/down-root/README b/src/plugins/down-root/README.down-root index d337ffe..d337ffe 100644 --- a/plugin/down-root/README +++ b/src/plugins/down-root/README.down-root diff --git a/plugin/down-root/down-root.c b/src/plugins/down-root/down-root.c index fced23b..d51d0e5 100644 --- a/plugin/down-root/down-root.c +++ b/src/plugins/down-root/down-root.c @@ -26,6 +26,10 @@ * OpenVPN plugin module to do privileged down-script execution. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <stdio.h> #include <string.h> #include <unistd.h> @@ -37,7 +41,7 @@ #include <signal.h> #include <syslog.h> -#include "openvpn-plugin.h" +#include <openvpn-plugin.h> #define DEBUG(verb) ((verb) >= 7) diff --git a/src/plugins/down-root/down-root.exports b/src/plugins/down-root/down-root.exports new file mode 100644 index 0000000..b07937c --- /dev/null +++ b/src/plugins/down-root/down-root.exports @@ -0,0 +1,4 @@ +openvpn_plugin_open_v1 +openvpn_plugin_func_v1 +openvpn_plugin_close_v1 +openvpn_plugin_abort_v1 @@ -1,849 +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 - */ - -#ifndef OPENVPN_SSL_H -#define OPENVPN_SSL_H - -#if defined(USE_CRYPTO) && defined(USE_SSL) - -#include <openssl/ssl.h> -#include <openssl/bio.h> -#include <openssl/rand.h> -#include <openssl/err.h> -#include <openssl/pkcs12.h> -#include <openssl/x509v3.h> - -#include "basic.h" -#include "common.h" -#include "crypto.h" -#include "packet_id.h" -#include "session_id.h" -#include "reliable.h" -#include "socket.h" -#include "mtu.h" -#include "options.h" -#include "plugin.h" - -/* - * OpenVPN Protocol, taken from ssl.h in OpenVPN source code. - * - * TCP/UDP Packet: This represents the top-level encapsulation. - * - * TCP/UDP packet format: - * - * Packet length (16 bits, unsigned) -- TCP only, always sent as - * plaintext. Since TCP is a stream protocol, the packet - * length words define the packetization of the stream. - * - * Packet opcode/key_id (8 bits) -- TLS only, not used in - * pre-shared secret mode. - * packet message type, a P_* constant (high 5 bits) - * key_id (low 3 bits, see key_id in struct tls_session - * below for comment). The key_id refers to an - * already negotiated TLS session. OpenVPN seamlessly - * renegotiates the TLS session by using a new key_id - * for the new session. Overlap (controlled by - * user definable parameters) between old and new TLS - * sessions is allowed, providing a seamless transition - * during tunnel operation. - * - * Payload (n bytes), which may be a P_CONTROL, P_ACK, or P_DATA - * message. - * - * Message types: - * - * P_CONTROL_HARD_RESET_CLIENT_V1 -- Key method 1, initial key from - * client, forget previous state. - * - * P_CONTROL_HARD_RESET_SERVER_V1 -- Key method 2, initial key - * from server, forget previous state. - * - * P_CONTROL_SOFT_RESET_V1 -- New key, with a graceful transition - * from old to new key in the sense that a transition window - * exists where both the old or new key_id can be used. OpenVPN - * uses two different forms of key_id. The first form is 64 bits - * and is used for all P_CONTROL messages. P_DATA messages on the - * other hand use a shortened key_id of 3 bits for efficiency - * reasons since the vast majority of OpenVPN packets in an - * active tunnel will be P_DATA messages. The 64 bit form - * is referred to as a session_id, while the 3 bit form is - * referred to as a key_id. - * - * P_CONTROL_V1 -- Control channel packet (usually TLS ciphertext). - * - * P_ACK_V1 -- Acknowledgement for P_CONTROL packets received. - * - * P_DATA_V1 -- Data channel packet containing actual tunnel data - * ciphertext. - * - * P_CONTROL_HARD_RESET_CLIENT_V2 -- Key method 2, initial key from - * client, forget previous state. - * - * P_CONTROL_HARD_RESET_SERVER_V2 -- Key method 2, initial key from - * server, forget previous state. - * - * P_CONTROL* and P_ACK Payload: The P_CONTROL message type - * indicates a TLS ciphertext packet which has been encapsulated - * inside of a reliability layer. The reliability layer is - * implemented as a straightforward ACK and retransmit model. - * - * P_CONTROL message format: - * - * local session_id (random 64 bit value to identify TLS session). - * HMAC signature of entire encapsulation header for integrity - * check if --tls-auth is specified (usually 16 or 20 bytes). - * packet-id for replay protection (4 or 8 bytes, includes - * sequence number and optional time_t timestamp). - * P_ACK packet_id array length (1 byte). - * P_ACK packet-id array (if length > 0). - * P_ACK remote session_id (if length > 0). - * message packet-id (4 bytes). - * TLS payload ciphertext (n bytes) (only for P_CONTROL). - * - * Once the TLS session has been initialized and authenticated, - * the TLS channel is used to exchange random key material for - * bidirectional cipher and HMAC keys which will be - * used to secure actual tunnel packets. OpenVPN currently - * implements two key methods. Key method 1 directly - * derives keys using random bits obtained from the RAND_bytes - * OpenSSL function. Key method 2 mixes random key material - * from both sides of the connection using the TLS PRF mixing - * function. Key method 2 is the preferred method and is the default - * for OpenVPN 2.0. - * - * TLS plaintext content: - * - * TLS plaintext packet (if key_method == 1): - * - * Cipher key length in bytes (1 byte). - * Cipher key (n bytes). - * HMAC key length in bytes (1 byte). - * HMAC key (n bytes). - * Options string (n bytes, null terminated, client/server options - * string should match). - * - * TLS plaintext packet (if key_method == 2): - * - * Literal 0 (4 bytes). - * key_method type (1 byte). - * key_source structure (pre_master only defined for client -> - * server). - * options_string_length, including null (2 bytes). - * Options string (n bytes, null terminated, client/server options - * string must match). - * [The username/password data below is optional, record can end - * at this point.] - * username_string_length, including null (2 bytes). - * Username string (n bytes, null terminated). - * password_string_length, including null (2 bytes). - * Password string (n bytes, null terminated). - * - * The P_DATA payload represents encrypted, encapsulated tunnel - * packets which tend to be either IP packets or Ethernet frames. - * This is essentially the "payload" of the VPN. - * - * P_DATA message content: - * HMAC of ciphertext IV + ciphertext (if not disabled by - * --auth none). - * Ciphertext IV (size is cipher-dependent, if not disabled by - * --no-iv). - * Tunnel packet ciphertext. - * - * P_DATA plaintext - * packet_id (4 or 8 bytes, if not disabled by --no-replay). - * In SSL/TLS mode, 4 bytes are used because the implementation - * can force a TLS renegotation before 2^32 packets are sent. - * In pre-shared key mode, 8 bytes are used (sequence number - * and time_t value) to allow long-term key usage without - * packet_id collisions. - * User plaintext (n bytes). - * - * Notes: - * (1) ACK messages can be encoded in either the dedicated - * P_ACK record or they can be prepended to a P_CONTROL message. - * (2) P_DATA and P_CONTROL/P_ACK use independent packet-id - * sequences because P_DATA is an unreliable channel while - * P_CONTROL/P_ACK is a reliable channel. Each use their - * own independent HMAC keys. - * (3) Note that when --tls-auth is used, all message types are - * protected with an HMAC signature, even the initial packets - * of the TLS handshake. This makes it easy for OpenVPN to - * throw away bogus packets quickly, without wasting resources - * on attempting a TLS handshake which will ultimately fail. - */ - -/* Used in the TLS PRF function */ -#define KEY_EXPANSION_ID "OpenVPN" - -/* passwords */ -#define UP_TYPE_AUTH "Auth" -#define UP_TYPE_PRIVATE_KEY "Private Key" - -/* packet opcode (high 5 bits) and key-id (low 3 bits) are combined in one byte */ -#define P_KEY_ID_MASK 0x07 -#define P_OPCODE_SHIFT 3 - -/* packet opcodes -- the V1 is intended to allow protocol changes in the future */ -#define P_CONTROL_HARD_RESET_CLIENT_V1 1 /* initial key from client, forget previous state */ -#define P_CONTROL_HARD_RESET_SERVER_V1 2 /* initial key from server, forget previous state */ -#define P_CONTROL_SOFT_RESET_V1 3 /* new key, graceful transition from old to new key */ -#define P_CONTROL_V1 4 /* control channel packet (usually TLS ciphertext) */ -#define P_ACK_V1 5 /* acknowledgement for packets received */ -#define P_DATA_V1 6 /* data channel packet */ - -/* indicates key_method >= 2 */ -#define P_CONTROL_HARD_RESET_CLIENT_V2 7 /* initial key from client, forget previous state */ -#define P_CONTROL_HARD_RESET_SERVER_V2 8 /* initial key from server, forget previous state */ - -/* define the range of legal opcodes */ -#define P_FIRST_OPCODE 1 -#define P_LAST_OPCODE 8 - -/* key negotiation states */ -#define S_ERROR -1 -#define S_UNDEF 0 -#define S_INITIAL 1 /* tls_init() was called */ -#define S_PRE_START 2 /* waiting for initial reset & acknowledgement */ -#define S_START 3 /* ready to exchange keys */ -#define S_SENT_KEY 4 /* client does S_SENT_KEY -> S_GOT_KEY */ -#define S_GOT_KEY 5 /* server does S_GOT_KEY -> S_SENT_KEY */ -#define S_ACTIVE 6 /* ready to exchange data channel packets */ -#define S_NORMAL_OP 7 /* normal operations */ - -/* - * Are we ready to receive data channel packets? - * - * Also, if true, we can safely assume session has been - * authenticated by TLS. - * - * NOTE: Assumes S_SENT_KEY + 1 == S_GOT_KEY. - */ -#define DECRYPT_KEY_ENABLED(multi, ks) ((ks)->state >= (S_GOT_KEY - (multi)->opt.server)) - -/* Should we aggregate TLS acknowledgements, and tack them onto control packets? */ -#define TLS_AGGREGATE_ACK - -/* - * If TLS_AGGREGATE_ACK, set the - * max number of acknowledgments that - * can "hitch a ride" on an outgoing - * non-P_ACK_V1 control packet. - */ -#define CONTROL_SEND_ACK_MAX 4 - -/* - * Define number of buffers for send and receive in the reliability layer. - */ -#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliablity layer */ -#define TLS_RELIABLE_N_REC_BUFFERS 8 - -/* - * Various timeouts - */ - -#define TLS_MULTI_REFRESH 15 /* call tls_multi_process once every n seconds */ -#define TLS_MULTI_HORIZON 2 /* call tls_multi_process frequently for n seconds after - every packet sent/received action */ - -/* The SSL/TLS worker thread will wait at most this many seconds for the interprocess - communication pipe to the main thread to be ready to accept writes. */ -#define TLS_MULTI_THREAD_SEND_TIMEOUT 5 - -/* Interval that tls_multi_process should call tls_authentication_status */ -#define TLS_MULTI_AUTH_STATUS_INTERVAL 10 - -/* - * Buffer sizes (also see mtu.h). - */ - -/* Maximum length of the username in cert */ -#define TLS_USERNAME_LEN 64 - -/* Legal characters in an X509 or common name */ -#define X509_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_COLON|CC_SLASH|CC_EQUAL) -#define COMMON_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_SLASH) - -/* Maximum length of OCC options string passed as part of auth handshake */ -#define TLS_OPTIONS_LEN 512 - -/* Default field in X509 to be username */ -#define X509_USERNAME_FIELD_DEFAULT "CN" - -/* - * Range of key exchange methods - */ -#define KEY_METHOD_MIN 1 -#define KEY_METHOD_MAX 2 - -/* key method taken from lower 4 bits */ -#define KEY_METHOD_MASK 0x0F - -/* - * Measure success rate of TLS handshakes, for debugging only - */ -/* #define MEASURE_TLS_HANDSHAKE_STATS */ - -/* - * Keep track of certificate hashes at various depths - */ - -/* Maximum certificate depth we will allow */ -#define MAX_CERT_DEPTH 16 - -struct cert_hash { - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; -}; - -struct cert_hash_set { - struct cert_hash *ch[MAX_CERT_DEPTH]; -}; - -/* - * Key material, used as source for PRF-based - * key expansion. - */ - -struct key_source { - uint8_t pre_master[48]; /* client generated */ - uint8_t random1[32]; /* generated by both client and server */ - uint8_t random2[32]; /* generated by both client and server */ -}; - -struct key_source2 { - struct key_source client; - struct key_source server; -}; - -/* - * Represents a single instantiation of a TLS negotiation and - * data channel key exchange. 4 keys are kept: encrypt hmac, - * decrypt hmac, encrypt cipher, and decrypt cipher. The TLS - * control channel is used to exchange these keys. - * Each hard or soft reset will build - * a fresh key_state. Normally an openvpn session will contain two - * key_state objects, one for the current TLS connection, and other - * for the retiring or "lame duck" key. The lame duck key_state is - * used to maintain transmission continuity on the data-channel while - * a key renegotiation is taking place. - */ -struct key_state -{ - int state; - int key_id; /* inherited from struct tls_session below */ - - SSL *ssl; /* SSL object -- new obj created for each new key */ - BIO *ssl_bio; /* read/write plaintext from here */ - BIO *ct_in; /* write ciphertext to here */ - BIO *ct_out; /* read ciphertext from here */ - - time_t established; /* when our state went S_ACTIVE */ - time_t must_negotiate; /* key negotiation times out if not finished before this time */ - time_t must_die; /* this object is destroyed at this time */ - - 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 key_source2 *key_src; /* source entropy for key expansion */ - - struct buffer plaintext_read_buf; - struct buffer plaintext_write_buf; - struct buffer ack_write_buf; - - struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */ - struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ - struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ - - struct buffer_list *paybuf; - - counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */ - counter_type n_packets; /* how many packets sent/recvd since last key exchange */ - - /* - * If bad username/password, TLS connection will come up but 'authenticated' will be false. - */ - bool authenticated; - time_t auth_deferred_expire; - -#ifdef ENABLE_DEF_AUTH - /* If auth_deferred is true, authentication is being deferred */ - bool auth_deferred; -#ifdef MANAGEMENT_DEF_AUTH - unsigned int mda_key_id; - unsigned int mda_status; -#endif -#ifdef PLUGIN_DEF_AUTH - unsigned int auth_control_status; - time_t acf_last_mod; - char *auth_control_file; -#endif -#endif -}; - -/* - * Our const options, obtained directly or derived from - * command line options. - */ -struct tls_options -{ - /* our master SSL_CTX from which all SSL objects derived */ - SSL_CTX *ssl_ctx; - - /* data channel cipher, hmac, and key lengths */ - struct key_type key_type; - - /* true if we are a TLS server, client otherwise */ - bool server; - - /* if true, don't xmit until first packet from peer is received */ - bool xmit_hold; - -#ifdef ENABLE_OCC - /* local and remote options strings - that must match between client and server */ - const char *local_options; - const char *remote_options; -#endif - - /* from command line */ - int key_method; - bool replay; - bool single_session; -#ifdef ENABLE_OCC - bool disable_occ; -#endif -#ifdef ENABLE_PUSH_PEER_INFO - bool push_peer_info; -#endif - int transition_window; - int handshake_window; - interval_t packet_timeout; - int renegotiate_bytes; - int renegotiate_packets; - interval_t renegotiate_seconds; - - /* cert verification parms */ - const char *verify_command; - const char *verify_export_cert; - const char *verify_x509name; - const char *crl_file; - int ns_cert_type; - unsigned remote_cert_ku[MAX_PARMS]; - const char *remote_cert_eku; - - /* allow openvpn config info to be - passed over control channel */ - bool pass_config_info; - - /* struct crypto_option flags */ - unsigned int crypto_flags_and; - unsigned int crypto_flags_or; - - int replay_window; /* --replay-window parm */ - int replay_time; /* --replay-window parm */ - - /* packet authentication for TLS handshake */ - struct crypto_options tls_auth; - struct key_ctx_bi tls_auth_key; - - /* frame parameters for TLS control channel */ - struct frame frame; - - /* used for username/password authentication */ - const char *auth_user_pass_verify_script; - bool auth_user_pass_verify_script_via_file; - const char *tmp_dir; - - /* use the client-config-dir as a positive authenticator */ - const char *client_config_dir_exclusive; - - /* instance-wide environment variable set */ - struct env_set *es; - const struct plugin_list *plugins; - - /* configuration file boolean 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_NO_NAME_REMAPPING (1<<3) -# define SSLF_OPT_VERIFY (1<<4) - unsigned int ssl_flags; - -#ifdef MANAGEMENT_DEF_AUTH - struct man_def_auth_context *mda_context; -#endif - - /* --gremlin bits */ - int gremlin; -}; - -/* index into tls_session.key */ -#define KS_PRIMARY 0 /* the primary key */ -#define KS_LAME_DUCK 1 /* the key that's going to retire soon */ -#define KS_SIZE 2 - -/* - * A tls_session lives through multiple key_state life-cycles. Soft resets - * will reuse a tls_session object, but hard resets or errors will require - * that a fresh object be built. Normally three tls_session objects are maintained - * by an active openvpn session. The first is the current, TLS authenticated - * session, the second is used to process connection requests from a new - * client that would usurp the current session if successfully authenticated, - * and the third is used as a repository for a "lame-duck" key in the event - * that the primary session resets due to error while the lame-duck key still - * has time left before its expiration. Lame duck keys are used to maintain - * the continuity of the data channel connection while a new key is being - * negotiated. - */ -struct tls_session -{ - /* const options and config info */ - const struct tls_options *opt; - - /* during hard reset used to control burst retransmit */ - bool burst; - - /* authenticate control packets */ - struct crypto_options tls_auth; - struct packet_id tls_auth_pid; - - 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) */ - - int limit_next; /* used for traffic shaping on the control channel */ - - int verify_maxlevel; - - char *common_name; - - struct cert_hash_set *cert_hash_set; - -#ifdef ENABLE_PF - uint32_t common_name_hashval; -#endif - - bool verified; /* true if peer certificate was verified against CA */ - - /* not-yet-authenticated incoming client */ - struct link_socket_actual untrusted_addr; - - struct key_state key[KS_SIZE]; -}; - -/* index into tls_multi.session */ -#define TM_ACTIVE 0 -#define TM_UNTRUSTED 1 -#define TM_LAME_DUCK 2 -#define TM_SIZE 3 - -/* - * The number of keys we will scan on encrypt or decrypt. The first - * is the "active" key. The second is the lame_duck or retiring key - * associated with the active key's session ID. The third is a detached - * lame duck session that only occurs in situations where a key renegotiate - * failed on the active key, but a lame duck key was still valid. By - * preserving the lame duck session, we can be assured of having a data - * channel key available even when network conditions are so bad that - * we can't negotiate a new key within the time allotted. - */ -#define KEY_SCAN_SIZE 3 - -/* - * An openvpn session running with TLS enabled has one tls_multi object. - */ -struct tls_multi -{ - /* const options and config info */ - struct tls_options opt; - - /* - * A list of key_state objects in the order they should be - * scanned by data channel encrypt and decrypt routines. - */ - struct key_state* key_scan[KEY_SCAN_SIZE]; - - /* - * used by tls_pre_encrypt to communicate the encrypt key - * to tls_post_encrypt() - */ - struct key_state *save_ks; /* temporary pointer used between pre/post routines */ - - /* - * Used to return outgoing address from - * tls_multi_process. - */ - struct link_socket_actual to_link_addr; - - /* - * Number of sessions negotiated thus far. - */ - int n_sessions; - - /* - * Number of errors. - */ - int n_hard_errors; /* errors due to TLS negotiation failure */ - int n_soft_errors; /* errors due to unrecognized or failed-to-authenticate incoming packets */ - - /* - * Our locked common name, username, and cert hashes (cannot change during the life of this tls_multi object) - */ - char *locked_cn; - char *locked_username; - struct cert_hash_set *locked_cert_hash_set; - -#ifdef ENABLE_DEF_AUTH - /* - * An error message to send to client on AUTH_FAILED - */ - char *client_reason; - - /* - * 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 - - /* - * Our session objects. - */ - struct tls_session session[TM_SIZE]; -}; - -/* - * Used in --mode server mode to check tls-auth signature on initial - * packets received from new clients. - */ -struct tls_auth_standalone -{ - struct key_ctx_bi tls_auth_key; - struct crypto_options tls_auth_options; - struct frame frame; -}; - -void init_ssl_lib (void); -void free_ssl_lib (void); - -/* Build master SSL_CTX object that serves for the whole of openvpn instantiation */ -SSL_CTX *init_ssl (const struct options *options); - -struct tls_multi *tls_multi_init (struct tls_options *tls_options); - -struct tls_auth_standalone *tls_auth_standalone_init (struct tls_options *tls_options, - struct gc_arena *gc); - -void tls_auth_standalone_finalize (struct tls_auth_standalone *tas, - const struct frame *frame); - -void tls_multi_init_finalize(struct tls_multi *multi, - const struct frame *frame); - -void tls_multi_init_set_options(struct tls_multi* multi, - const char *local, - const char *remote); - -#define TLSMP_INACTIVE 0 -#define TLSMP_ACTIVE 1 -#define TLSMP_KILL 2 -int tls_multi_process (struct tls_multi *multi, - struct buffer *to_link, - struct link_socket_actual **to_link_addr, - struct link_socket_info *to_link_socket_info, - interval_t *wakeup); - -void tls_multi_free (struct tls_multi *multi, bool clear); - -bool tls_pre_decrypt (struct tls_multi *multi, - const struct link_socket_actual *from, - struct buffer *buf, - struct crypto_options *opt); - -bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas, - const struct link_socket_actual *from, - const struct buffer *buf); - -void tls_pre_encrypt (struct tls_multi *multi, - struct buffer *buf, struct crypto_options *opt); - -void tls_post_encrypt (struct tls_multi *multi, struct buffer *buf); - -void show_available_tls_ciphers (void); -void get_highest_preference_tls_cipher (char *buf, int size); - -void pem_password_setup (const char *auth_file); -int pem_password_callback (char *buf, int size, int rwflag, void *u); -void auth_user_pass_setup (const char *auth_file); -void ssl_set_auth_nocache (void); -void ssl_purge_auth (void); - - -#ifdef ENABLE_CLIENT_CR -/* - * ssl_get_auth_challenge will parse the server-pushed auth-failed - * reason string and return a dynamically allocated - * auth_challenge_info struct. - */ -void ssl_purge_auth_challenge (void); -void ssl_put_auth_challenge (const char *cr_str); -#endif - -void tls_set_verify_command (const char *cmd); -void tls_set_crl_verify (const char *crl); -void tls_set_verify_x509name (const char *x509name); - -void tls_adjust_frame_parameters(struct frame *frame); - -bool tls_send_payload (struct tls_multi *multi, - const uint8_t *data, - int size); - -bool tls_rec_payload (struct tls_multi *multi, - struct buffer *buf); - -const char *tls_common_name (const struct tls_multi* multi, const bool null); -void tls_set_common_name (struct tls_multi *multi, const char *common_name); -void tls_lock_common_name (struct tls_multi *multi); -void tls_lock_cert_hash_set (struct tls_multi *multi); - -#define TLS_AUTHENTICATION_SUCCEEDED 0 -#define TLS_AUTHENTICATION_FAILED 1 -#define TLS_AUTHENTICATION_DEFERRED 2 -#define TLS_AUTHENTICATION_UNDEFINED 3 -int tls_authentication_status (struct tls_multi *multi, const int latency); -void tls_deauthenticate (struct tls_multi *multi); - -#ifdef MANAGEMENT_DEF_AUTH -bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason); - -static inline char * -tls_get_peer_info(const struct tls_multi *multi) -{ - return multi->peer_info; -} -#endif - -/* - * inline functions - */ - -static inline bool -tls_initial_packet_received (const struct tls_multi *multi) -{ - return multi->n_sessions > 0; -} - -static inline bool -tls_test_auth_deferred_interval (const struct tls_multi *multi) -{ - if (multi) - { - const struct key_state *ks = &multi->session[TM_ACTIVE].key[KS_PRIMARY]; - return now < ks->auth_deferred_expire; - } - return false; -} - -static inline int -tls_test_payload_len (const struct tls_multi *multi) -{ - if (multi) - { - const struct key_state *ks = &multi->session[TM_ACTIVE].key[KS_PRIMARY]; - if (ks->state >= S_ACTIVE) - return BLEN (&ks->plaintext_read_buf); - } - return 0; -} - -static inline void -tls_set_single_session (struct tls_multi *multi) -{ - if (multi) - multi->opt.single_session = true; -} - -static inline const char * -tls_client_reason (struct tls_multi *multi) -{ -#ifdef ENABLE_DEF_AUTH - return multi->client_reason; -#else - return NULL; -#endif -} - -#ifdef ENABLE_PF - -static inline bool -tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t *cn_hash) -{ - if (multi) - { - const struct tls_session *s = &multi->session[TM_ACTIVE]; - if (s->common_name && s->common_name[0] != '\0') - { - *cn = s->common_name; - *cn_hash = s->common_name_hashval; - return true; - } - } - return false; -} - -#endif - -/* - * protocol_dump() flags - */ -#define PD_TLS_AUTH_HMAC_SIZE_MASK 0xFF -#define PD_SHOW_DATA (1<<8) -#define PD_TLS (1<<9) -#define PD_VERBOSE (1<<10) - -const char *protocol_dump (struct buffer *buffer, - unsigned int flags, - struct gc_arena *gc); - -/* - * debugging code - */ - -#ifdef MEASURE_TLS_HANDSHAKE_STATS -void show_tls_performance_stats(void); -#endif - -/*#define EXTRACT_X509_FIELD_TEST*/ -void extract_x509_field_test (void); - -#endif /* USE_CRYPTO && USE_SSL */ - -#endif diff --git a/tap-win32/MAKEFILE b/tap-win32/MAKEFILE deleted file mode 100755 index 6ee4f43..0000000 --- a/tap-win32/MAKEFILE +++ /dev/null @@ -1,6 +0,0 @@ -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the components of NT OS/2 -# -!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/tap-win32/SOURCES.in b/tap-win32/SOURCES.in deleted file mode 100755 index cf030f4..0000000 --- a/tap-win32/SOURCES.in +++ /dev/null @@ -1,64 +0,0 @@ -# Build TAP-Win32 driver. -# Build Command: build -cef - -MAJORCOMP=ntos -MINORCOMP=ndis - -TARGETNAME=@@PRODUCT_TAP_ID@@ -TARGETTYPE=DRIVER -TARGETPATH=. -TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib $(DDK_LIB_PATH)\ntstrsafe.lib -INCLUDES=$(DDK_INCLUDE_PATH) .. - -# The TAP version numbers here must be >= -# PRODUCT_TAP_WIN32_MIN_x values defined in version.m4 -C_DEFINES= -C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MAJOR_VERSION=@@PRODUCT_TAP_MAJOR_VER@@ -C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MINOR_VERSION=@@PRODUCT_TAP_MINOR_VER@@ - -# Produce the same symbolic information for both free & checked builds. -# This will allow us to perform full source-level debugging on both -# builds without affecting the free build's performance. -!IF "$(DDKBUILDENV)" != "chk" -NTDEBUGTYPE=both -USE_PDB=1 -!ELSE -NTDEBUGTYPE=both -USE_PDB=1 -!ENDIF - -# Set compiler optimizations: -# /Ox - Full optimization enabled -# /Os - favor speed over size when optimizing -# /Od - Disable all optimizations -# /Oi - Enable optimization for intrinsic functions -# /Fc - Generate mixed assembler/source code files -# -# For both checked and free builds, make sure that any intrinsic -# functions are compiled correctly. To do this, ensure that /Oi -# is selected for both free and checked builds. There is a bug in -# VC++ 6.0 (at least through SP4) where, if you specify any -# intrinsic functions in your code with "#pragma intrinsic" but -# you don't have the /Oi optimization enabled, neither a call -# to the function, nor the intrinsic inline version of the function -# will end up in your object code. This bug only applies to free -# builds, but just to be safe we'll make sure that the flag is -# enabled for all builds. - -!IF "$(DDKBUILDENV)" != "chk" -MSC_OPTIMIZATION=/Ox /Oi /Fc -!ELSE -MSC_OPTIMIZATION=/Od /Oi /Fc -!ENDIF - -# Generate a linker map file just in case we need one for debugging -LINKER_FLAGS=$(LINKER_FLAGS) /INCREMENTAL:NO /MAP /MAPINFO:EXPORTS - -# Generate a browser information file for use in IDE development -#BROWSER_INFO=1 -#BROWSERFILE=$(TARGETNAME).BSC -n - -# Abort compilation on warnings by adding /WX -MSC_WARNING_LEVEL=/W3 - -SOURCES=tapdrvr.c resource.rc diff --git a/tap-win32/common.h b/tap-win32/common.h deleted file mode 100755 index bb8ab90..0000000 --- a/tap-win32/common.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 is included both by OpenVPN and -// the TAP-Win32 driver and contains definitions -// common to both. -//=============================================== - -#ifndef HAVE_CONFIG_H -#include "autodefs.h" -#endif - -//============= -// TAP IOCTLs -//============= - -#define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) - -// Present in 8.1 - -#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) -#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) -#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) - -// Added in 8.2 - -/* obsoletes TAP_IOCTL_CONFIG_POINT_TO_POINT */ -#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE (10, METHOD_BUFFERED) - -//================= -// Registry keys -//================= - -#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -//====================== -// Filesystem prefixes -//====================== - -#define USERMODEDEVICEDIR "\\\\.\\Global\\" -#define SYSDEVICEDIR "\\Device\\" -#define USERDEVICEDIR "\\DosDevices\\Global\\" -#define TAPSUFFIX ".tap" - -//========================================================= -// TAP_COMPONENT_ID -- This string defines the TAP driver -// type -- different component IDs can reside in the system -// simultaneously. -//========================================================= - -#define TAP_COMPONENT_ID TAP_ID diff --git a/tap-win32/constants.h b/tap-win32/constants.h deleted file mode 100755 index 9bbd7ee..0000000 --- a/tap-win32/constants.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//==================================================================== -// Product and Version public settings -//==================================================================== - -#define PRODUCT_STRING PRODUCT_TAP_DEVICE_DESCRIPTION - -#define TAP_NDIS_MAJOR_VERSION 5 -#define TAP_NDIS_MINOR_VERSION 0 - -//=========================================================== -// Driver constants -//=========================================================== - -#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER)) -#define ETHERNET_MTU 1500 -#define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE) -#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE) - -#define NIC_MAX_MCAST_LIST 32 // Max length of multicast address list - -#define MINIMUM_MTU 576 // USE TCP Minimum MTU -#define MAXIMUM_MTU 65536 // IP maximum MTU - -#define PACKET_QUEUE_SIZE 64 // tap -> userspace queue size -#define IRP_QUEUE_SIZE 16 // max number of simultaneous i/o operations from userspace -#define INJECT_QUEUE_SIZE 16 // DHCP/ARP -> tap injection queue - -#define TAP_LITTLE_ENDIAN // affects ntohs, htonl, etc. functions diff --git a/tap-win32/dhcp.c b/tap-win32/dhcp.c deleted file mode 100755 index 3891d42..0000000 --- a/tap-win32/dhcp.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//========================= -// Code to set DHCP options -//========================= - -VOID -SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len) -{ - if (!m->overflow) - { - if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE) - { - if (len) - { - NdisMoveMemory (m->msg.options + m->optlen, data, len); - m->optlen += len; - } - } - else - { - m->overflow = TRUE; - } - } -} - -VOID -SetDHCPOpt0 (DHCPMsg *msg, int type) -{ - DHCPOPT0 opt; - opt.type = (UCHAR) type; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -VOID -SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data) -{ - DHCPOPT8 opt; - opt.type = (UCHAR) type; - opt.len = sizeof (opt.data); - opt.data = (UCHAR) data; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -VOID -SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data) -{ - DHCPOPT32 opt; - opt.type = (UCHAR) type; - opt.len = sizeof (opt.data); - opt.data = data; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -//============== -// Checksum code -//============== - -USHORT -ip_checksum (const UCHAR *buf, const int len_ip_header) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words in the packet - // and add them up - for (i = 0; i < len_ip_header - 1; i += 2) { - word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF); - sum += (ULONG) word16; - } - - // take only 16 bits out of the 32 bit sum and add up the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // one's complement the result - return ((USHORT) ~sum); -} - -USHORT -udp_checksum (const UCHAR *buf, - const int len_udp, - const UCHAR *src_addr, - const UCHAR *dest_addr) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words and - // calculate the sum of all 16 bit words - for (i = 0; i < len_udp; i += 2){ - word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0); - sum += word16; - } - - // add the UDP pseudo header which contains the IP source and destination addresses - for (i = 0; i < 4; i += 2){ - word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF); - sum += word16; - } - for (i = 0; i < 4; i += 2){ - word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF); - sum += word16; - } - - // the protocol number and the length of the UDP packet - sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp; - - // keep only the last 16 bits of the 32 bit calculated sum and add the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // Take the one's complement of sum - return ((USHORT) ~sum); -} - -//================================ -// Set IP and UDP packet checksums -//================================ - -VOID -SetChecksumDHCPMsg (DHCPMsg *m) -{ - // Set IP checksum - m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR))); - - // Set UDP Checksum - m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp, - sizeof (UDPHDR) + sizeof (DHCP) + m->optlen, - (UCHAR *)&m->msg.pre.ip.saddr, - (UCHAR *)&m->msg.pre.ip.daddr)); -} - -//=================== -// DHCP message tests -//=================== - -int -GetDHCPMessageType (const DHCP *dhcp, const int optlen) -{ - const UCHAR *p = (UCHAR *) (dhcp + 1); - int i; - - for (i = 0; i < optlen; ++i) - { - const UCHAR type = p[i]; - const int room = optlen - i - 1; - if (type == DHCP_END) // didn't find what we were looking for - return -1; - else if (type == DHCP_PAD) // no-operation - ; - else if (type == DHCP_MSG_TYPE) // what we are looking for - { - if (room >= 2) - { - if (p[i+1] == 1) // message length should be 1 - return p[i+2]; // return message type - } - return -1; - } - else // some other message - { - if (room >= 1) - { - const int len = p[i+1]; // get message length - i += (len + 1); // advance to next message - } - } - } - return -1; -} - -BOOLEAN -DHCPMessageOurs (const TapAdapterPointer p_Adapter, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp) -{ - // Must be UDPv4 protocol - if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP)) - return FALSE; - - // Source MAC must be our adapter - if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC)) - return FALSE; - - // Dest MAC must be either broadcast or our virtual DHCP server - if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast) - || MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac))) - return FALSE; - - // Port numbers must be correct - if (!(udp->dest == htons (BOOTPS_PORT) - && udp->source == htons (BOOTPC_PORT))) - return FALSE; - - // Hardware address must be MAC addr sized - if (!(dhcp->hlen == sizeof (MACADDR))) - return FALSE; - - // Hardware address must match our adapter - if (!MAC_EQUAL (eth->src, dhcp->chaddr)) - return FALSE; - - return TRUE; -} - - -//===================================================== -// Build all of DHCP packet except for DHCP options. -// Assume that *p has been zeroed before we are called. -//===================================================== - -VOID -BuildDHCPPre (const TapAdapterPointer a, - DHCPPre *p, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen, - const int type) -{ - // Should we broadcast or direct to a specific MAC / IP address? - const BOOLEAN broadcast = (type == DHCPNAK - || MAC_EQUAL (eth->dest, a->m_MAC_Broadcast)); - // Build ethernet header - - COPY_MAC (p->eth.src, a->m_dhcp_server_mac); - - if (broadcast) - COPY_MAC (p->eth.dest, a->m_MAC_Broadcast); - else - COPY_MAC (p->eth.dest, eth->src); - - p->eth.proto = htons (ETH_P_IP); - - // Build IP header - - p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2); - p->ip.tos = 0; - p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen); - p->ip.id = 0; - p->ip.frag_off = 0; - p->ip.ttl = 16; - p->ip.protocol = IPPROTO_UDP; - p->ip.check = 0; - p->ip.saddr = a->m_dhcp_server_ip; - - if (broadcast) - p->ip.daddr = ~0; - else - p->ip.daddr = a->m_dhcp_addr; - - // Build UDP header - - p->udp.source = htons (BOOTPS_PORT); - p->udp.dest = htons (BOOTPC_PORT); - p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen); - p->udp.check = 0; - - // Build DHCP response - - p->dhcp.op = BOOTREPLY; - p->dhcp.htype = 1; - p->dhcp.hlen = sizeof (MACADDR); - p->dhcp.hops = 0; - p->dhcp.xid = dhcp->xid; - p->dhcp.secs = 0; - p->dhcp.flags = 0; - p->dhcp.ciaddr = 0; - - if (type == DHCPNAK) - p->dhcp.yiaddr = 0; - else - p->dhcp.yiaddr = a->m_dhcp_addr; - - p->dhcp.siaddr = a->m_dhcp_server_ip; - p->dhcp.giaddr = 0; - COPY_MAC (p->dhcp.chaddr, eth->src); - p->dhcp.magic = htonl (0x63825363); -} -//============================= -// Build specific DHCP messages -//============================= - -VOID -SendDHCPMsg (const TapAdapterPointer a, - const int type, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp) -{ - DHCPMsg *pkt; - - if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK)) - { - DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type)); - return; - } - - pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE); - - if (pkt) - { - //----------------------- - // Build DHCP options - //----------------------- - - // Message Type - SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type); - - // Server ID - SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip); - - if (type == DHCPOFFER || type == DHCPACK) - { - // Lease Time - SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time)); - - // Netmask - SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask); - - // Other user-defined options - SetDHCPOpt (pkt, - a->m_dhcp_user_supplied_options_buffer, - a->m_dhcp_user_supplied_options_buffer_len); - } - - // End - SetDHCPOpt0 (pkt, DHCP_END); - - if (!DHCPMSG_OVERFLOW (pkt)) - { - // The initial part of the DHCP message (not including options) gets built here - BuildDHCPPre (a, - &pkt->msg.pre, - eth, - ip, - udp, - dhcp, - DHCPMSG_LEN_OPT (pkt), - type); - - SetChecksumDHCPMsg (pkt); - - DUMP_PACKET ("DHCPMsg", - DHCPMSG_BUF (pkt), - DHCPMSG_LEN_FULL (pkt)); - - // Return DHCP response to kernel - InjectPacketDeferred (a, - DHCPMSG_BUF (pkt), - DHCPMSG_LEN_FULL (pkt)); - } - else - { - DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n")); - } - - MemFree (pkt, sizeof (DHCPMsg)); - } -} - -//=================================================================== -// Handle a BOOTPS packet produced by the local system to -// resolve the address/netmask of this adapter. -// If we are in TAP_IOCTL_CONFIG_DHCP_MASQ mode, reply -// to the message. Return TRUE if we processed the passed -// message, so that downstream stages can ignore it. -//=================================================================== - -BOOLEAN -ProcessDHCP (TapAdapterPointer p_Adapter, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - int optlen) -{ - int msg_type; - - // Sanity check IP header - if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen - && (ntohs (ip->frag_off) & IP_OFFMASK) == 0)) - return TRUE; - - // Does this message belong to us? - if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp)) - return FALSE; - - msg_type = GetDHCPMessageType (dhcp, optlen); - - // Drop non-BOOTREQUEST messages - if (dhcp->op != BOOTREQUEST) - return TRUE; - - // Drop any messages except DHCPDISCOVER or DHCPREQUEST - if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST)) - return TRUE; - - // Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK? - if (msg_type == DHCPREQUEST - && ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) - || !p_Adapter->m_dhcp_received_discover - || p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD)) - SendDHCPMsg (p_Adapter, - DHCPNAK, - eth, ip, udp, dhcp); - else - SendDHCPMsg (p_Adapter, - (msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK), - eth, ip, udp, dhcp); - - // Remember if we received a DHCPDISCOVER - if (msg_type == DHCPDISCOVER) - p_Adapter->m_dhcp_received_discover = TRUE; - - // Is this a bad DHCPREQUEST? - if (msg_type == DHCPREQUEST && dhcp->ciaddr != p_Adapter->m_dhcp_addr) - ++p_Adapter->m_dhcp_bad_requests; - - return TRUE; -} - -#if DBG - -const char * -message_op_text (int op) -{ - switch (op) - { - case BOOTREQUEST: - return "BOOTREQUEST"; - case BOOTREPLY: - return "BOOTREPLY"; - default: - return "???"; - } -} - -const char * -message_type_text (int type) -{ - switch (type) - { - case DHCPDISCOVER: - return "DHCPDISCOVER"; - case DHCPOFFER: - return "DHCPOFFER"; - case DHCPREQUEST: - return "DHCPREQUEST"; - case DHCPDECLINE: - return "DHCPDECLINE"; - case DHCPACK: - return "DHCPACK"; - case DHCPNAK: - return "DHCPNAK"; - case DHCPRELEASE: - return "DHCPRELEASE"; - case DHCPINFORM: - return "DHCPINFORM"; - default: - return "???"; - } -} - -const char * -port_name (int port) -{ - switch (port) - { - case BOOTPS_PORT: - return "BOOTPS"; - case BOOTPC_PORT: - return "BOOTPC"; - default: - return "unknown"; - } -} - -VOID -DumpDHCP (const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen) -{ - DEBUGP ((" %s", message_op_text (dhcp->op))); - DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen)))); - PrIP (ip->saddr); - DEBUGP ((":%s[", port_name (ntohs (udp->source)))); - PrMac (eth->src); - DEBUGP (("] -> ")); - PrIP (ip->daddr); - DEBUGP ((":%s[", port_name (ntohs (udp->dest)))); - PrMac (eth->dest); - DEBUGP (("]")); - if (dhcp->ciaddr) - { - DEBUGP ((" ci=")); - PrIP (dhcp->ciaddr); - } - if (dhcp->yiaddr) - { - DEBUGP ((" yi=")); - PrIP (dhcp->yiaddr); - } - if (dhcp->siaddr) - { - DEBUGP ((" si=")); - PrIP (dhcp->siaddr); - } - if (dhcp->hlen == sizeof (MACADDR)) - { - DEBUGP ((" ch=")); - PrMac (dhcp->chaddr); - } - - DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid))); - - if (ntohl (dhcp->magic) != 0x63825363) - DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic))); - if (dhcp->htype != 1) - DEBUGP ((" htype=%d", dhcp->htype)); - if (dhcp->hops) - DEBUGP ((" hops=%d", dhcp->hops)); - if (ntohs (dhcp->secs)) - DEBUGP ((" secs=%d", ntohs (dhcp->secs))); - if (ntohs (dhcp->flags)) - DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags))); - - // extra stuff - - if (ip->version_len != 0x45) - DEBUGP ((" vl=0x%02x", ip->version_len)); - if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen) - DEBUGP ((" tl=%d", ntohs (ip->tot_len))); - if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen) - DEBUGP ((" ul=%d", ntohs (udp->len))); - - if (ip->tos) - DEBUGP ((" tos=0x%02x", ip->tos)); - if (ntohs (ip->id)) - DEBUGP ((" id=0x%04x", ntohs (ip->id))); - if (ntohs (ip->frag_off)) - DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off))); - - DEBUGP ((" ttl=%d", ip->ttl)); - DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check), - ip_checksum ((UCHAR*)ip, sizeof (IPHDR)))); - DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check), - udp_checksum ((UCHAR *) udp, - sizeof (UDPHDR) + sizeof (DHCP) + optlen, - (UCHAR *) &ip->saddr, - (UCHAR *) &ip->daddr), - optlen)); - - // Options - { - const UCHAR *opt = (UCHAR *) (dhcp + 1); - int i; - - DEBUGP ((" OPT")); - for (i = 0; i < optlen; ++i) - { - const UCHAR data = opt[i]; - DEBUGP ((".%d", data)); - } - } -} - -#endif /* DBG */ diff --git a/tap-win32/dhcp.h b/tap-win32/dhcp.h deleted file mode 100755 index 4215f81..0000000 --- a/tap-win32/dhcp.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -#pragma pack(1) - -//=================================================== -// How many bad DHCPREQUESTs do we receive before we -// return a NAK? -// -// A bad DHCPREQUEST is defined to be one where the -// requestor doesn't know its IP address. -//=================================================== - -#define BAD_DHCPREQUEST_NAK_THRESHOLD 3 - -//============================================== -// Maximum number of DHCP options bytes supplied -//============================================== - -#define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256 -#define DHCP_OPTIONS_BUFFER_SIZE 256 - -//=================================== -// UDP port numbers of DHCP messages. -//=================================== - -#define BOOTPS_PORT 67 -#define BOOTPC_PORT 68 - -//=========================== -// The DHCP message structure -//=========================== - -typedef struct { -# define BOOTREQUEST 1 -# define BOOTREPLY 2 - UCHAR op; /* message op */ - - UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */ - UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */ - UCHAR hops; /* client sets to 0, may be used by relay agents */ - ULONG xid; /* transaction ID, chosen by client */ - USHORT secs; /* seconds since request process began, set by client */ - USHORT flags; - ULONG ciaddr; /* client IP address, client sets if known */ - ULONG yiaddr; /* 'your' IP address -- server's response to client */ - ULONG siaddr; /* server IP address */ - ULONG giaddr; /* relay agent IP address */ - UCHAR chaddr[16]; /* client hardware address */ - UCHAR sname[64]; /* optional server host name */ - UCHAR file[128]; /* boot file name */ - ULONG magic; /* must be 0x63825363 (network order) */ -} DHCP; - -typedef struct { - ETH_HEADER eth; - IPHDR ip; - UDPHDR udp; - DHCP dhcp; -} DHCPPre; - -typedef struct { - DHCPPre pre; - UCHAR options[DHCP_OPTIONS_BUFFER_SIZE]; -} DHCPFull; - -typedef struct { - unsigned int optlen; - BOOLEAN overflow; - DHCPFull msg; -} DHCPMsg; - -//=================== -// Macros for DHCPMSG -//=================== - -#define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre)) -#define DHCPMSG_LEN_OPT(p) ((p)->optlen) -#define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p)) -#define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg) -#define DHCPMSG_OVERFLOW(p) ((p)->overflow) - -//======================================== -// structs to hold individual DHCP options -//======================================== - -typedef struct { - UCHAR type; -} DHCPOPT0; - -typedef struct { - UCHAR type; - UCHAR len; - UCHAR data; -} DHCPOPT8; - -typedef struct { - UCHAR type; - UCHAR len; - ULONG data; -} DHCPOPT32; - -#pragma pack() - -//================== -// DHCP Option types -//================== - -#define DHCP_MSG_TYPE 53 /* message type (u8) */ -#define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */ -#define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */ -#define DHCP_IP 50 /* requested IP addr (u32) */ -#define DHCP_NETMASK 1 /* subnet mask (u32) */ -#define DHCP_LEASE_TIME 51 /* lease time sec (u32) */ -#define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */ -#define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */ -#define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */ -#define DHCP_PAD 0 -#define DHCP_END 255 - -//==================== -// DHCP Messages types -//==================== - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 -#define DHCPINFORM 8 - -#if DBG - -VOID -DumpDHCP (const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen); - -#endif diff --git a/tap-win32/endian.h b/tap-win32/endian.h deleted file mode 100755 index 128029a..0000000 --- a/tap-win32/endian.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 TAP_LITTLE_ENDIAN -#define ntohs(x) RtlUshortByteSwap(x) -#define htons(x) RtlUshortByteSwap(x) -#define ntohl(x) RtlUlongByteSwap(x) -#define htonl(x) RtlUlongByteSwap(x) -#else -#define ntohs(x) ((USHORT)(x)) -#define htons(x) ((USHORT)(x)) -#define ntohl(x) ((ULONG)(x)) -#define htonl(x) ((ULONG)(x)) -#endif diff --git a/tap-win32/error.c b/tap-win32/error.c deleted file mode 100755 index 5b25f48..0000000 --- a/tap-win32/error.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//----------------- -// DEBUGGING OUTPUT -//----------------- - -const char *g_LastErrorFilename; -int g_LastErrorLineNumber; - -#if DBG - -DebugOutput g_Debug; - -BOOLEAN -NewlineExists (const char *str, int len) -{ - while (len-- > 0) - { - const char c = *str++; - if (c == '\n') - return TRUE; - else if (c == '\0') - break; - } - return FALSE; -} - -VOID -MyDebugInit (unsigned int bufsiz) -{ - NdisZeroMemory (&g_Debug, sizeof (g_Debug)); - g_Debug.text = (char *) MemAlloc (bufsiz, FALSE); - if (g_Debug.text) - g_Debug.capacity = bufsiz; -} - -VOID -MyDebugFree () -{ - if (g_Debug.text) - MemFree (g_Debug.text, g_Debug.capacity); - NdisZeroMemory (&g_Debug, sizeof (g_Debug)); -} - -VOID -MyDebugPrint (const unsigned char* format, ...) -{ - if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT) - { - BOOLEAN owned; - ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); - if (owned) - { - const int remaining = (int)g_Debug.capacity - (int)g_Debug.out; - - if (remaining > 0) - { - va_list args; - NTSTATUS status; - char *end; - - va_start (args, format); - status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out, - remaining, - &end, - NULL, - STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS, - format, - args); - va_end (args); - - if (status == STATUS_SUCCESS) - g_Debug.out = (unsigned int) (end - g_Debug.text); - else - g_Debug.error = TRUE; - } - else - g_Debug.error = TRUE; - - RELEASE_MUTEX (&g_Debug.lock); - } - else - g_Debug.error = TRUE; - } -} - -BOOLEAN -GetDebugLine (char *buf, const int len) -{ - static const char *truncated = "[OUTPUT TRUNCATED]\n"; - BOOLEAN ret = FALSE; - - NdisZeroMemory (buf, len); - - if (g_Debug.text && g_Debug.capacity > 0) - { - BOOLEAN owned; - ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); - if (owned) - { - int i = 0; - - if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in)) - { - while (i < (len - 1) && g_Debug.in < g_Debug.out) - { - const char c = g_Debug.text[g_Debug.in++]; - if (c == '\n') - break; - buf[i++] = c; - } - if (i < len) - buf[i] = '\0'; - } - - if (!i) - { - if (g_Debug.in == g_Debug.out) - { - g_Debug.in = g_Debug.out = 0; - if (g_Debug.error) - { - const unsigned int tlen = strlen (truncated); - if (tlen < g_Debug.capacity) - { - NdisMoveMemory (g_Debug.text, truncated, tlen+1); - g_Debug.out = tlen; - } - g_Debug.error = FALSE; - } - } - } - else - ret = TRUE; - - RELEASE_MUTEX (&g_Debug.lock); - } - } - return ret; -} - -VOID -MyAssert (const unsigned char *file, int line) -{ - DEBUGP (("MYASSERT failed %s/%d\n", file, line)); - KeBugCheckEx (0x0F00BABA, - (ULONG_PTR) line, - (ULONG_PTR) 0, - (ULONG_PTR) 0, - (ULONG_PTR) 0); -} - -VOID -PrMac (const MACADDR mac) -{ - DEBUGP (("%x:%x:%x:%x:%x:%x", - mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5])); -} - -VOID -PrIP (IPADDR ip_addr) -{ - const unsigned char *ip = (const unsigned char *) &ip_addr; - - DEBUGP (("%d.%d.%d.%d", - ip[0], ip[1], ip[2], ip[3])); -} - -const char * -PrIPProto (int proto) -{ - switch (proto) - { - case IPPROTO_UDP: - return "UDP"; - case IPPROTO_TCP: - return "TCP"; - case IPPROTO_ICMP: - return "ICMP"; - case IPPROTO_IGMP: - return "IGMP"; - default: - return "???"; - } -} - -VOID -DumpARP (const char *prefix, const ARP_PACKET *arp) -{ - DEBUGP (("%s ARP src=", prefix)); - PrMac (arp->m_MAC_Source); - DEBUGP ((" dest=")); - PrMac (arp->m_MAC_Destination); - DEBUGP ((" OP=0x%04x", - (int)ntohs(arp->m_ARP_Operation))); - DEBUGP ((" M=0x%04x(%d)", - (int)ntohs(arp->m_MAC_AddressType), - (int)arp->m_MAC_AddressSize)); - DEBUGP ((" P=0x%04x(%d)", - (int)ntohs(arp->m_PROTO_AddressType), - (int)arp->m_PROTO_AddressSize)); - - DEBUGP ((" MacSrc=")); - PrMac (arp->m_ARP_MAC_Source); - DEBUGP ((" MacDest=")); - PrMac (arp->m_ARP_MAC_Destination); - - DEBUGP ((" IPSrc=")); - PrIP (arp->m_ARP_IP_Source); - DEBUGP ((" IPDest=")); - PrIP (arp->m_ARP_IP_Destination); - - DEBUGP (("\n")); -} - -struct ethpayload { - ETH_HEADER eth; - UCHAR payload[DEFAULT_PACKET_LOOKAHEAD]; -}; - -VOID -DumpPacket2 (const char *prefix, - const ETH_HEADER *eth, - const unsigned char *data, - unsigned int len) -{ - struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE); - if (ep) - { - if (len > DEFAULT_PACKET_LOOKAHEAD) - len = DEFAULT_PACKET_LOOKAHEAD; - ep->eth = *eth; - NdisMoveMemory (ep->payload, data, len); - DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len); - MemFree (ep, sizeof (struct ethpayload)); - } -} - -VOID -DumpPacket (const char *prefix, - const unsigned char *data, - unsigned int len) -{ - const ETH_HEADER *eth = (const ETH_HEADER *) data; - const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER)); - - if (len < sizeof (ETH_HEADER)) - { - DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len)); - return; - } - - // ARP Packet? - if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP)) - { - DumpARP (prefix, (const ARP_PACKET *) data); - return; - } - - // IPv4 packet? - if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER)) - && eth->proto == htons (ETH_P_IP) - && IPH_GET_VER (ip->version_len) == 4) - { - const int hlen = IPH_GET_LEN (ip->version_len); - const int blen = len - sizeof (ETH_HEADER); - BOOLEAN did = FALSE; - - DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len)); - - if (!(ntohs (ip->tot_len) == blen && hlen <= blen)) - { - DEBUGP ((" XXX")); - return; - } - - // TCP packet? - if (ip->protocol == IPPROTO_TCP - && blen - hlen >= (sizeof (TCPHDR))) - { - const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen); - DEBUGP ((" ")); - PrIP (ip->saddr); - DEBUGP ((":%d", ntohs (tcp->source))); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - DEBUGP ((":%d", ntohs (tcp->dest))); - did = TRUE; - } - - // UDP packet? - else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0 - && ip->protocol == IPPROTO_UDP - && blen - hlen >= (sizeof (UDPHDR))) - { - const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen); - - // DHCP packet? - if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT)) - && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP))) - { - const DHCP *dhcp = (DHCP *) (data - + hlen - + sizeof (ETH_HEADER) - + sizeof (UDPHDR)); - - int optlen = len - - sizeof (ETH_HEADER) - - hlen - - sizeof (UDPHDR) - - sizeof (DHCP); - - if (optlen < 0) - optlen = 0; - - DumpDHCP (eth, ip, udp, dhcp, optlen); - did = TRUE; - } - - if (!did) - { - DEBUGP ((" ")); - PrIP (ip->saddr); - DEBUGP ((":%d", ntohs (udp->source))); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - DEBUGP ((":%d", ntohs (udp->dest))); - did = TRUE; - } - } - - if (!did) - { - DEBUGP ((" ipproto=%d ", ip->protocol)); - PrIP (ip->saddr); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - } - - DEBUGP (("\n")); - return; - } - - { - DEBUGP (("%s ??? src=", prefix)); - PrMac (eth->src); - DEBUGP ((" dest=")); - PrMac (eth->dest); - DEBUGP ((" proto=0x%04x len=%d\n", - (int) ntohs(eth->proto), - len)); - } -} - -#endif diff --git a/tap-win32/error.h b/tap-win32/error.h deleted file mode 100755 index d8436dc..0000000 --- a/tap-win32/error.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//----------------- -// DEBUGGING OUTPUT -//----------------- - -#define NOTE_ERROR() \ -{ \ - g_LastErrorFilename = __FILE__; \ - g_LastErrorLineNumber = __LINE__; \ -} - -#if DBG - -typedef struct { - unsigned int in; - unsigned int out; - unsigned int capacity; - char *text; - BOOLEAN error; - MUTEX lock; -} DebugOutput; - -VOID MyDebugPrint (const unsigned char* format, ...); - -VOID MyAssert (const unsigned char *file, int line); - -VOID DumpPacket (const char *prefix, - const unsigned char *data, - unsigned int len); - -VOID DumpPacket2 (const char *prefix, - const ETH_HEADER *eth, - const unsigned char *data, - unsigned int len); - -#define CAN_WE_PRINT (DEBUGP_AT_DISPATCH || KeGetCurrentIrql () < DISPATCH_LEVEL) - -#if ALSO_DBGPRINT -#define DEBUGP(fmt) { MyDebugPrint fmt; if (CAN_WE_PRINT) DbgPrint fmt; } -#else -#define DEBUGP(fmt) { MyDebugPrint fmt; } -#endif - -#define MYASSERT(exp) \ -{ \ - if (!(exp)) \ - { \ - MyAssert(__FILE__, __LINE__); \ - } \ -} - -#define DUMP_PACKET(prefix, data, len) \ - DumpPacket (prefix, data, len) - -#define DUMP_PACKET2(prefix, eth, data, len) \ - DumpPacket2 (prefix, eth, data, len) - -#else - -#define DEBUGP(fmt) -#define MYASSERT(exp) -#define DUMP_PACKET(prefix, data, len) -#define DUMP_PACKET2(prefix, eth, data, len) - -#endif diff --git a/tap-win32/hexdump.c b/tap-win32/hexdump.c deleted file mode 100755 index 49bc38c..0000000 --- a/tap-win32/hexdump.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 __cplusplus -extern "C" { -#endif - -#include "hexdump.h" - -#ifndef NDIS_MINIPORT_DRIVER - -VOID (*DbgMessage)(char *p_Format, ...) = DisplayDebugString; - -VOID DisplayDebugString (char *p_Format, ...) - { - static char l_Buffer [4096]; - - va_list l_ArgumentList; - va_start (l_ArgumentList, p_Format); - vsprintf (l_Buffer, p_Format, l_ArgumentList); - va_end (l_ArgumentList); - - OutputDebugStringA (l_Buffer); - } - -#endif - -VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size) - { - unsigned long l_Index, l_Idx; - unsigned char l_Row [17]; - - for (l_Index = l_Row [16] = 0; l_Index < p_Size || l_Index % 16; ++l_Index) - { - if (l_Index % 16 == 0) - DEBUGP (("%05x ", l_Index)); - DEBUGP (("%02x ", l_Row [l_Index % 16] = (l_Index < p_Size ? p_Buffer [l_Index] : 0))); - l_Row [l_Index % 16] = IfPrint (l_Row [l_Index % 16]); - if ((l_Index + 1) % 16 == 0) - DEBUGP ((" %s\n", l_Row)); - } - - DEBUGP (("\n")); - } - -#ifdef __cplusplus -} -#endif diff --git a/tap-win32/hexdump.h b/tap-win32/hexdump.h deleted file mode 100755 index c1af705..0000000 --- a/tap-win32/hexdump.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 HEXDUMP_DEFINED -#define HEXDUMP_DEFINED - -#ifdef __cplusplus -extern "C" { -#endif - -//===================================================================================== -// Debug Routines -//===================================================================================== - -#ifndef NDIS_MINIPORT_DRIVER -# include <stdio.h> -# include <ctype.h> -# include <windows.h> -# include <winnt.h> -# include <memory.h> - -# ifndef DEBUGP -# define DEBUGP(fmt) { DbgMessage fmt; } -# endif - - extern VOID (*DbgMessage)(char *p_Format, ...); - - VOID DisplayDebugString (char *p_Format, ...); -#endif - -//=================================================================================== -// Reporting / Debugging -//=================================================================================== -#define IfPrint(c) (c >= 32 && c < 127 ? c : '.') - -VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tap-win32/i386/OemWin2k.inf.in b/tap-win32/i386/OemWin2k.inf.in deleted file mode 100755 index 031b06c..0000000 --- a/tap-win32/i386/OemWin2k.inf.in +++ /dev/null @@ -1,195 +0,0 @@ -; **************************************************************************** -; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * -; * 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. * -; **************************************************************************** - -; SYNTAX CHECKER -; cd \WINDDK\3790\tools\chkinf -; chkinf c:\src\openvpn\tap-win32\i386\oemwin2k.inf -; OUTPUT -> file:///c:/WINDDK/3790/tools/chkinf/htm/c%23+src+openvpn+tap-win32+i386+__OemWin2k.htm - -; INSTALL/REMOVE DRIVER -; tapinstall install OemWin2k.inf TAP0901 -; tapinstall update OemWin2k.inf TAP0901 -; tapinstall remove TAP0901 - -;********************************************************* -; Note to Developers: -; -; If you are bundling the TAP-Win32 driver with your app, -; you should try to rename it in such a way that it will -; not collide with other instances of TAP-Win32 defined -; by other apps. Multiple versions of the TAP-Win32 -; driver, each installed by different apps, can coexist -; on the same machine if you follow these guidelines. -; NOTE: these instructions assume you are editing the -; generated OemWin2k.inf file, not the source -; OemWin2k.inf.in file which is preprocessed by winconfig -; and uses macro definitions from settings.in. -; -; (1) Rename all tapXXXX instances in this file to -; something different (use at least 5 characters -; for this name!) -; (2) Change the "!define TAP" definition in openvpn.nsi -; to match what you changed tapXXXX to. -; (3) Change TARGETNAME in SOURCES to match what you -; changed tapXXXX to. -; (4) Change TAP_COMPONENT_ID in common.h to match what -; you changed tapXXXX to. -; (5) Change SZDEPENDENCIES in service.h to match what -; you changed tapXXXX to. -; (6) Change DeviceDescription and Provider strings. -; (7) Change PRODUCT_STRING in constants.h to what you -; set DeviceDescription to. -; -;********************************************************* - -[Version] - Signature = "$Windows NT$" - CatalogFile = @@PRODUCT_TAP_ID@@.cat - ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} - Provider = %Provider% - Class = Net - -; This version number should match the version -; number given in SOURCES. - DriverVer=@@PRODUCT_TAP_RELDATE@@,@@PRODUCT_TAP_MAJOR_VER@@.00.00.@@PRODUCT_TAP_MINOR_VER@@ - -[Strings] - DeviceDescription = "@@PRODUCT_TAP_DEVICE_DESCRIPTION@@" - Provider = "@@PRODUCT_TAP_PROVIDER@@" - -;---------------------------------------------------------------- -; Manufacturer + Product Section (Done) -;---------------------------------------------------------------- -[Manufacturer] -!ifdef AMD64 - %Provider% = @@PRODUCT_TAP_ID@@, NTamd64 -!else - %Provider% = @@PRODUCT_TAP_ID@@ -!endif - -!ifdef AMD64 -[@@PRODUCT_TAP_ID@@.NTamd64] -!else -[@@PRODUCT_TAP_ID@@] -!endif - %DeviceDescription% = @@PRODUCT_TAP_ID@@.ndi, @@PRODUCT_TAP_ID@@ - -;--------------------------------------------------------------- -; Driver Section (Done) -;--------------------------------------------------------------- - -;----------------- Characteristics ------------ -; NCF_PHYSICAL = 0x04 -; NCF_VIRTUAL = 0x01 -; NCF_SOFTWARE_ENUMERATED = 0x02 -; NCF_HIDDEN = 0x08 -; NCF_NO_SERVICE = 0x10 -; NCF_HAS_UI = 0x80 -;----------------- Characteristics ------------ - -[@@PRODUCT_TAP_ID@@.ndi] - CopyFiles = @@PRODUCT_TAP_ID@@.driver, @@PRODUCT_TAP_ID@@.files - AddReg = @@PRODUCT_TAP_ID@@.reg - AddReg = @@PRODUCT_TAP_ID@@.params.reg - Characteristics = @@PRODUCT_TAP_CHARACTERISTICS@@ - -[@@PRODUCT_TAP_ID@@.ndi.Services] - AddService = @@PRODUCT_TAP_ID@@, 2, @@PRODUCT_TAP_ID@@.service - -[@@PRODUCT_TAP_ID@@.reg] - HKR, Ndi, Service, 0, "@@PRODUCT_TAP_ID@@" - HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" - HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" - HKR, , Manufacturer, 0, "%Provider%" - HKR, , ProductName, 0, "%DeviceDescription%" - -[@@PRODUCT_TAP_ID@@.params.reg] - HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" - HKR, Ndi\params\MTU, Type, 0, "int" - HKR, Ndi\params\MTU, Default, 0, "1500" - HKR, Ndi\params\MTU, Optional, 0, "0" - HKR, Ndi\params\MTU, Min, 0, "100" - HKR, Ndi\params\MTU, Max, 0, "1500" - HKR, Ndi\params\MTU, Step, 0, "1" - HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" - HKR, Ndi\params\MediaStatus, Type, 0, "enum" - HKR, Ndi\params\MediaStatus, Default, 0, "0" - HKR, Ndi\params\MediaStatus, Optional, 0, "0" - HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" - HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" - HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" - HKR, Ndi\params\MAC, Type, 0, "edit" - HKR, Ndi\params\MAC, Optional, 0, "1" - HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access" - HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum" - HKR, Ndi\params\AllowNonAdmin, Default, 0, "1" - HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0" - HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed" - HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed" - -;---------------------------------------------------------------- -; Service Section -;---------------------------------------------------------------- - -;---------- Service Type ------------- -; SERVICE_KERNEL_DRIVER = 0x01 -; SERVICE_WIN32_OWN_PROCESS = 0x10 -;---------- Service Type ------------- - -;---------- Start Mode --------------- -; SERVICE_BOOT_START = 0x0 -; SERVICE_SYSTEM_START = 0x1 -; SERVICE_AUTO_START = 0x2 -; SERVICE_DEMAND_START = 0x3 -; SERVICE_DISABLED = 0x4 -;---------- Start Mode --------------- - -[@@PRODUCT_TAP_ID@@.service] - DisplayName = %DeviceDescription% - ServiceType = 1 - StartType = 3 - ErrorControl = 1 - LoadOrderGroup = NDIS - ServiceBinary = %12%\@@PRODUCT_TAP_ID@@.sys - -;----------------------------------------------------------------- -; File Installation -;----------------------------------------------------------------- - -;----------------- Copy Flags ------------ -; COPYFLG_NOSKIP = 0x02 -; COPYFLG_NOVERSIONCHECK = 0x04 -;----------------- Copy Flags ------------ - -; SourceDisksNames -; diskid = description[, [tagfile] [, <unused>, subdir]] -; 1 = "Intel Driver Disk 1",e100bex.sys,, - -[SourceDisksNames] - 1 = %DeviceDescription%, @@PRODUCT_TAP_ID@@.sys - -; SourceDisksFiles -; filename_on_source = diskID[, [subdir][, size]] -; e100bex.sys = 1,, ; on distribution disk 1 - -[SourceDisksFiles] -@@PRODUCT_TAP_ID@@.sys = 1 - -[DestinationDirs] - @@PRODUCT_TAP_ID@@.files = 11 - @@PRODUCT_TAP_ID@@.driver = 12 - -[@@PRODUCT_TAP_ID@@.files] -; TapPanel.cpl,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK -; cipsrvr.exe,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK - -[@@PRODUCT_TAP_ID@@.driver] - @@PRODUCT_TAP_ID@@.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK - -;--------------------------------------------------------------- -; End -;--------------------------------------------------------------- diff --git a/tap-win32/instance.c b/tap-win32/instance.c deleted file mode 100755 index 182cee8..0000000 --- a/tap-win32/instance.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice)) - -#define N_INSTANCE_BUCKETS 256 - -typedef struct _INSTANCE { - struct _INSTANCE *next; - TapAdapterPointer m_Adapter; -} INSTANCE; - -typedef struct { - INSTANCE *list; - MUTEX lock; -} INSTANCE_BUCKET; - -typedef struct { - INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS]; -} INSTANCE_HASH; - -INSTANCE_HASH *g_InstanceHash = NULL; - -// must return a hash >= 0 and < N_INSTANCE_BUCKETS -int -InstanceHashValue (PVOID addr) -{ - UCHAR *p = (UCHAR *) &addr; - - if (sizeof (addr) == 4) - return p[0] ^ p[1] ^ p[2] ^ p[3]; - else if (sizeof (addr) == 8) - return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7]; - else - { - MYASSERT (0); - } -} - -BOOLEAN -InitInstanceList (VOID) -{ - MYASSERT (g_InstanceHash == NULL); - g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE); - if (g_InstanceHash) - { - int i; - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - INIT_MUTEX (&g_InstanceHash->buckets[i].lock); - return TRUE; - } - else - return FALSE; -} - -int -NInstances (VOID) -{ - int i, n = 0; - - if (g_InstanceHash) - { - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - { - BOOLEAN got_lock; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current; - for (current = ib->list; current != NULL; current = current->next) - ++n; - RELEASE_MUTEX (&ib->lock); - } - else - return -1; - } - } - - return n; -} - -int -InstanceMaxBucketSize (VOID) -{ - int i, n = 0; - - if (g_InstanceHash) - { - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - { - BOOLEAN got_lock; - int bucket_size = 0; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current; - for (current = ib->list; current != NULL; current = current->next) - ++bucket_size; - if (bucket_size > n) - n = bucket_size; - RELEASE_MUTEX (&ib->lock); - } - else - return -1; - } - } - - return n; -} - -VOID -FreeInstanceList (VOID) -{ - if (g_InstanceHash) - { - MYASSERT (NInstances() == 0); - MemFree (g_InstanceHash, sizeof (INSTANCE_HASH)); - g_InstanceHash = NULL; - } -} - -BOOLEAN -AddAdapterToInstanceList (TapAdapterPointer p_Adapter) -{ - BOOLEAN got_lock; - BOOLEAN ret = FALSE; - const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter)); - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash]; - - DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash)); - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE); - if (i) - { - MYASSERT (p_Adapter); - i->m_Adapter = p_Adapter; - i->next = ib->list; - ib->list = i; - ret = TRUE; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} - -BOOLEAN -RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter) -{ - BOOLEAN got_lock; - BOOLEAN ret = FALSE; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))]; - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current, *prev=NULL; - for (current = ib->list; current != NULL; current = current->next) - { - if (current->m_Adapter == p_Adapter) // found match - { - if (prev) - prev->next = current->next; - else - ib->list = current->next; - MemFree (current->m_Adapter, sizeof (TapAdapter)); - MemFree (current, sizeof (INSTANCE)); - ret = TRUE; - break; - } - prev = current; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} - -TapAdapterPointer -LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject) -{ - BOOLEAN got_lock; - TapAdapterPointer ret = NULL; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)]; - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current, *prev=NULL; - for (current = ib->list; current != NULL; current = current->next) - { - if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match - { - // move it to head of list - if (prev) - { - prev->next = current->next; - current->next = ib->list; - ib->list = current; - } - ret = ib->list->m_Adapter; - break; - } - prev = current; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} diff --git a/tap-win32/lock.h b/tap-win32/lock.h deleted file mode 100755 index ea75414..0000000 --- a/tap-win32/lock.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -typedef struct -{ - volatile long count; -} MUTEX; - -#define MUTEX_SLEEP_TIME 10000 // microseconds - -#define INIT_MUTEX(m) { (m)->count = 0; } - -#define ACQUIRE_MUTEX_BLOCKING(m) \ -{ \ - while (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - NdisMSleep(MUTEX_SLEEP_TIME); \ - } \ -} - -#define RELEASE_MUTEX(m) \ -{ \ - NdisInterlockedDecrement(&((m)->count)); \ -} - -#define ACQUIRE_MUTEX_NONBLOCKING(m, result) \ -{ \ - if (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - result = FALSE; \ - } \ - else \ - { \ - result = TRUE; \ - } \ -} - -#define ACQUIRE_MUTEX_ADAPTIVE(m, result) \ -{ \ - result = TRUE; \ - while (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - if (KeGetCurrentIrql () < DISPATCH_LEVEL) \ - NdisMSleep(MUTEX_SLEEP_TIME); \ - else \ - { \ - result = FALSE; \ - break; \ - } \ - } \ -} diff --git a/tap-win32/macinfo.c b/tap-win32/macinfo.c deleted file mode 100755 index 8d512ec..0000000 --- a/tap-win32/macinfo.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 "macinfo.h" - -int -HexStringToDecimalInt (const int p_Character) -{ - int l_Value = 0; - - if (p_Character >= 'A' && p_Character <= 'F') - l_Value = (p_Character - 'A') + 10; - else if (p_Character >= 'a' && p_Character <= 'f') - l_Value = (p_Character - 'a') + 10; - else if (p_Character >= '0' && p_Character <= '9') - l_Value = p_Character - '0'; - - return l_Value; -} - -BOOLEAN -ParseMAC (MACADDR dest, const char *src) -{ - int c; - int mac_index = 0; - BOOLEAN high_digit = FALSE; - int delim_action = 1; - - MYASSERT (src); - MYASSERT (dest); - - CLEAR_MAC (dest); - - while (c = *src++) - { - if (IsMacDelimiter (c)) - { - mac_index += delim_action; - high_digit = FALSE; - delim_action = 1; - } - else if (IsHexDigit (c)) - { - const int digit = HexStringToDecimalInt (c); - if (mac_index < sizeof (MACADDR)) - { - if (!high_digit) - { - dest[mac_index] = (char)(digit); - high_digit = TRUE; - delim_action = 1; - } - else - { - dest[mac_index] = (char)(dest[mac_index] * 16 + digit); - ++mac_index; - high_digit = FALSE; - delim_action = 0; - } - } - else - return FALSE; - } - else - return FALSE; - } - - return (mac_index + delim_action) >= sizeof (MACADDR); -} - -/* - * Generate a MAC using the GUID in the adapter name. - * - * The mac is constructed as 00:FF:xx:xx:xx:xx where - * the Xs are taken from the first 32 bits of the GUID in the - * adapter name. This is similar to the Linux 2.4 tap MAC - * generator, except linux uses 32 random bits for the Xs. - * - * In general, this solution is reasonable for most - * applications except for very large bridged TAP networks, - * where the probability of address collisions becomes more - * than infintesimal. - * - * Using the well-known "birthday paradox", on a 1000 node - * network the probability of collision would be - * 0.000116292153. On a 10,000 node network, the probability - * of collision would be 0.01157288998621678766. - */ - -VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name) -{ - unsigned const char *cp = adapter_name; - unsigned char c; - unsigned int i = 2; - unsigned int byte = 0; - int brace = 0; - int state = 0; - - CLEAR_MAC (mac); - - mac[0] = 0x00; - mac[1] = 0xFF; - - while (c = *cp++) - { - if (i >= sizeof (MACADDR)) - break; - if (c == '{') - brace = 1; - if (IsHexDigit (c) && brace) - { - const unsigned int digit = HexStringToDecimalInt (c); - if (state) - { - byte <<= 4; - byte |= digit; - mac[i++] = (unsigned char) byte; - state = 0; - } - else - { - byte = digit; - state = 1; - } - } - } -} - -VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta) -{ - COPY_MAC (dest, src); - dest[2] += (UCHAR) delta; -} diff --git a/tap-win32/macinfo.h b/tap-win32/macinfo.h deleted file mode 100755 index 51e930d..0000000 --- a/tap-win32/macinfo.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 MacInfoDefined -#define MacInfoDefined - -//=================================================================================== -// Macros -//=================================================================================== -#define IsMacDelimiter(a) (a == ':' || a == '-' || a == '.') -#define IsHexDigit(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) - -#define COPY_MAC(dest, src) NdisMoveMemory ((dest), (src), sizeof (MACADDR)) -#define CLEAR_MAC(dest) NdisZeroMemory ((dest), sizeof (MACADDR)) -#define MAC_EQUAL(a,b) (memcmp ((a), (b), sizeof (MACADDR)) == 0) - -#endif diff --git a/tap-win32/mem.c b/tap-win32/mem.c deleted file mode 100755 index 6fbbed5..0000000 --- a/tap-win32/mem.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//------------------ -// Memory Management -//------------------ - -PVOID -MemAlloc (ULONG p_Size, BOOLEAN zero) -{ - PVOID l_Return = NULL; - - if (p_Size) - { - __try - { - if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT') - == NDIS_STATUS_SUCCESS) - { - if (zero) - NdisZeroMemory (l_Return, p_Size); - } - else - l_Return = NULL; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - l_Return = NULL; - } - } - - return l_Return; -} - -VOID -MemFree (PVOID p_Addr, ULONG p_Size) -{ - if (p_Addr && p_Size) - { - __try - { -#if DBG - NdisZeroMemory (p_Addr, p_Size); -#endif - NdisFreeMemory (p_Addr, p_Size, 0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - } -} - -/* - * Circular queue management routines. - */ - -#define QUEUE_BYTE_ALLOCATION(size) \ - (sizeof (Queue) + (size * sizeof (PVOID))) - -#define QUEUE_ADD_INDEX(var, inc) \ -{ \ - var += inc; \ - if (var >= q->capacity) \ - var -= q->capacity; \ - MYASSERT (var < q->capacity); \ -} - -#define QUEUE_SANITY_CHECK() \ - MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity) - -#define QueueCount(q) (q->size) - -#define UPDATE_MAX_SIZE() \ -{ \ - if (q->size > q->max_size) \ - q->max_size = q->size; \ -} - -Queue * -QueueInit (ULONG capacity) -{ - Queue *q; - - MYASSERT (capacity > 0); - q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE); - if (!q) - return NULL; - - q->base = q->size = 0; - q->capacity = capacity; - q->max_size = 0; - return q; -} - -VOID -QueueFree (Queue *q) -{ - if (q) - { - QUEUE_SANITY_CHECK (); - MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity)); - } -} - -PVOID -QueuePush (Queue *q, PVOID item) -{ - ULONG dest; - QUEUE_SANITY_CHECK (); - if (q->size == q->capacity) - return NULL; - dest = q->base; - QUEUE_ADD_INDEX (dest, q->size); - q->data[dest] = item; - ++q->size; - UPDATE_MAX_SIZE(); - return item; -} - -PVOID -QueuePop (Queue *q) -{ - ULONG oldbase; - QUEUE_SANITY_CHECK (); - if (!q->size) - return NULL; - oldbase = q->base; - QUEUE_ADD_INDEX (q->base, 1); - --q->size; - UPDATE_MAX_SIZE(); - return q->data[oldbase]; -} - -PVOID -QueueExtract (Queue *q, PVOID item) -{ - ULONG src, dest, count, n; - QUEUE_SANITY_CHECK (); - n = 0; - src = dest = q->base; - count = q->size; - while (count--) - { - if (item == q->data[src]) - { - ++n; - --q->size; - } - else - { - q->data[dest] = q->data[src]; - QUEUE_ADD_INDEX (dest, 1); - } - QUEUE_ADD_INDEX (src, 1); - } - if (n) - return item; - else - return NULL; -} - -#undef QUEUE_BYTE_ALLOCATION -#undef QUEUE_ADD_INDEX -#undef QUEUE_SANITY_CHECK -#undef UPDATE_MAX_SIZE diff --git a/tap-win32/proto.h b/tap-win32/proto.h deleted file mode 100755 index 894a37f..0000000 --- a/tap-win32/proto.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 - */ - -//============================================================ -// MAC address, Ethernet header, and ARP -//============================================================ - -#pragma pack(1) - -#define IP_HEADER_SIZE 20 -#define IPV6_HEADER_SIZE 40 - -typedef unsigned char MACADDR [6]; -typedef unsigned long IPADDR; -typedef unsigned char IPV6ADDR [16]; - -//----------------- -// Ethernet address -//----------------- - -typedef struct { - MACADDR addr; -} ETH_ADDR; - -typedef struct { - ETH_ADDR list[NIC_MAX_MCAST_LIST]; -} MC_LIST; - -//---------------- -// Ethernet header -//---------------- - -typedef struct -{ - MACADDR dest; /* destination eth addr */ - MACADDR src; /* source ether addr */ - -# define ETH_P_IP 0x0800 /* IPv4 protocol */ -# define ETH_P_IPV6 0x86DD /* IPv6 protocol */ -# define ETH_P_ARP 0x0806 /* ARP protocol */ - USHORT proto; /* packet type ID field */ -} ETH_HEADER, *PETH_HEADER; - -//---------------- -// ARP packet -//---------------- - -typedef struct - { - MACADDR m_MAC_Destination; // Reverse these two - MACADDR m_MAC_Source; // to answer ARP requests - USHORT m_Proto; // 0x0806 - -# define MAC_ADDR_TYPE 0x0001 - USHORT m_MAC_AddressType; // 0x0001 - - USHORT m_PROTO_AddressType; // 0x0800 - UCHAR m_MAC_AddressSize; // 0x06 - UCHAR m_PROTO_AddressSize; // 0x04 - -# define ARP_REQUEST 0x0001 -# define ARP_REPLY 0x0002 - USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply - - MACADDR m_ARP_MAC_Source; - IPADDR m_ARP_IP_Source; - MACADDR m_ARP_MAC_Destination; - IPADDR m_ARP_IP_Destination; - } -ARP_PACKET, *PARP_PACKET; - -//---------- -// IP Header -//---------- - -typedef struct { -# define IPH_GET_VER(v) (((v) >> 4) & 0x0F) -# define IPH_GET_LEN(v) (((v) & 0x0F) << 2) - UCHAR version_len; - - UCHAR tos; - USHORT tot_len; - USHORT id; - -# define IP_OFFMASK 0x1fff - USHORT frag_off; - - UCHAR ttl; - -# define IPPROTO_UDP 17 /* UDP protocol */ -# define IPPROTO_TCP 6 /* TCP protocol */ -# define IPPROTO_ICMP 1 /* ICMP protocol */ -# define IPPROTO_IGMP 2 /* IGMP protocol */ - UCHAR protocol; - - USHORT check; - ULONG saddr; - ULONG daddr; - /* The options start here. */ -} IPHDR; - -//----------- -// UDP header -//----------- - -typedef struct { - USHORT source; - USHORT dest; - USHORT len; - USHORT check; -} UDPHDR; - -//-------------------------- -// TCP header, per RFC 793. -//-------------------------- - -typedef struct { - USHORT source; /* source port */ - USHORT dest; /* destination port */ - ULONG seq; /* sequence number */ - ULONG ack_seq; /* acknowledgement number */ - -# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2) - UCHAR doff_res; - -# define TCPH_FIN_MASK (1<<0) -# define TCPH_SYN_MASK (1<<1) -# define TCPH_RST_MASK (1<<2) -# define TCPH_PSH_MASK (1<<3) -# define TCPH_ACK_MASK (1<<4) -# define TCPH_URG_MASK (1<<5) -# define TCPH_ECE_MASK (1<<6) -# define TCPH_CWR_MASK (1<<7) - UCHAR flags; - - USHORT window; - USHORT check; - USHORT urg_ptr; -} TCPHDR; - -#define TCPOPT_EOL 0 -#define TCPOPT_NOP 1 -#define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 - -//------------ -// IPv6 Header -//------------ - -typedef struct { - UCHAR version_prio; - UCHAR flow_lbl[3]; - USHORT payload_len; -# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */ - UCHAR nexthdr; - UCHAR hop_limit; - IPV6ADDR saddr; - IPV6ADDR daddr; -} IPV6HDR; - -//-------------------------------------------- -// IPCMPv6 NS/NA Packets (RFC4443 and RFC4861) -//-------------------------------------------- - -// Neighbor Solictiation - RFC 4861, 4.3 -// (this is just the ICMPv6 part of the packet) -typedef struct { - UCHAR type; -# define ICMPV6_TYPE_NS 135 // neighbour solicitation - UCHAR code; -# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA - USHORT checksum; - ULONG reserved; - IPV6ADDR target_addr; -} ICMPV6_NS; - -// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1 -// (this is just the ICMPv6 payload) -typedef struct { - UCHAR type; -# define ICMPV6_TYPE_NA 136 // neighbour advertisement - UCHAR code; -# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA - USHORT checksum; - UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4) - UCHAR reserved[3]; - IPV6ADDR target_addr; -// always include "Target Link-layer Address" option (RFC 4861 4.6.1) - UCHAR opt_type; -#define ICMPV6_OPTION_TLLA 2 - UCHAR opt_length; -#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes - MACADDR target_macaddr; -} ICMPV6_NA; - -// this is the complete packet with Ethernet and IPv6 headers -typedef struct { - ETH_HEADER eth; - IPV6HDR ipv6; - ICMPV6_NA icmpv6; -} ICMPV6_NA_PKT; - -#pragma pack() diff --git a/tap-win32/prototypes.h b/tap-win32/prototypes.h deleted file mode 100755 index 55454d5..0000000 --- a/tap-win32/prototypes.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 TAP_PROTOTYPES_DEFINED -#define TAP_PROTOTYPES_DEFINED - -NTSTATUS DriverEntry - ( - IN PDRIVER_OBJECT p_DriverObject, - IN PUNICODE_STRING p_RegistryPath - ); - -VOID TapDriverUnload - ( - IN PDRIVER_OBJECT p_DriverObject - ); - -NDIS_STATUS AdapterCreate - ( - OUT PNDIS_STATUS p_ErrorStatus, - OUT PUINT p_MediaIndex, - IN PNDIS_MEDIUM p_Media, - IN UINT p_MediaCount, - IN NDIS_HANDLE p_AdapterHandle, - IN NDIS_HANDLE p_ConfigurationHandle - ); - -VOID AdapterHalt - ( - IN NDIS_HANDLE p_AdapterContext - ); - -VOID AdapterFreeResources - ( - TapAdapterPointer p_Adapter - ); - -NDIS_STATUS AdapterReset - ( - OUT PBOOLEAN p_AddressingReset, - IN NDIS_HANDLE p_AdapterContext - ); - -NDIS_STATUS AdapterQuery - ( - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesWritten, - OUT PULONG p_BytesNeeded - ); - -NDIS_STATUS AdapterModify - ( - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesRead, - OUT PULONG p_BytesNeeded - ); - -NDIS_STATUS AdapterTransmit - ( - IN NDIS_HANDLE p_AdapterContext, - IN PNDIS_PACKET p_Packet, - IN UINT p_Flags - ); - -NDIS_STATUS AdapterReceive - ( - OUT PNDIS_PACKET p_Packet, - OUT PUINT p_Transferred, - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_HANDLE p_ReceiveContext, - IN UINT p_Offset, - IN UINT p_ToTransfer - ); - -NTSTATUS TapDeviceHook - ( - IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP - ); - -NDIS_STATUS CreateTapDevice - ( - TapExtensionPointer p_Extension, - const char *p_Name - ); - -VOID DestroyTapDevice - ( - TapExtensionPointer p_Extension - ); - -VOID TapDeviceFreeResources - ( - TapExtensionPointer p_Extension - ); - -NTSTATUS CompleteIRP - ( - IN PIRP p_IRP, - IN TapPacketPointer p_PacketBuffer, - IN CCHAR PriorityBoost - ); - -VOID CancelIRPCallback - ( - IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP - ); - -VOID CancelIRP - ( - TapExtensionPointer p_Extension, - IN PIRP p_IRP, - BOOLEAN callback - ); - -VOID FlushQueues - ( - TapExtensionPointer p_Extension - ); - -VOID ResetTapAdapterState - ( - TapAdapterPointer p_Adapter - ); - -BOOLEAN ProcessARP - ( - TapAdapterPointer p_Adapter, - const PARP_PACKET src, - const IPADDR adapter_ip, - const IPADDR ip_network, - const IPADDR ip_netmask, - const MACADDR mac - ); - -VOID SetMediaStatus - ( - TapAdapterPointer p_Adapter, - BOOLEAN state - ); - -VOID InjectPacketDeferred - ( - TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len - ); - -VOID InjectPacketNow - ( - TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len - ); - -// for KDEFERRED_ROUTINE and Static Driver Verifier -//#include <wdm.h> -//KDEFERRED_ROUTINE InjectPacketDpc; - -VOID InjectPacketDpc - ( - KDPC *Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2 - ); - -VOID CheckIfDhcpAndTunMode - ( - TapAdapterPointer p_Adapter - ); - -VOID HookDispatchFunctions(); - -#if ENABLE_NONADMIN - -#if DDKVER_MAJOR < 5600 -/* - * Better solution for use on Vista DDK, but possibly not compatible with - * earlier DDKs: - * - * Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject), - * and at the top of tapdrv.c change: - * - * #include <ndis.h> - * #include <ntstrsafe.h> - * #include <ntddk.h> - * - * To - * - * #include <ntifs.h> - * #include <ndis.h> - * #include <ntstrsafe.h> - */ -typedef struct _SECURITY_DESCRIPTOR { - unsigned char opaque[64]; -} SECURITY_DESCRIPTOR; - -NTSYSAPI -NTSTATUS -NTAPI -ZwSetSecurityObject ( - IN HANDLE Handle, - IN SECURITY_INFORMATION SecurityInformation, - IN PSECURITY_DESCRIPTOR SecurityDescriptor); - -#endif - -VOID AllowNonAdmin (TapExtensionPointer p_Extension); - -#endif - -struct WIN2K_NDIS_MINIPORT_BLOCK -{ - unsigned char opaque[16]; - UNICODE_STRING MiniportName; // how mini-port refers to us -}; - -#if PACKET_TRUNCATION_CHECK - -VOID IPv4PacketSizeVerify - ( - const UCHAR *data, - ULONG length, - BOOLEAN tun, - const char *prefix, - LONG *counter - ); - -#endif - -#endif diff --git a/tap-win32/resource.rc b/tap-win32/resource.rc deleted file mode 100755 index 84884cf..0000000 --- a/tap-win32/resource.rc +++ /dev/null @@ -1,58 +0,0 @@ -#include <windows.h> -#include <ntverp.h> - -/* get VERSION */ -#include "common.h" - -/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR - * and VER_INTERNALNAME_STR must be defined before including COMMON.VER - * The strings don't need a '\0', since common.ver has them. - */ - -#define VER_FILETYPE VFT_DRV -/* possible values: VFT_UNKNOWN - VFT_APP - VFT_DLL - VFT_DRV - VFT_FONT - VFT_VXD - VFT_STATIC_LIB -*/ -#define VER_FILESUBTYPE VFT2_DRV_NETWORK -/* possible values VFT2_UNKNOWN - VFT2_DRV_PRINTER - VFT2_DRV_KEYBOARD - VFT2_DRV_LANGUAGE - VFT2_DRV_DISPLAY - VFT2_DRV_MOUSE - VFT2_DRV_NETWORK - VFT2_DRV_SYSTEM - VFT2_DRV_INSTALLABLE - VFT2_DRV_SOUND - VFT2_DRV_COMM -*/ - -#define VER_COMPANYNAME_STR "The OpenVPN Project" -#define VER_FILEDESCRIPTION_STR "TAP-Win32 Virtual Network Driver" -#define VER_ORIGINALFILENAME_STR TAP_COMPONENT_ID ".sys" -#define VER_LEGALCOPYRIGHT_YEARS "2003-2010" -#define VER_LEGALCOPYRIGHT_STR "OpenVPN Technologies, Inc." - - -#define VER_PRODUCTNAME_STR VER_FILEDESCRIPTION_STR -#define VER_PRODUCTVERSION TAP_DRIVER_MAJOR_VERSION,00,00,TAP_DRIVER_MINOR_VERSION - -#define XSTR(s) STR(s) -#define STR(s) #s - -#define VSTRING PACKAGE_VERSION " " XSTR(TAP_DRIVER_MAJOR_VERSION) "/" XSTR(TAP_DRIVER_MINOR_VERSION) - -#ifdef DBG -#define VER_PRODUCTVERSION_STR VSTRING " (DEBUG)" -#else -#define VER_PRODUCTVERSION_STR VSTRING -#endif - -#define VER_INTERNALNAME_STR VER_ORIGINALFILENAME_STR - -#include "common.ver" diff --git a/tap-win32/tapdrvr.c b/tap-win32/tapdrvr.c deleted file mode 100755 index 7ab3916..0000000 --- a/tap-win32/tapdrvr.c +++ /dev/null @@ -1,3145 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 driver is designed to work on Win 2000 or higher -// versions of Windows. -// -// It is SMP-safe and handles NDIS 5 power management. -// -// By default we operate as a "tap" virtual ethernet -// 802.3 interface, but we can emulate a "tun" -// interface (point-to-point IPv4) through the -// TAP_IOCTL_CONFIG_POINT_TO_POINT or -// TAP_IOCTL_CONFIG_TUN ioctl. -//====================================================== - -#include "common.h" -#ifndef DDKVER_MAJOR -#error DDKVER_MAJOR must be defined as the major number of the DDK Version -#endif - -#define NDIS_MINIPORT_DRIVER -#define BINARY_COMPATIBLE 0 -#define NDIS50_MINIPORT 1 -#define NDIS_WDM 0 -#define NDIS50 1 -#define NTSTRSAFE_LIB - -// Debug info output -#define ALSO_DBGPRINT 1 -#define DEBUGP_AT_DISPATCH 0 - -//======================================================== -// Check for truncated IPv4 packets, log errors if found. -//======================================================== -#define PACKET_TRUNCATION_CHECK 0 - -//======================================================== -// EXPERIMENTAL -- Configure TAP device object to be -// accessible from non-administrative accounts, based -// on an advanced properties setting. -// -// Duplicates the functionality of OpenVPN's -// --allow-nonadmin directive. -//======================================================== -#define ENABLE_NONADMIN 1 - -#if DDKVER_MAJOR < 5600 -#include <ndis.h> -#include <ntstrsafe.h> -#include <ntddk.h> -#else -#include <ntifs.h> -#include <ndis.h> -#include <ntstrsafe.h> -#endif - -#include "lock.h" -#include "constants.h" -#include "proto.h" -#include "error.h" -#include "endian.h" -#include "dhcp.h" -#include "types.h" -#include "prototypes.h" - -#include "mem.c" -#include "macinfo.c" -#include "error.c" -#include "dhcp.c" -#include "instance.c" - -#define IS_UP(ta) \ - ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning) - -#define INCREMENT_STAT(s) ++(s) - -#define NAME_BUFFER_SIZE 80 - -//======================================================== -// Globals -//======================================================== - -NDIS_HANDLE g_NdisWrapperHandle; - -const UINT g_SupportedOIDList[] = { - OID_GEN_HARDWARE_STATUS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_LOOKAHEAD, - OID_GEN_MAC_OPTIONS, - OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_DRIVER_VERSION, - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_802_3_PERMANENT_ADDRESS, - OID_802_3_CURRENT_ADDRESS, - OID_GEN_RCV_NO_BUFFER, - OID_802_3_RCV_ERROR_ALIGNMENT, - OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS, - OID_802_3_MULTICAST_LIST, - OID_802_3_MAXIMUM_LIST_SIZE, - OID_GEN_VENDOR_ID, - OID_GEN_CURRENT_LOOKAHEAD, - OID_GEN_CURRENT_PACKET_FILTER, - OID_GEN_PROTOCOL_OPTIONS, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_TRANSMIT_BUFFER_SPACE, - OID_GEN_RECEIVE_BUFFER_SPACE, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_MAXIMUM_SEND_PACKETS, - OID_GEN_MEDIA_CONNECT_STATUS, - OID_GEN_SUPPORTED_LIST -}; - -//============================================================ -// Driver Entry -//============================================================ -#pragma NDIS_INIT_FUNCTION (DriverEntry) - -NTSTATUS -DriverEntry (IN PDRIVER_OBJECT p_DriverObject, - IN PUNICODE_STRING p_RegistryPath) -{ - NDIS_STATUS l_Status = NDIS_STATUS_FAILURE; - NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL; - - //======================================================== - // Notify NDIS that a new miniport driver is initializing. - //======================================================== - - NdisMInitializeWrapper (&g_NdisWrapperHandle, - p_DriverObject, - p_RegistryPath, NULL); - - //====================== - // Global initialization - //====================== - -#if DBG - MyDebugInit (10000); // Allocate debugging text space -#endif - - if (!InitInstanceList ()) - { - DEBUGP (("[TAP] Allocation failed for adapter instance list\n")); - goto cleanup; - } - - //======================================= - // Set and register miniport entry points - //======================================= - - l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE); - - if (l_Properties == NULL) - { - DEBUGP (("[TAP] Allocation failed for miniport entry points\n")); - goto cleanup; - } - - l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION; - l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION; - l_Properties->InitializeHandler = AdapterCreate; - l_Properties->HaltHandler = AdapterHalt; - l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */ - l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */ - l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */ - l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */ - l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */ - - switch (l_Status = - NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties, - sizeof (NDIS_MINIPORT_CHARACTERISTICS))) - { - case NDIS_STATUS_SUCCESS: - { - DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__)); - DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer)); - break; - } - - case NDIS_STATUS_BAD_CHARACTERISTICS: - { - DEBUGP (("[TAP] Miniport characteristics were badly defined\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - case NDIS_STATUS_BAD_VERSION: - { - DEBUGP - (("[TAP] NDIS Version is wrong for the given characteristics\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - case NDIS_STATUS_RESOURCES: - { - DEBUGP (("[TAP] Insufficient resources\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - default: - case NDIS_STATUS_FAILURE: - { - DEBUGP (("[TAP] Unknown fatal registration error\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - } - - cleanup: - if (l_Properties) - MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS)); - - if (l_Status == NDIS_STATUS_SUCCESS) - NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload); - else - TapDriverUnload (p_DriverObject); - - return l_Status; -} - -//============================================================ -// Driver Unload -//============================================================ -VOID -TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject) -{ - DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__, - NInstances(), - InstanceMaxBucketSize())); - - FreeInstanceList (); - - //============================== - // Free debugging text space - //============================== -#if DBG - MyDebugFree (); -#endif -} - -//========================================================== -// Adapter Initialization -//========================================================== -NDIS_STATUS AdapterCreate -(OUT PNDIS_STATUS p_ErrorStatus, - OUT PUINT p_MediaIndex, - IN PNDIS_MEDIUM p_Media, - IN UINT p_MediaCount, - IN NDIS_HANDLE p_AdapterHandle, - IN NDIS_HANDLE p_ConfigurationHandle) -{ - TapAdapterPointer l_Adapter = NULL; - - NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet - BOOLEAN l_MacFromRegistry = FALSE; - UINT l_Index; - NDIS_STATUS status; - -#if ENABLE_NONADMIN - BOOLEAN enable_non_admin = FALSE; -#endif - - DEBUGP (("[TAP] AdapterCreate called\n")); - - //==================================== - // Make sure adapter type is supported - //==================================== - - for (l_Index = 0; - l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium; - ++l_Index); - - if (l_Index == p_MediaCount) - { - DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n", - l_PreferredMedium)); - return NDIS_STATUS_UNSUPPORTED_MEDIA; - } - - *p_MediaIndex = l_Index; - - //========================================= - // Allocate memory for TapAdapter structure - //========================================= - - l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE); - - if (l_Adapter == NULL) - { - DEBUGP (("[TAP] Couldn't allocate adapter memory\n")); - return NDIS_STATUS_RESOURCES; - } - - //========================================== - // Inform the NDIS library about significant - // features of our virtual NIC. - //========================================== - - NdisMSetAttributesEx - (p_AdapterHandle, - (NDIS_HANDLE) l_Adapter, - 16, - NDIS_ATTRIBUTE_DESERIALIZE - | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT - | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT - | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, - NdisInterfaceInternal); - - //===================================== - // Initialize simple Adapter parameters - //===================================== - - l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD; - l_Adapter->m_Medium = l_PreferredMedium; - l_Adapter->m_DeviceState = '?'; - l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle; - - //================================== - // Allocate spinlock for controlling - // access to multicast address list. - //================================== - NdisAllocateSpinLock (&l_Adapter->m_MCLock); - l_Adapter->m_MCLockAllocated = TRUE; - - //==================================================== - // Register a shutdown handler which will be called - // on system restart/shutdown to halt our virtual NIC. - //==================================================== - - NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter, - AdapterHalt); - l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE; - - //============================================ - // Get parameters from registry which were set - // in the adapter advanced properties dialog. - //============================================ - { - NDIS_STATUS status; - NDIS_HANDLE configHandle; - NDIS_CONFIGURATION_PARAMETER *parm; - - // set defaults in case our registry query fails - l_Adapter->m_MTU = ETHERNET_MTU; - l_Adapter->m_MediaStateAlwaysConnected = FALSE; - l_Adapter->m_MediaState = FALSE; - - NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle); - if (status != NDIS_STATUS_SUCCESS) - { - DEBUGP (("[TAP] Couldn't open adapter registry\n")); - AdapterFreeResources (l_Adapter); - return status; - } - - //==================================== - // Allocate and construct adapter name - //==================================== - { - - NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName"); - NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion"); - NDIS_STATUS vstatus; - NDIS_CONFIGURATION_PARAMETER *vparm; - - NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger); - if (vstatus == NDIS_STATUS_SUCCESS) - DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData)); - - NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterString) - { - DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n", - parm->ParameterData.StringData.Length/2, - parm->ParameterData.StringData.Buffer)); - - if (RtlUnicodeStringToAnsiString ( - &l_Adapter->m_NameAnsi, - &parm->ParameterData.StringData, - TRUE) != STATUS_SUCCESS) - { - DEBUGP (("[TAP] MiniportName failed\n")); - status = NDIS_STATUS_RESOURCES; - } - } - } - else - { - /* "MiniportName" is available only XP and above. Not on Windows 2000. */ - if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000) - { - /* Fallback for Windows 2000 with NDIS version 5.00.00 - Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */ - if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi, - &((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName, - TRUE) != STATUS_SUCCESS) - { - DEBUGP (("[TAP] MiniportName (W2K) failed\n")); - status = NDIS_STATUS_RESOURCES; - } - else - { - DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer)); - status = NDIS_STATUS_SUCCESS; - } - } - } - } - - /* Can't continue without name (see macro 'NAME') */ - if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer) - { - NdisCloseConfiguration (configHandle); - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] failed to get miniport name\n")); - return NDIS_STATUS_RESOURCES; - } - - /* Read MTU setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MTU"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - int mtu = parm->ParameterData.IntegerData; - if (mtu < MINIMUM_MTU) - mtu = MINIMUM_MTU; - if (mtu > MAXIMUM_MTU) - mtu = MAXIMUM_MTU; - l_Adapter->m_MTU = mtu; - } - } - } - - /* Read Media Status setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MediaStatus"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - if (parm->ParameterData.IntegerData) - { - l_Adapter->m_MediaStateAlwaysConnected = TRUE; - l_Adapter->m_MediaState = TRUE; - } - } - } - } - -#if ENABLE_NONADMIN - /* Read AllowNonAdmin setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - if (parm->ParameterData.IntegerData) - { - enable_non_admin = TRUE; - } - } - } - } -#endif - - /* Read optional MAC setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MAC"); - ANSI_STRING mac_string; - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterString); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterString) - { - if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS) - { - l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer); - RtlFreeAnsiString (&mac_string); - } - } - } - } - - NdisCloseConfiguration (configHandle); - - DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU)); - } - - //================================== - // Store and update MAC address info - //================================== - - if (!l_MacFromRegistry) - GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter)); - - DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n", - NAME (l_Adapter), - l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2], - l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5])); - - //================== - // Set broadcast MAC - //================== - { - int i; - for (i = 0; i < sizeof (MACADDR); ++i) - l_Adapter->m_MAC_Broadcast[i] = 0xFF; - } - - //==================================== - // Initialize TAP device - //==================================== - { - NDIS_STATUS tap_status; - tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter)); - if (tap_status != NDIS_STATUS_SUCCESS) - { - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] CreateTapDevice failed\n")); - return tap_status; - } - } - - if (!AddAdapterToInstanceList (l_Adapter)) - { - NOTE_ERROR (); - TapDeviceFreeResources (&l_Adapter->m_Extension); - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] AddAdapterToInstanceList failed\n")); - return NDIS_STATUS_RESOURCES; - } - - l_Adapter->m_InterfaceIsRunning = TRUE; - -#if ENABLE_NONADMIN - if (enable_non_admin) - AllowNonAdmin (&l_Adapter->m_Extension); -#endif - - return NDIS_STATUS_SUCCESS; -} - -VOID -AdapterHalt (IN NDIS_HANDLE p_AdapterContext) -{ - BOOLEAN status; - - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - - NOTE_ERROR (); - - l_Adapter->m_InterfaceIsRunning = FALSE; - - DEBUGP (("[%s] is being halted\n", NAME (l_Adapter))); - - DestroyTapDevice (&l_Adapter->m_Extension); - - // Free resources - DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter))); - AdapterFreeResources (l_Adapter); - - status = RemoveAdapterFromInstanceList (l_Adapter); - DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status)); - - DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__)); -} - -VOID -AdapterFreeResources (TapAdapterPointer p_Adapter) -{ - MYASSERT (!p_Adapter->m_CalledAdapterFreeResources); - p_Adapter->m_CalledAdapterFreeResources = TRUE; - - if (p_Adapter->m_NameAnsi.Buffer) - RtlFreeAnsiString (&p_Adapter->m_NameAnsi); - - if (p_Adapter->m_RegisteredAdapterShutdownHandler) - NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle); - - if (p_Adapter->m_MCLockAllocated) - NdisFreeSpinLock (&p_Adapter->m_MCLock); -} - -VOID -DestroyTapDevice (TapExtensionPointer p_Extension) -{ - DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName)); - - //====================================== - // Let clients know we are shutting down - //====================================== - p_Extension->m_TapIsRunning = FALSE; - p_Extension->m_TapOpens = 0; - p_Extension->m_Halt = TRUE; - - //===================================== - // If we are concurrently executing in - // TapDeviceHook or AdapterTransmit, - // give those calls time to finish. - // Note that we must be running at IRQL - // < DISPATCH_LEVEL in order to call - // NdisMSleep. - //===================================== - NdisMSleep (500000); - - //=========================================================== - // Exhaust IRP and packet queues. Any pending IRPs will - // be cancelled, causing user-space to get this error - // on overlapped reads: - // The I/O operation has been aborted because of either a - // thread exit or an application request. (code=995) - // It's important that user-space close the device handle - // when this code is returned, so that when we finally - // do a NdisMDeregisterDevice, the device reference count - // is 0. Otherwise the driver will not unload even if the - // the last adapter has been halted. - //=========================================================== - FlushQueues (p_Extension); - NdisMSleep (500000); // give user space time to respond to IRP cancel - - TapDeviceFreeResources (p_Extension); -} - -VOID -TapDeviceFreeResources (TapExtensionPointer p_Extension) -{ - MYASSERT (p_Extension); - MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources); - p_Extension->m_CalledTapDeviceFreeResources = TRUE; - - if (p_Extension->m_PacketQueue) - QueueFree (p_Extension->m_PacketQueue); - if (p_Extension->m_IrpQueue) - QueueFree (p_Extension->m_IrpQueue); - if (p_Extension->m_InjectQueue) - QueueFree (p_Extension->m_InjectQueue); - - if (p_Extension->m_CreatedUnicodeLinkName) - RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName); - - //========================================================== - // According to DDK docs, the device is not actually deleted - // until its reference count falls to zero. That means we - // still need to gracefully fail TapDeviceHook requests - // after this point, otherwise ugly things would happen if - // the device was disabled (e.g. in the network connections - // control panel) while a userspace app still held an open - // file handle to it. - //========================================================== - - if (p_Extension->m_TapDevice) - { - BOOLEAN status; - status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle) - == NDIS_STATUS_SUCCESS); - DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status)); - } - - if (p_Extension->m_TapName) - MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE); - - if (p_Extension->m_InjectDpcInitialized) - KeRemoveQueueDpc (&p_Extension->m_InjectDpc); - - if (p_Extension->m_AllocatedSpinlocks) - { - NdisFreeSpinLock (&p_Extension->m_QueueLock); - NdisFreeSpinLock (&p_Extension->m_InjectLock); - } -} - -//======================================================================== -// Tap Device Initialization -//======================================================================== - -NDIS_STATUS -CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name) -{ -# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1)) - PDRIVER_DISPATCH *l_Dispatch = NULL; - ANSI_STRING l_TapString, l_LinkString; - UNICODE_STRING l_TapUnicode; - BOOLEAN l_FreeTapUnicode = FALSE; - NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS; - const char *l_UsableName; - - DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - p_Name)); - - NdisZeroMemory (p_Extension, sizeof (TapExtension)); - - INIT_MUTEX (&p_Extension->m_OpenCloseMutex); - - l_LinkString.Buffer = NULL; - l_TapString.Buffer = NULL; - - l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE; - - //======================================= - // Set TAP device entry points - //======================================= - - if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook; - l_Dispatch[IRP_MJ_READ] = TapDeviceHook; - l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook; - l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook; - l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook; - - //================================== - // Find the beginning of the GUID - //================================== - l_UsableName = p_Name; - while (*l_UsableName != '{') - { - if (*l_UsableName == '\0') - { - DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - ++l_UsableName; - } - - //================================== - // Allocate pool for TAP device name - //================================== - - if ((p_Extension->m_TapName = l_TapString.Buffer = - MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //================================================ - // Allocate pool for TAP symbolic link name buffer - //================================================ - - if ((l_LinkString.Buffer = - MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //======================================================= - // Set TAP device name - //======================================================= - - l_Status = RtlStringCchPrintfExA - (l_TapString.Buffer, - l_TapString.MaximumLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, - "%s%s%s", - SYSDEVICEDIR, - l_UsableName, - TAPSUFFIX); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't format TAP device name\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_TapString.Length = (USHORT) strlen (l_TapString.Buffer); - - DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer)); - - //======================================================= - // Set TAP link name - //======================================================= - - l_Status = RtlStringCchPrintfExA - (l_LinkString.Buffer, - l_LinkString.MaximumLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, - "%s%s%s", - USERDEVICEDIR, - l_UsableName, - TAPSUFFIX); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't format TAP device symbolic link\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer); - - DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer)); - - //================================================== - // Convert strings to unicode - //================================================== - if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) != - STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_FreeTapUnicode = TRUE; - - if (RtlAnsiStringToUnicodeString - (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE) - != STATUS_SUCCESS) - { - DEBUGP - (("[%s] Couldn't allocate unicode string for symbolic link name\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - p_Extension->m_CreatedUnicodeLinkName = TRUE; - - //================================================== - // Create new TAP device with symbolic - // link and associate with adapter. - //================================================== - - l_Status = NdisMRegisterDevice - (g_NdisWrapperHandle, - &l_TapUnicode, - &p_Extension->m_UnicodeLinkName, - l_Dispatch, - &p_Extension->m_TapDevice, - &p_Extension->m_TapDeviceHandle - ); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't be created\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - /* Set TAP device flags */ - p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO; - - //======================================================== - // Initialize Packet and IRP queues. - // - // The packet queue is used to buffer data which has been - // "transmitted" by the virtual NIC, before user space - // has had a chance to read it. - // - // The IRP queue is used to buffer pending I/O requests - // from userspace, i.e. read requests on the TAP device - // waiting for the system to "transmit" something through - // the virtual NIC. - // - // Basically, packets in the packet queue are used - // to satisfy IRP requests in the IRP queue. - // - // QueueLock is used to lock the packet queue used - // for the TAP-Win32 NIC -> User Space packet flow direction. - // - // All accesses to packet or IRP queues should be - // bracketed by the QueueLock spinlock, - // in order to be SMP-safe. - //======================================================== - - NdisAllocateSpinLock (&p_Extension->m_QueueLock); - NdisAllocateSpinLock (&p_Extension->m_InjectLock); - p_Extension->m_AllocatedSpinlocks = TRUE; - - p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE); - p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE); - p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE); - if (!p_Extension->m_PacketQueue - || !p_Extension->m_IrpQueue - || !p_Extension->m_InjectQueue) - { - DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //================================================================= - // Initialize deferred procedure call for DHCP/ARP packet injection - //================================================================= - - KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL); - p_Extension->m_InjectDpcInitialized = TRUE; - - //======================== - // Finalize initialization - //======================== - - p_Extension->m_TapIsRunning = TRUE; - - DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name, - p_Extension->m_TapName)); - - cleanup: - if (l_FreeTapUnicode) - RtlFreeUnicodeString (&l_TapUnicode); - if (l_LinkString.Buffer) - MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE); - if (l_Dispatch) - MemFree (l_Dispatch, SIZEOF_DISPATCH); - - if (l_Return != NDIS_STATUS_SUCCESS) - TapDeviceFreeResources (p_Extension); - - return l_Return; -} -#undef SIZEOF_DISPATCH - -//======================================================== -// Adapter Control -//======================================================== -NDIS_STATUS -AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - DEBUGP (("[%s] is resetting\n", NAME (l_Adapter))); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS AdapterReceive - (OUT PNDIS_PACKET p_Packet, - OUT PUINT p_Transferred, - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_HANDLE p_ReceiveContext, - IN UINT p_Offset, - IN UINT p_ToTransfer) -{ - return NDIS_STATUS_SUCCESS; -} - -//============================================================== -// Adapter Option Query/Modification -//============================================================== -NDIS_STATUS AdapterQuery -(IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - TapAdapterQuery l_Query, *l_QueryPtr = &l_Query; - NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS; - UINT l_QueryLength = 4; - BOOLEAN lock_succeeded; - - NdisZeroMemory (&l_Query, sizeof (l_Query)); - - switch (p_OID) - { - //=================================================================== - // Vendor & Driver version Info - //=================================================================== - case OID_GEN_VENDOR_DESCRIPTION: - l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_STRING; - l_QueryLength = strlen (PRODUCT_STRING) + 1; - break; - - case OID_GEN_VENDOR_ID: - l_Query.m_Long = 0xffffff; - break; - - case OID_GEN_DRIVER_VERSION: - l_Query.m_Short = - (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT) - TAP_NDIS_MINOR_VERSION); - l_QueryLength = sizeof (unsigned short); - break; - - case OID_GEN_VENDOR_DRIVER_VERSION: - l_Query.m_Long = - (((USHORT) TAP_DRIVER_MAJOR_VERSION) << 8 | (USHORT) - TAP_DRIVER_MINOR_VERSION); - break; - - //================================================================= - // Statistics - //================================================================= - case OID_GEN_RCV_NO_BUFFER: - l_Query.m_Long = 0; - break; - - case OID_802_3_RCV_ERROR_ALIGNMENT: - l_Query.m_Long = 0; - break; - - case OID_802_3_XMIT_ONE_COLLISION: - l_Query.m_Long = 0; - break; - - case OID_802_3_XMIT_MORE_COLLISIONS: - l_Query.m_Long = 0; - break; - - case OID_GEN_XMIT_OK: - l_Query.m_Long = l_Adapter->m_Tx; - break; - - case OID_GEN_RCV_OK: - l_Query.m_Long = l_Adapter->m_Rx; - break; - - case OID_GEN_XMIT_ERROR: - l_Query.m_Long = l_Adapter->m_TxErr; - break; - - case OID_GEN_RCV_ERROR: - l_Query.m_Long = l_Adapter->m_RxErr; - break; - - //=================================================================== - // Device & Protocol Options - //=================================================================== - case OID_GEN_SUPPORTED_LIST: - l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList; - l_QueryLength = sizeof (g_SupportedOIDList); - break; - - case OID_GEN_MAC_OPTIONS: - // This MUST be here !!! - l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED - | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA - | NDIS_MAC_OPTION_NO_LOOPBACK - | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND); - - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - l_Query.m_Long = - (NDIS_PACKET_TYPE_ALL_LOCAL | - NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL); - - break; - - case OID_GEN_PROTOCOL_OPTIONS: - l_Query.m_Long = 0; - break; - - //================================================================== - // Device Info - //================================================================== - case OID_GEN_MEDIA_CONNECT_STATUS: - l_Query.m_Long = l_Adapter->m_MediaState - ? NdisMediaStateConnected : NdisMediaStateDisconnected; - break; - - case OID_GEN_HARDWARE_STATUS: - l_Query.m_HardwareStatus = NdisHardwareStatusReady; - l_QueryLength = sizeof (NDIS_HARDWARE_STATUS); - break; - - case OID_GEN_MEDIA_SUPPORTED: - case OID_GEN_MEDIA_IN_USE: - l_Query.m_Medium = l_Adapter->m_Medium; - l_QueryLength = sizeof (NDIS_MEDIUM); - break; - - case OID_GEN_PHYSICAL_MEDIUM: - l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified; - l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM); - break; - - case OID_GEN_LINK_SPEED: - l_Query.m_Long = 100000; // rate / 100 bps - break; - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC); - l_QueryLength = sizeof (MACADDR); - break; - - //================================================================== - // Limits - //================================================================== - - case OID_GEN_MAXIMUM_SEND_PACKETS: - l_Query.m_Long = 1; - break; - - case OID_802_3_MAXIMUM_LIST_SIZE: - l_Query.m_Long = NIC_MAX_MCAST_LIST; - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - l_Query.m_Long = l_Adapter->m_Lookahead; - break; - - case OID_GEN_MAXIMUM_LOOKAHEAD: - case OID_GEN_MAXIMUM_TOTAL_SIZE: - case OID_GEN_RECEIVE_BUFFER_SPACE: - case OID_GEN_RECEIVE_BLOCK_SIZE: - l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD; - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - case OID_GEN_TRANSMIT_BLOCK_SIZE: - case OID_GEN_TRANSMIT_BUFFER_SPACE: - l_Query.m_Long = l_Adapter->m_MTU; - break; - - case OID_PNP_CAPABILITIES: - do - { - PNDIS_PNP_CAPABILITIES pPNPCapabilities; - PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct; - - if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES)) - { - pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer); - - // - // Setting up the buffer to be returned - // to the Protocol above the Passthru miniport - // - pPMstruct = &pPNPCapabilities->WakeUpCapabilities; - pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; - } - l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES); - } - while (FALSE); - break; - case OID_PNP_QUERY_POWER: - break; - - // Required OIDs that we don't support - - case OID_GEN_SUPPORTED_GUIDS: - case OID_GEN_MEDIA_CAPABILITIES: - case OID_TCP_TASK_OFFLOAD: - case OID_FFP_SUPPORT: - l_Status = NDIS_STATUS_INVALID_OID; - break; - - // Optional stats OIDs - - case OID_GEN_DIRECTED_BYTES_XMIT: - case OID_GEN_DIRECTED_FRAMES_XMIT: - case OID_GEN_MULTICAST_BYTES_XMIT: - case OID_GEN_MULTICAST_FRAMES_XMIT: - case OID_GEN_BROADCAST_BYTES_XMIT: - case OID_GEN_BROADCAST_FRAMES_XMIT: - case OID_GEN_DIRECTED_BYTES_RCV: - case OID_GEN_DIRECTED_FRAMES_RCV: - case OID_GEN_MULTICAST_BYTES_RCV: - case OID_GEN_MULTICAST_FRAMES_RCV: - case OID_GEN_BROADCAST_BYTES_RCV: - case OID_GEN_BROADCAST_FRAMES_RCV: - l_Status = NDIS_STATUS_INVALID_OID; - break; - - //=================================================================== - // Not Handled - //=================================================================== - default: - DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID)); - l_Status = NDIS_STATUS_INVALID_OID; - break; - } - - if (l_Status != NDIS_STATUS_SUCCESS) - ; - else if (l_QueryLength > p_BufferLength) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = l_QueryLength; - } - else - NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr, - (*p_BytesWritten = l_QueryLength)); - - return l_Status; -} - -NDIS_STATUS AdapterModify -(IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesRead, - OUT PULONG p_BytesNeeded) -{ - TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer; - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID; - ULONG l_Long; - - switch (p_OID) - { - //================================================================== - // Device Info - //================================================================== - case OID_802_3_MULTICAST_LIST: - DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n", - NAME (l_Adapter))); - - *p_BytesNeeded = sizeof (ETH_ADDR); - *p_BytesRead = p_BufferLength; - - if (p_BufferLength % sizeof (ETH_ADDR)) - l_Status = NDIS_STATUS_INVALID_LENGTH; - else if (p_BufferLength > sizeof (MC_LIST)) - { - l_Status = NDIS_STATUS_MULTICAST_FULL; - *p_BytesNeeded = sizeof (MC_LIST); - } - else - { - NdisAcquireSpinLock (&l_Adapter->m_MCLock); - - NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST)); - - NdisMoveMemory(&l_Adapter->m_MCList, - p_Buffer, - p_BufferLength); - - l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR); - - NdisReleaseSpinLock (&l_Adapter->m_MCLock); - - l_Status = NDIS_STATUS_SUCCESS; - } - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = 4; - - if (p_BufferLength >= sizeof (ULONG)) - { - DEBUGP - (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n", - NAME (l_Adapter), l_Query->m_Long)); - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = sizeof (ULONG); - } - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - if (p_BufferLength < sizeof (ULONG)) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = 4; - } - else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD - || l_Query->m_Long <= 0) - { - l_Status = NDIS_STATUS_INVALID_DATA; - } - else - { - DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n", - NAME (l_Adapter), l_Query->m_Long)); - l_Adapter->m_Lookahead = l_Query->m_Long; - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = sizeof (ULONG); - } - break; - - case OID_GEN_NETWORK_LAYER_ADDRESSES: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - case OID_GEN_TRANSPORT_HEADER_OFFSET: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - case OID_PNP_SET_POWER: - do - { - NDIS_DEVICE_POWER_STATE NewDeviceState; - - NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer); - - switch (NewDeviceState) - { - case NdisDeviceStateD0: - l_Adapter->m_DeviceState = '0'; - break; - case NdisDeviceStateD1: - l_Adapter->m_DeviceState = '1'; - break; - case NdisDeviceStateD2: - l_Adapter->m_DeviceState = '2'; - break; - case NdisDeviceStateD3: - l_Adapter->m_DeviceState = '3'; - break; - default: - l_Adapter->m_DeviceState = '?'; - break; - } - - l_Status = NDIS_STATUS_FAILURE; - - // - // Check for invalid length - // - if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE)) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - if (NewDeviceState > NdisDeviceStateD0) - { - l_Adapter->m_InterfaceIsRunning = FALSE; - DEBUGP (("[%s] Power management device state OFF\n", - NAME (l_Adapter))); - } - else - { - l_Adapter->m_InterfaceIsRunning = TRUE; - DEBUGP (("[%s] Power management device state ON\n", - NAME (l_Adapter))); - } - - l_Status = NDIS_STATUS_SUCCESS; - } - while (FALSE); - - if (l_Status == NDIS_STATUS_SUCCESS) - { - *p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE); - *p_BytesNeeded = 0; - } - else - { - *p_BytesRead = 0; - *p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); - } - break; - - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - case OID_PNP_ADD_WAKE_UP_PATTERN: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - default: - DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter), - p_OID)); - l_Status = NDIS_STATUS_INVALID_OID; - *p_BytesRead = *p_BytesNeeded = 0; - break; - } - - return l_Status; -} - -// checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum -// see RFC 4443, 2.3, and RFC 2460, 8.1 -USHORT -icmpv6_checksum (const UCHAR *buf, - const int len_icmpv6, - const UCHAR *saddr6, - const UCHAR *daddr6) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words and - // calculate the sum of all 16 bit words - for (i = 0; i < len_icmpv6; i += 2){ - word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0); - sum += word16; - } - - // add the IPv6 pseudo header which contains the IP source and destination addresses - for (i = 0; i < 16; i += 2){ - word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF); - sum += word16; - } - for (i = 0; i < 16; i += 2){ - word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF); - sum += word16; - } - - // the next-header number and the length of the ICMPv6 packet - sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6; - - // keep only the last 16 bits of the 32 bit calculated sum and add the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // Take the one's complement of sum - return ((USHORT) ~sum); -} - -// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that -// the tap driver needs to answer?" -// see RFC 4861 4.3 for the different cases -static IPV6ADDR IPV6_NS_TARGET_MCAST = - { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 }; -static IPV6ADDR IPV6_NS_TARGET_UNICAST = - { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; - -BOOLEAN -HandleIPv6NeighborDiscovery( TapAdapterPointer p_Adapter, UCHAR * m_Data ) -{ - const ETH_HEADER * e = (ETH_HEADER *) m_Data; - const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER)); - const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR)); - ICMPV6_NA_PKT *na; - USHORT icmpv6_len, icmpv6_csum; - - // we don't really care about the destination MAC address here - // - it's either a multicast MAC, or the userland destination MAC - // but since the TAP driver is point-to-point, all packets are "for us" - - // IPv6 target address must be ff02::1::ff00:8 (multicast for - // initial NS) or fe80::1 (unicast for recurrent NUD) - if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST, - sizeof(IPV6ADDR) ) != 0 && - memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ) != 0 ) - { - return FALSE; // wrong target address - } - - // IPv6 Next-Header must be ICMPv6 - if ( ipv6->nexthdr != IPPROTO_ICMPV6 ) - { - return FALSE; // wrong next-header - } - - // ICMPv6 type+code must be 135/0 for NS - if ( icmpv6_ns->type != ICMPV6_TYPE_NS || - icmpv6_ns->code != ICMPV6_CODE_0 ) - { - return FALSE; // wrong ICMPv6 type - } - - // ICMPv6 target address must be fe80::8 (magic) - if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ) != 0 ) - { - return FALSE; // not for us - } - - // packet identified, build magic response packet - - na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE); - if ( !na ) return FALSE; - - //------------------------------------------------ - // Initialize Neighbour Advertisement reply packet - //------------------------------------------------ - - // ethernet header - na->eth.proto = htons(ETH_P_IPV6); - COPY_MAC(na->eth.dest, p_Adapter->m_MAC); - COPY_MAC(na->eth.src, p_Adapter->m_TapToUser.dest); - - // IPv6 header - na->ipv6.version_prio = ipv6->version_prio; - NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl, - sizeof(na->ipv6.flow_lbl) ); - icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR); - na->ipv6.payload_len = htons(icmpv6_len); - na->ipv6.nexthdr = IPPROTO_ICMPV6; - na->ipv6.hop_limit = 255; - NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ); - NdisMoveMemory( na->ipv6.daddr, ipv6->saddr, - sizeof(IPV6ADDR) ); - - // ICMPv6 - na->icmpv6.type = ICMPV6_TYPE_NA; - na->icmpv6.code = ICMPV6_CODE_0; - na->icmpv6.checksum = 0; - na->icmpv6.rso_bits = 0x60; // Solicited + Override - NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) ); - NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ); - - // ICMPv6 option "Target Link Layer Address" - na->icmpv6.opt_type = ICMPV6_OPTION_TLLA; - na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA; - COPY_MAC( na->icmpv6.target_macaddr, p_Adapter->m_TapToUser.dest ); - - // calculate and set checksum - icmpv6_csum = icmpv6_checksum ( (UCHAR*) &(na->icmpv6), - icmpv6_len, - na->ipv6.saddr, - na->ipv6.daddr ); - na->icmpv6.checksum = htons( icmpv6_csum ); - - DUMP_PACKET ("HandleIPv6NeighborDiscovery", - (unsigned char *) na, - sizeof (ICMPV6_NA_PKT)); - - InjectPacketDeferred (p_Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT)); - - MemFree (na, sizeof (ICMPV6_NA_PKT)); - - return TRUE; // all fine -} - -//==================================================================== -// Adapter Transmission -//==================================================================== -NDIS_STATUS -AdapterTransmit (IN NDIS_HANDLE p_AdapterContext, - IN PNDIS_PACKET p_Packet, - IN UINT p_Flags) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - ULONG l_Index = 0, l_PacketLength = 0; - UINT l_BufferLength = 0; - PIRP l_IRP; - TapPacketPointer l_PacketBuffer; - PNDIS_BUFFER l_NDIS_Buffer; - PUCHAR l_Buffer; - PVOID result; - - NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength); - - //==================================================== - // Here we abandon the transmission attempt if any of - // the parameters is wrong or memory allocation fails - // but we do not indicate failure. The packet is - // silently dropped. - //==================================================== - - if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535) - goto exit_fail; - else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState) - goto exit_success; // Nothing is bound to the TAP device - - if (NdisAllocateMemoryWithTag (&l_PacketBuffer, - TAP_PACKET_SIZE (l_PacketLength), - '5PAT') != NDIS_STATUS_SUCCESS) - goto exit_no_resources; - - if (l_PacketBuffer == NULL) - goto exit_no_resources; - - l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK); - - //=========================== - // Reassemble packet contents - //=========================== - - __try - { - l_Index = 0; - while (l_NDIS_Buffer && l_Index < l_PacketLength) - { - ULONG newlen; - NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer, - &l_BufferLength); - newlen = l_Index + l_BufferLength; - if (newlen > l_PacketLength) - { - NOTE_ERROR (); - goto no_queue; /* overflow */ - } - NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer, - l_BufferLength); - l_Index = newlen; - NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer); - } - if (l_Index != l_PacketLength) - { - NOTE_ERROR (); - goto no_queue; /* underflow */ - } - - DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc); -#endif - - //===================================================== - // Are we running in DHCP server masquerade mode? - // - // If so, catch both DHCP requests and ARP queries - // to resolve the address of our virtual DHCP server. - //===================================================== - if (l_Adapter->m_dhcp_enabled) - { - const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data; - const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER)); - const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR)); - - // ARP packet? - if (l_PacketLength == sizeof (ARP_PACKET) - && eth->proto == htons (ETH_P_ARP) - && l_Adapter->m_dhcp_server_arp) - { - if (ProcessARP (l_Adapter, - (PARP_PACKET) l_PacketBuffer->m_Data, - l_Adapter->m_dhcp_addr, - l_Adapter->m_dhcp_server_ip, - ~0, - l_Adapter->m_dhcp_server_mac)) - goto no_queue; - } - - // DHCP packet? - else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) - && eth->proto == htons (ETH_P_IP) - && ip->version_len == 0x45 // IPv4, 20 byte header - && ip->protocol == IPPROTO_UDP - && udp->dest == htons (BOOTPS_PORT)) - { - const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data - + sizeof (ETH_HEADER) - + sizeof (IPHDR) - + sizeof (UDPHDR)); - - const int optlen = l_PacketLength - - sizeof (ETH_HEADER) - - sizeof (IPHDR) - - sizeof (UDPHDR) - - sizeof (DHCP); - - if (optlen > 0) // we must have at least one DHCP option - { - if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen)) - goto no_queue; - } - else - goto no_queue; - } - } - - //=============================================== - // In Point-To-Point mode, check to see whether - // packet is ARP (handled) or IPv4 (sent to app). - // IPv6 packets are inspected for neighbour discovery - // (to be handled locally), and the rest is forwarded - // all other protocols are dropped - //=============================================== - if (l_Adapter->m_tun) - { - ETH_HEADER *e; - - if (l_PacketLength < ETHERNET_HEADER_SIZE) - goto no_queue; - - e = (ETH_HEADER *) l_PacketBuffer->m_Data; - - switch (ntohs (e->proto)) - { - case ETH_P_ARP: - - // Make sure that packet is the - // right size for ARP. - if (l_PacketLength != sizeof (ARP_PACKET)) - goto no_queue; - - ProcessARP (l_Adapter, - (PARP_PACKET) l_PacketBuffer->m_Data, - l_Adapter->m_localIP, - l_Adapter->m_remoteNetwork, - l_Adapter->m_remoteNetmask, - l_Adapter->m_TapToUser.dest); - - default: - goto no_queue; - - case ETH_P_IP: - - // Make sure that packet is large - // enough to be IPv4. - if (l_PacketLength - < ETHERNET_HEADER_SIZE + IP_HEADER_SIZE) - goto no_queue; - - // Only accept directed packets, - // not broadcasts. - if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE)) - goto no_queue; - - // Packet looks like IPv4, queue it. - l_PacketBuffer->m_SizeFlags |= TP_TUN; - - case ETH_P_IPV6: - // make sure that packet is large - // enough to be IPv6 - if (l_PacketLength - < ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE) - goto no_queue; - - // broadcasts and multicasts are handled specially - // (to be implemented) - - // neighbor discovery packets to fe80::8 are special - // OpenVPN sets this next-hop to signal "handled by tapdrv" - if ( HandleIPv6NeighborDiscovery( l_Adapter, - l_PacketBuffer->m_Data )) - { - goto no_queue; - } - - // Packet looks like IPv6, queue it :-) - l_PacketBuffer->m_SizeFlags |= TP_TUN; - } - } - - //=============================================== - // Push packet onto queue to wait for read from - // userspace. - //=============================================== - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - result = NULL; - if (IS_UP (l_Adapter)) - result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer); - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if ((TapPacketPointer) result != l_PacketBuffer) - { - // adapter receive overrun - INCREMENT_STAT (l_Adapter->m_TxErr); - goto no_queue; - } - else - { - INCREMENT_STAT (l_Adapter->m_Tx); - } - - //============================================================ - // Cycle through IRPs and packets, try to satisfy each pending - // IRP with a queued packet. - //============================================================ - while (TRUE) - { - l_IRP = NULL; - l_PacketBuffer = NULL; - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueueCount (l_Adapter->m_Extension.m_PacketQueue) - && QueueCount (l_Adapter->m_Extension.m_IrpQueue)) - { - l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue); - l_PacketBuffer = (TapPacketPointer) - QueuePop (l_Adapter->m_Extension.m_PacketQueue); - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1); - - if (l_IRP && l_PacketBuffer) - { - CompleteIRP (l_IRP, - l_PacketBuffer, - IO_NETWORK_INCREMENT); - } - else - break; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - - return NDIS_STATUS_SUCCESS; - - no_queue: - NdisFreeMemory (l_PacketBuffer, - TAP_PACKET_SIZE (l_PacketLength), - 0); - - exit_success: - return NDIS_STATUS_SUCCESS; - - exit_fail: - return NDIS_STATUS_FAILURE; - - exit_no_resources: - return NDIS_STATUS_RESOURCES; -} - -//====================================================================== -// Hooks for catching TAP device IRP's. -//====================================================================== - -NTSTATUS -TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP) -{ - TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); - PIO_STACK_LOCATION l_IrpSp; - NTSTATUS l_Status = STATUS_SUCCESS; - BOOLEAN accessible; - - l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP); - - p_IRP->IoStatus.Status = STATUS_SUCCESS; - p_IRP->IoStatus.Information = 0; - - if (!l_Adapter || l_Adapter->m_Extension.m_Halt) - { - DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n", - (int)l_IrpSp->MajorFunction)); - - if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE) - { - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - else - { - p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - return STATUS_NO_SUCH_DEVICE; - } - } - - switch (l_IrpSp->MajorFunction) - { - //=========================================================== - // Ioctl call handlers - //=========================================================== - case IRP_MJ_DEVICE_CONTROL: - { - switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode) - { - case TAP_IOCTL_GET_MAC: - { - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= sizeof (MACADDR)) - { - COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer, - l_Adapter->m_MAC); - p_IRP->IoStatus.Information = sizeof (MACADDR); - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - break; - } - case TAP_IOCTL_GET_VERSION: - { - const ULONG size = sizeof (ULONG) * 3; - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= size) - { - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] - = TAP_DRIVER_MAJOR_VERSION; - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1] - = TAP_DRIVER_MINOR_VERSION; - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2] -#if DBG - = 1; -#else - = 0; -#endif - p_IRP->IoStatus.Information = size; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - break; - } - case TAP_IOCTL_GET_MTU: - { - const ULONG size = sizeof (ULONG) * 1; - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= size) - { - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] - = l_Adapter->m_MTU; - p_IRP->IoStatus.Information = size; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - break; - } - case TAP_IOCTL_GET_INFO: - { - char state[16]; - if (l_Adapter->m_InterfaceIsRunning) - state[0] = 'A'; - else - state[0] = 'a'; - if (l_Adapter->m_Extension.m_TapIsRunning) - state[1] = 'T'; - else - state[1] = 't'; - state[2] = l_Adapter->m_DeviceState; - if (l_Adapter->m_MediaStateAlwaysConnected) - state[3] = 'C'; - else - state[3] = 'c'; - state[4] = '\0'; - - p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA ( - ((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)), - l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, -#if PACKET_TRUNCATION_CHECK - "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", -#else - "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", -#endif - state, - g_LastErrorFilename, - g_LastErrorLineNumber, - (int)l_Adapter->m_Extension.m_NumTapOpens, - (int)l_Adapter->m_Tx, - (int)l_Adapter->m_TxErr, -#if PACKET_TRUNCATION_CHECK - (int)l_Adapter->m_TxTrunc, -#endif - (int)l_Adapter->m_Rx, - (int)l_Adapter->m_RxErr, -#if PACKET_TRUNCATION_CHECK - (int)l_Adapter->m_RxTrunc, -#endif - (int)l_Adapter->m_Extension.m_IrpQueue->size, - (int)l_Adapter->m_Extension.m_IrpQueue->max_size, - (int)IRP_QUEUE_SIZE, - (int)l_Adapter->m_Extension.m_PacketQueue->size, - (int)l_Adapter->m_Extension.m_PacketQueue->max_size, - (int)PACKET_QUEUE_SIZE, - (int)l_Adapter->m_Extension.m_InjectQueue->size, - (int)l_Adapter->m_Extension.m_InjectQueue->max_size, - (int)INJECT_QUEUE_SIZE - ); - - p_IRP->IoStatus.Information - = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; - - break; - } - -#if DBG - case TAP_IOCTL_GET_LOG_LINE: - { - if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength)) - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - else - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - - p_IRP->IoStatus.Information - = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; - - break; - } -#endif - - case TAP_IOCTL_CONFIG_TUN: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 3)) - { - MACADDR dest; - - l_Adapter->m_tun = FALSE; - - GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); - - l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; - - // sanity check on network/netmask - if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork) - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - break; - } - - COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); - COPY_MAC (l_Adapter->m_TapToUser.dest, dest); - COPY_MAC (l_Adapter->m_UserToTap.src, dest); - COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); - - l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); - l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; - l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); - - l_Adapter->m_tun = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } - - case TAP_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_IOCTL_CONFIG_TUN - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 2)) - { - MACADDR dest; - - l_Adapter->m_tun = FALSE; - - GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); - - l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - l_Adapter->m_remoteNetmask = ~0; - - COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); - COPY_MAC (l_Adapter->m_TapToUser.dest, dest); - COPY_MAC (l_Adapter->m_UserToTap.src, dest); - COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); - - l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); - l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; - l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); - - l_Adapter->m_tun = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } - - case TAP_IOCTL_SET_MEDIA_STATUS: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (ULONG) * 1)) - { - ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - SetMediaStatus (l_Adapter, (BOOLEAN) parm); - p_IRP->IoStatus.Information = 1; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - break; - } - - case TAP_IOCTL_CONFIG_DHCP_MASQ: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 4)) - { - l_Adapter->m_dhcp_enabled = FALSE; - l_Adapter->m_dhcp_server_arp = FALSE; - l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - - // Adapter IP addr / netmask - l_Adapter->m_dhcp_addr = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_dhcp_netmask = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - - // IP addr of DHCP masq server - l_Adapter->m_dhcp_server_ip = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; - - // Lease time in seconds - l_Adapter->m_dhcp_lease_time = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3]; - - GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2); - - l_Adapter->m_dhcp_enabled = TRUE; - l_Adapter->m_dhcp_server_arp = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } - - case TAP_IOCTL_CONFIG_DHCP_SET_OPT: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <= - DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE - && l_Adapter->m_dhcp_enabled) - { - l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - - NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer, - p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.DeviceIoControl.InputBufferLength); - - l_Adapter->m_dhcp_user_supplied_options_buffer_len = - l_IrpSp->Parameters.DeviceIoControl.InputBufferLength; - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } - - default: - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - break; - } - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //=========================================================== - // User mode thread issued a read request on the tap device - // If there are packets waiting to be read, then the request - // will be satisfied here. If not, then the request will be - // queued and satisfied by any packet that is not used to - // satisfy requests ahead of it. - //=========================================================== - case IRP_MJ_READ: - { - TapPacketPointer l_PacketBuffer; - BOOLEAN pending = FALSE; - - // Save IRP-accessible copy of buffer length - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length; - - if (p_IRP->MdlAddress == NULL) - { - DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - else if ((p_IRP->AssociatedIrp.SystemBuffer = - MmGetSystemAddressForMdlSafe - (p_IRP->MdlAddress, NormalPagePriority)) == NULL) - { - DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - else if (!l_Adapter->m_InterfaceIsRunning) - { - DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //================================== - // Can we provide immediate service? - //================================== - - l_PacketBuffer = NULL; - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueueCount (l_Adapter->m_Extension.m_PacketQueue) - && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0) - { - l_PacketBuffer = (TapPacketPointer) - QueuePop (l_Adapter->m_Extension.m_PacketQueue); - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (l_PacketBuffer) - { - l_Status = CompleteIRP (p_IRP, - l_PacketBuffer, - IO_NO_INCREMENT); - break; - } - - //============================= - // Attempt to pend read request - //============================= - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP) - { - IoSetCancelRoutine (p_IRP, CancelIRPCallback); - l_Status = STATUS_PENDING; - IoMarkIrpPending (p_IRP); - pending = TRUE; - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (pending) - break; - - // Can't queue anymore IRP's - DEBUGP (("[%s] TAP [%s] read IRP overrun\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapName)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //============================================================== - // User mode issued a WriteFile request on the TAP file handle. - // The request will always get satisfied here. The call may - // fail if there are too many pending packets (queue full). - //============================================================== - case IRP_MJ_WRITE: - { - if (p_IRP->MdlAddress == NULL) - { - DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - p_IRP->IoStatus.Information = 0; - } - else if ((p_IRP->AssociatedIrp.SystemBuffer = - MmGetSystemAddressForMdlSafe - (p_IRP->MdlAddress, NormalPagePriority)) == NULL) - { - DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; - p_IRP->IoStatus.Information = 0; - } - else if (!l_Adapter->m_InterfaceIsRunning) - { - DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE)) - { - __try - { - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; - - DUMP_PACKET ("IRP_MJ_WRITE ETH", - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - FALSE, - "RX", - &l_Adapter->m_RxTrunc); -#endif - - NdisMEthIndicateReceive - (l_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) l_Adapter, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - ETHERNET_HEADER_SIZE, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE, - l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE, - l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE); - - NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); - - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } - else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE)) - { - __try - { - ETH_HEADER * p_UserToTap = &l_Adapter->m_UserToTap; - - // for IPv6, need to use ethernet header with IPv6 proto - if ( IPH_GET_VER( ((IPHDR*) p_IRP->AssociatedIrp.SystemBuffer)->version_len) == 6 ) - { - p_UserToTap = &l_Adapter->m_UserToTap_IPv6; - } - - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; - - DUMP_PACKET2 ("IRP_MJ_WRITE P2P", - p_UserToTap, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - TRUE, - "RX", - &l_Adapter->m_RxTrunc); -#endif - - NdisMEthIndicateReceive - (l_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) l_Adapter, - (unsigned char *) p_UserToTap, - sizeof (ETH_HEADER), - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - l_IrpSp->Parameters.Write.Length); - - NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); - - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } - else - { - DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n", - NAME (l_Adapter), - l_IrpSp->Parameters.Write.Length)); - NOTE_ERROR (); - p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE; - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - if (l_Status == STATUS_SUCCESS) - INCREMENT_STAT (l_Adapter->m_Rx); - else - INCREMENT_STAT (l_Adapter->m_RxErr); - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //-------------------------------------------------------------- - // User mode thread has called CreateFile() on the tap device - //-------------------------------------------------------------- - case IRP_MJ_CREATE: - { - BOOLEAN succeeded = FALSE; - BOOLEAN mutex_succeeded; - - DEBUGP - (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n", - NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens)); - - ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); - if (mutex_succeeded) - { - if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens) - { - ResetTapAdapterState (l_Adapter); - l_Adapter->m_Extension.m_TapOpens = 1; - succeeded = TRUE; - } - - if (succeeded) - { - INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens); - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - p_IRP->IoStatus.Information = 0; - } - else - { - DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); - } - else - { - DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //----------------------------------------------------------- - // User mode thread called CloseHandle() on the tap device - //----------------------------------------------------------- - case IRP_MJ_CLOSE: - { - BOOLEAN mutex_succeeded; - - DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n", - NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION)); - - ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); - if (mutex_succeeded) - { - l_Adapter->m_Extension.m_TapOpens = 0; - ResetTapAdapterState (l_Adapter); - FlushQueues (&l_Adapter->m_Extension); - SetMediaStatus (l_Adapter, FALSE); - RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); - } - else - { - DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //------------------ - // Strange Request - //------------------ - default: - { - //NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - } - - return l_Status; -} - -//============================================================= -// CompleteIRP is normally called with an adapter -> userspace -// network packet and an IRP (Pending I/O request) from userspace. -// -// The IRP will normally represent a queued overlapped read -// operation from userspace that is in a wait state. -// -// Use the ethernet packet to satisfy the IRP. -//============================================================= - -NTSTATUS -CompleteIRP (IN PIRP p_IRP, - IN TapPacketPointer p_PacketBuffer, - IN CCHAR PriorityBoost) -{ - NTSTATUS l_Status = STATUS_UNSUCCESSFUL; - - int offset; - int len; - - MYASSERT (p_IRP); - MYASSERT (p_PacketBuffer); - - IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine - - //------------------------------------------- - // While p_PacketBuffer always contains a - // full ethernet packet, including the - // ethernet header, in point-to-point mode, - // we only want to return the IPv4 - // component. - //------------------------------------------- - - if (p_PacketBuffer->m_SizeFlags & TP_TUN) - { - offset = ETHERNET_HEADER_SIZE; - len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE; - } - else - { - offset = 0; - len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK); - } - - if (len < 0 || (int) p_IRP->IoStatus.Information < len) - { - p_IRP->IoStatus.Information = 0; - p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - NOTE_ERROR (); - } - else - { - p_IRP->IoStatus.Information = len; - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - - __try - { - NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer, - p_PacketBuffer->m_Data + offset, - len); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } - - __try - { - NdisFreeMemory (p_PacketBuffer, - TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK), - 0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - - if (l_Status == STATUS_SUCCESS) - { - IoCompleteRequest (p_IRP, PriorityBoost); - } - else - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - - return l_Status; -} - -//============================================== -// IRPs get cancelled for a number of reasons. -// -// The TAP device could be closed by userspace -// when there are still pending read operations. -// -// The user could disable the TAP adapter in the -// network connections control panel, while the -// device is still open by a process. -//============================================== -VOID -CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP) -{ - TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); - CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE); -} - -VOID -CancelIRP (TapExtensionPointer p_Extension, - IN PIRP p_IRP, - BOOLEAN callback) -{ - BOOLEAN exists = FALSE; - - MYASSERT (p_IRP); - - if (p_Extension) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - } - else - exists = TRUE; - - if (exists) - { - IoSetCancelRoutine (p_IRP, NULL); - p_IRP->IoStatus.Status = STATUS_CANCELLED; - p_IRP->IoStatus.Information = 0; - } - - if (callback) - IoReleaseCancelSpinLock (p_IRP->CancelIrql); - - if (exists) - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); -} - -//=========================================== -// Exhaust packet, IRP, and injection queues. -//=========================================== -VOID -FlushQueues (TapExtensionPointer p_Extension) -{ - PIRP l_IRP; - TapPacketPointer l_PacketBuffer; - InjectPacketPointer l_InjectBuffer; - int n_IRP=0, n_Packet=0, n_Inject=0; - - MYASSERT (p_Extension); - MYASSERT (p_Extension->m_TapDevice); - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - l_IRP = QueuePop (p_Extension->m_IrpQueue); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - if (l_IRP) - { - ++n_IRP; - CancelIRP (NULL, l_IRP, FALSE); - } - else - break; - } - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - if (l_PacketBuffer) - { - ++n_Packet; - MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK)); - } - else - break; - } - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_InjectLock); - l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue); - NdisReleaseSpinLock (&p_Extension->m_InjectLock); - if (l_InjectBuffer) - { - ++n_Inject; - INJECT_PACKET_FREE(l_InjectBuffer); - } - else - break; - } - - DEBUGP (( - "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n", - p_Extension->m_TapName, - n_IRP, - p_Extension->m_IrpQueue->max_size, - IRP_QUEUE_SIZE, - n_Packet, - p_Extension->m_PacketQueue->max_size, - PACKET_QUEUE_SIZE, - n_Inject, - p_Extension->m_InjectQueue->max_size, - INJECT_QUEUE_SIZE - )); -} - -//=================================================== -// Tell Windows whether the TAP device should be -// considered "connected" or "disconnected". -//=================================================== -VOID -SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state) -{ - if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected) - { - if (state) - NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, - NDIS_STATUS_MEDIA_CONNECT, NULL, 0); - else - NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, - NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0); - - NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle); - p_Adapter->m_MediaState = state; - } -} - - -//====================================================== -// If DHCP mode is used together with tun -// mode, consider the fact that the P2P remote subnet -// might enclose the DHCP masq server address. -//====================================================== -VOID -CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter) -{ - if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled) - { - if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork) - { - COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest); - p_Adapter->m_dhcp_server_arp = FALSE; - } - } -} - -//=================================================== -// Generate an ARP reply message for specific kinds -// ARP queries. -//=================================================== -BOOLEAN -ProcessARP (TapAdapterPointer p_Adapter, - const PARP_PACKET src, - const IPADDR adapter_ip, - const IPADDR ip_network, - const IPADDR ip_netmask, - const MACADDR mac) -{ - //----------------------------------------------- - // Is this the kind of packet we are looking for? - //----------------------------------------------- - if (src->m_Proto == htons (ETH_P_ARP) - && MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC) - && MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC) - && MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast) - && src->m_ARP_Operation == htons (ARP_REQUEST) - && src->m_MAC_AddressType == htons (MAC_ADDR_TYPE) - && src->m_MAC_AddressSize == sizeof (MACADDR) - && src->m_PROTO_AddressType == htons (ETH_P_IP) - && src->m_PROTO_AddressSize == sizeof (IPADDR) - && src->m_ARP_IP_Source == adapter_ip - && (src->m_ARP_IP_Destination & ip_netmask) == ip_network - && src->m_ARP_IP_Destination != adapter_ip) - { - ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE); - if (arp) - { - //---------------------------------------------- - // Initialize ARP reply fields - //---------------------------------------------- - arp->m_Proto = htons (ETH_P_ARP); - arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE); - arp->m_PROTO_AddressType = htons (ETH_P_IP); - arp->m_MAC_AddressSize = sizeof (MACADDR); - arp->m_PROTO_AddressSize = sizeof (IPADDR); - arp->m_ARP_Operation = htons (ARP_REPLY); - - //---------------------------------------------- - // ARP addresses - //---------------------------------------------- - COPY_MAC (arp->m_MAC_Source, mac); - COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC); - COPY_MAC (arp->m_ARP_MAC_Source, mac); - COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC); - arp->m_ARP_IP_Source = src->m_ARP_IP_Destination; - arp->m_ARP_IP_Destination = adapter_ip; - - DUMP_PACKET ("ProcessARP", - (unsigned char *) arp, - sizeof (ARP_PACKET)); - - InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET)); - - MemFree (arp, sizeof (ARP_PACKET)); - } - - return TRUE; - } - else - return FALSE; -} - -//=============================================================== -// Used in cases where internally generated packets such as -// ARP or DHCP replies must be returned to the kernel, to be -// seen as an incoming packet "arriving" on the interface. -//=============================================================== - -// Defer packet injection till IRQL < DISPATCH_LEVEL -VOID -InjectPacketDeferred (TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len) -{ - InjectPacketPointer l_InjectBuffer; - PVOID result; - - if (NdisAllocateMemoryWithTag (&l_InjectBuffer, - INJECT_PACKET_SIZE (len), - 'IPAT') == NDIS_STATUS_SUCCESS) - { - l_InjectBuffer->m_Size = len; - NdisMoveMemory (l_InjectBuffer->m_Data, packet, len); - NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock); - result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer); - NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock); - if (result) - KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL); - else - INJECT_PACKET_FREE(l_InjectBuffer); - } -} - -// Handle the injection of previously deferred packets -VOID -InjectPacketDpc(KDPC *Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - InjectPacketPointer l_InjectBuffer; - TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1; - while (TRUE) - { - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock); - l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue); - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock); - if (l_InjectBuffer) - { - InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size); - INJECT_PACKET_FREE(l_InjectBuffer); - } - else - break; - } -} - -// Do packet injection now -VOID -InjectPacketNow (TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len) -{ - MYASSERT (len >= ETHERNET_HEADER_SIZE); - - __try - { - //------------------------------------------------------------ - // NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete - // could potentially be called reentrantly both here and in - // TapDeviceHook/IRP_MJ_WRITE. - // - // The DDK docs imply that this is okay. - // - // Note that reentrant behavior could only occur if the - // non-deferred version of InjectPacket is used. - //------------------------------------------------------------ - NdisMEthIndicateReceive - (p_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) p_Adapter, - packet, - ETHERNET_HEADER_SIZE, - packet + ETHERNET_HEADER_SIZE, - len - ETHERNET_HEADER_SIZE, - len - ETHERNET_HEADER_SIZE); - - NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n", - NAME (p_Adapter))); - NOTE_ERROR (); - } -} - -//=================================================================== -// Go back to default TAP mode from Point-To-Point mode. -// Also reset (i.e. disable) DHCP Masq mode. -//=================================================================== -VOID ResetTapAdapterState (TapAdapterPointer p_Adapter) -{ - // Point-To-Point - p_Adapter->m_tun = FALSE; - p_Adapter->m_localIP = 0; - p_Adapter->m_remoteNetwork = 0; - p_Adapter->m_remoteNetmask = 0; - NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser)); - NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap)); - NdisZeroMemory (&p_Adapter->m_UserToTap_IPv6, sizeof (p_Adapter->m_UserToTap_IPv6)); - - // DHCP Masq - p_Adapter->m_dhcp_enabled = FALSE; - p_Adapter->m_dhcp_server_arp = FALSE; - p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - p_Adapter->m_dhcp_addr = 0; - p_Adapter->m_dhcp_netmask = 0; - p_Adapter->m_dhcp_server_ip = 0; - p_Adapter->m_dhcp_lease_time = 0; - p_Adapter->m_dhcp_received_discover = FALSE; - p_Adapter->m_dhcp_bad_requests = 0; - NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR)); -} - -#if ENABLE_NONADMIN - -//=================================================================== -// Set TAP device handle to be accessible without admin privileges. -//=================================================================== -VOID AllowNonAdmin (TapExtensionPointer p_Extension) -{ - NTSTATUS stat; - SECURITY_DESCRIPTOR sd; - OBJECT_ATTRIBUTES oa; - IO_STATUS_BLOCK isb; - HANDLE hand = NULL; - - NdisZeroMemory (&sd, sizeof (sd)); - NdisZeroMemory (&oa, sizeof (oa)); - NdisZeroMemory (&isb, sizeof (isb)); - - if (!p_Extension->m_CreatedUnicodeLinkName) - { - DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n")); - NOTE_ERROR (); - return; - } - - stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n")); - NOTE_ERROR (); - return; - } - - InitializeObjectAttributes ( - &oa, - &p_Extension->m_UnicodeLinkName, - OBJ_KERNEL_HANDLE, - NULL, - NULL - ); - - stat = ZwOpenFile ( - &hand, - WRITE_DAC, - &oa, - &isb, - 0, - 0 - ); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat)); - NOTE_ERROR (); - return; - } - - stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n")); - NOTE_ERROR (); - return; - } - - stat = ZwClose (hand); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n")); - NOTE_ERROR (); - return; - } - - DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n")); -} - -#endif - -#if PACKET_TRUNCATION_CHECK - -VOID -IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter) -{ - const IPHDR *ip; - int len = length; - - if (tun) - { - ip = (IPHDR *) data; - } - else - { - if (length >= sizeof (ETH_HEADER)) - { - const ETH_HEADER *eth = (ETH_HEADER *) data; - - if (eth->proto != htons (ETH_P_IP)) - return; - - ip = (IPHDR *) (data + sizeof (ETH_HEADER)); - len -= sizeof (ETH_HEADER); - } - else - return; - } - - if (len >= sizeof (IPHDR)) - { - const int totlen = ntohs (ip->tot_len); - - DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen)); - - if (len != totlen) - ++(*counter); - } -} - -#endif - -//====================================================================== -// End of Source -//====================================================================== diff --git a/tap-win32/types.h b/tap-win32/types.h deleted file mode 100755 index bdc08e7..0000000 --- a/tap-win32/types.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * 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 TAP_TYPES_DEFINED -#define TAP_TYPES_DEFINED - -typedef struct _Queue -{ - ULONG base; - ULONG size; - ULONG capacity; - ULONG max_size; - PVOID data[]; -} Queue; - -typedef struct _TapAdapter; -typedef struct _TapPacket; - -typedef union _TapAdapterQuery -{ - NDIS_HARDWARE_STATUS m_HardwareStatus; - NDIS_MEDIUM m_Medium; - NDIS_PHYSICAL_MEDIUM m_PhysicalMedium; - UCHAR m_MacAddress [6]; - UCHAR m_Buffer [256]; - ULONG m_Long; - USHORT m_Short; - UCHAR m_Byte; -} -TapAdapterQuery, *TapAdapterQueryPointer; - -typedef struct _TapExtension -{ - // TAP device object and packet queues - Queue *m_PacketQueue, *m_IrpQueue; - PDEVICE_OBJECT m_TapDevice; - NDIS_HANDLE m_TapDeviceHandle; - ULONG m_TapOpens; - - // Used to lock packet queues - NDIS_SPIN_LOCK m_QueueLock; - BOOLEAN m_AllocatedSpinlocks; - - // Used to bracket open/close - // state changes. - MUTEX m_OpenCloseMutex; - - // True if device has been permanently halted - BOOLEAN m_Halt; - - // TAP device name - unsigned char *m_TapName; - UNICODE_STRING m_UnicodeLinkName; - BOOLEAN m_CreatedUnicodeLinkName; - - // Used for device status ioctl only - const char *m_LastErrorFilename; - int m_LastErrorLineNumber; - LONG m_NumTapOpens; - - // Flags - BOOLEAN m_TapIsRunning; - BOOLEAN m_CalledTapDeviceFreeResources; - - // DPC queue for deferred packet injection - BOOLEAN m_InjectDpcInitialized; - KDPC m_InjectDpc; - NDIS_SPIN_LOCK m_InjectLock; - Queue *m_InjectQueue; -} -TapExtension, *TapExtensionPointer; - -typedef struct _TapPacket - { -# define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size)) -# define TP_TUN 0x80000000 -# define TP_SIZE_MASK (~TP_TUN) - ULONG m_SizeFlags; - UCHAR m_Data []; // m_Data must be the last struct member - } -TapPacket, *TapPacketPointer; - -typedef struct _InjectPacket - { -# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size)) -# define INJECT_PACKET_FREE(ib) NdisFreeMemory ((ib), INJECT_PACKET_SIZE ((ib)->m_Size), 0) - ULONG m_Size; - UCHAR m_Data []; // m_Data must be the last struct member - } -InjectPacket, *InjectPacketPointer; - -typedef struct _TapAdapter -{ -# define NAME(a) ((a)->m_NameAnsi.Buffer) - ANSI_STRING m_NameAnsi; - MACADDR m_MAC; - BOOLEAN m_InterfaceIsRunning; - NDIS_HANDLE m_MiniportAdapterHandle; - LONG m_Rx, m_Tx, m_RxErr, m_TxErr; -#if PACKET_TRUNCATION_CHECK - LONG m_RxTrunc, m_TxTrunc; -#endif - NDIS_MEDIUM m_Medium; - ULONG m_Lookahead; - ULONG m_MTU; - - // TRUE if adapter should always be - // "connected" even when device node - // is not open by a userspace process. - BOOLEAN m_MediaStateAlwaysConnected; - - // TRUE if device is "connected" - BOOLEAN m_MediaState; - - // Adapter power state - char m_DeviceState; - - // Info for point-to-point mode - BOOLEAN m_tun; - IPADDR m_localIP; - IPADDR m_remoteNetwork; - IPADDR m_remoteNetmask; - ETH_HEADER m_TapToUser; - ETH_HEADER m_UserToTap; - ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6 - MACADDR m_MAC_Broadcast; - - // Used for DHCP server masquerade - BOOLEAN m_dhcp_enabled; - IPADDR m_dhcp_addr; - ULONG m_dhcp_netmask; - IPADDR m_dhcp_server_ip; - BOOLEAN m_dhcp_server_arp; - MACADDR m_dhcp_server_mac; - ULONG m_dhcp_lease_time; - UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE]; - ULONG m_dhcp_user_supplied_options_buffer_len; - BOOLEAN m_dhcp_received_discover; - ULONG m_dhcp_bad_requests; - - // Help to tear down the adapter by keeping - // some state information on allocated - // resources. - BOOLEAN m_CalledAdapterFreeResources; - BOOLEAN m_RegisteredAdapterShutdownHandler; - - // Multicast list info - NDIS_SPIN_LOCK m_MCLock; - BOOLEAN m_MCLockAllocated; - ULONG m_MCListSize; - MC_LIST m_MCList; - - // Information on the TAP device - TapExtension m_Extension; -} TapAdapter, *TapAdapterPointer; - -#endif diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..b7980e0 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,23 @@ +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh + +TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)" +TESTS = $(test_scripts) + +dist_noinst_SCRIPTS = \ + $(test_scripts) \ + t_cltsrv-down.sh + diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..d2a7092 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,518 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# +# 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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> +# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com> +# + +VPATH = @srcdir@ +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 +DIST_COMMON = $(dist_noinst_SCRIPTS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/t_client.sh.in +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 +CONFIG_CLEAN_FILES = t_client.sh +CONFIG_CLEAN_VPATH_FILES = +SCRIPTS = $(dist_noinst_SCRIPTS) +SOURCES = +DIST_SOURCES = +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +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@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +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@ +OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@ +OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@ +OPTIONAL_DL_LIBS = @OPTIONAL_DL_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@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +POLARSSL_CFLAGS = @POLARSSL_CFLAGS@ +POLARSSL_LIBS = @POLARSSL_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@ +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@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +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@ +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@ +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh +TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)" +TESTS = $(test_scripts) +dist_noinst_SCRIPTS = \ + $(test_scripts) \ + t_cltsrv-down.sh + +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) --gnu tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu 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): +t_client.sh: $(top_builddir)/config.status $(srcdir)/t_client.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +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; 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 \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$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-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 + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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: clean-am + +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: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool 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 \ + 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/t_client.sh b/tests/t_client.sh index 21698ef..97a9e44 100755 --- a/t_client.sh +++ b/tests/t_client.sh @@ -12,19 +12,21 @@ # - for "ping6" checks: fping6 binary in $PATH # -if [ -r ./t_client.rc ] ; then - . ./t_client.rc +srcdir="${srcdir:-.}" +top_builddir="${top_builddir:-..}" +if [ -r "${top_builddir}"/t_client.rc ] ; then + . "${top_builddir}"/t_client.rc elif [ -r "${srcdir}"/t_client.rc ] ; then . "${srcdir}"/t_client.rc else - echo "$0: cannot find 't_client.rc' in current directory or" >&2 - echo "$0: source dir ('${srcdir}'). SKIPPING TEST." >&2 + echo "$0: cannot find 't_client.rc' in build dir ('${top_builddir}')" >&2 + echo "$0: or source directory ('${srcdir}'). SKIPPING TEST." >&2 exit 77 fi -if [ ! -x ./openvpn ] +if [ ! -x "${top_builddir}/src/openvpn/openvpn" ] then - echo "no (executable) openvpn binary in current directory. FAIL." >&2 + echo "no (executable) openvpn binary in current build tree. FAIL." >&2 exit 1 fi @@ -50,8 +52,12 @@ ID=`id` if expr "$ID" : "uid=0" >/dev/null then : else - echo "$0: this test must run be as root. SKIP." >&2 - exit 77 + 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 + fi fi LOGDIR=t_client-`hostname`-`date +%Y%m%d-%H%M%S` @@ -80,12 +86,12 @@ fail() get_ifconfig_route() { # linux / iproute2? (-> if configure got a path) - if [ "/sbin/ip" != "ip" ] + if [ -n "/sbin/ip" ] then echo "-- linux iproute2 --" /sbin/ip addr show | grep -v valid_lft /sbin/ip route show - /sbin/ip -6 route show | sed -e 's/expires [0-9]*sec //' + /sbin/ip -o -6 route show | grep -v ' cache' | sed -e 's/expires [0-9]*sec//' return fi @@ -94,26 +100,26 @@ get_ifconfig_route() Linux) echo "-- linux / ifconfig --" LANG=C /sbin/ifconfig -a |egrep "( addr:|encap:)" - LANG=C /bin/netstat -rn -4 -6 + LANG=C netstat -rn -4 -6 return ;; FreeBSD|NetBSD|Darwin) echo "-- FreeBSD/NetBSD/Darwin [MacOS X] --" /sbin/ifconfig -a | egrep "(flags=|inet)" - /bin/netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$NF }' + netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$NF }' return ;; OpenBSD) echo "-- OpenBSD --" /sbin/ifconfig -a | egrep "(flags=|inet)" | \ sed -e 's/pltime [0-9]*//' -e 's/vltime [0-9]*//' - /bin/netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$NF }' + netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$NF }' return ;; SunOS) echo "-- Solaris --" /sbin/ifconfig -a | egrep "(flags=|inet)" - /bin/netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }' + netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }' return ;; esac @@ -197,21 +203,25 @@ run_ping_tests() # ---------------------------------------------------------- # main test loop # ---------------------------------------------------------- +SUMMARY_OK= +SUMMARY_FAIL= + for SUF in $TEST_RUN_LIST do - echo -e "\n### test run $SUF ###\n" - fail_count=0 - - echo "save pre-openvpn ifconfig + route" - get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt - # get config variables + eval test_run_title=\"\$RUN_TITLE_$SUF\" eval openvpn_conf=\"\$OPENVPN_CONF_$SUF\" eval expect_ifconfig4=\"\$EXPECT_IFCONFIG4_$SUF\" eval expect_ifconfig6=\"\$EXPECT_IFCONFIG6_$SUF\" eval ping4_hosts=\"\$PING4_HOSTS_$SUF\" eval ping6_hosts=\"\$PING6_HOSTS_$SUF\" + echo -e "\n### test run $SUF: '$test_run_title' ###\n" + fail_count=0 + + echo "save pre-openvpn ifconfig + route" + get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt + echo -e "\nrun pre-openvpn ping tests - targets must not be reachable..." run_ping_tests 4 want_fail "$ping4_hosts" run_ping_tests 6 want_fail "$ping6_hosts" @@ -223,19 +233,20 @@ do continue fi - echo " run ./openvpn $openvpn_conf" - ./openvpn $openvpn_conf >$LOGDIR/$SUF:openvpn.log & + echo " run openvpn $openvpn_conf" + echo "# src/openvpn/openvpn $openvpn_conf" >$LOGDIR/$SUF:openvpn.log + $RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf >>$LOGDIR/$SUF:openvpn.log & opid=$! # make sure openvpn client is terminated in case shell exits - trap "kill $opid" 0 - trap "kill $opid ; trap - 0 ; exit 1" 1 2 3 15 + 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 10 + sleep ${SETUP_TIME_WAIT:-10} # test whether OpenVPN process is still there - if kill -0 $opid + if $RUN_SUDO kill -0 $opid then : else echo -e "OpenVPN process has failed to start up, check log ($LOGDIR/$SUF:openvpn.log). FAIL.\ntail of logfile follows:\n..." >&2 @@ -266,7 +277,7 @@ do echo -e "ping tests done.\n" echo "stopping OpenVPN" - kill $opid + $RUN_SUDO kill $opid wait $! rc=$? if [ $rc != 0 ] ; then @@ -287,12 +298,19 @@ do fi if [ "$fail_count" = 0 ] ; then echo -e "test run $SUF: all tests OK.\n" + SUMMARY_OK="$SUMMARY_OK $SUF" else echo -e "test run $SUF: $fail_count test failures. FAIL.\n"; + SUMMARY_FAIL="$SUMMARY_FAIL $SUF" exit_code=30 fi done +if [ -z "$SUMMARY_OK" ] ; then SUMMARY_OK=" none"; fi +if [ -z "$SUMMARY_FAIL" ] ; then SUMMARY_FAIL=" none"; fi +echo "Test sets succeded:$SUMMARY_OK." +echo "Test sets failed:$SUMMARY_FAIL." + # remove trap handler trap - 0 1 2 3 15 exit $exit_code diff --git a/t_client.sh.in b/tests/t_client.sh.in index b273964..189eecc 100755 --- a/t_client.sh.in +++ b/tests/t_client.sh.in @@ -12,19 +12,21 @@ # - for "ping6" checks: fping6 binary in $PATH # -if [ -r ./t_client.rc ] ; then - . ./t_client.rc +srcdir="${srcdir:-.}" +top_builddir="${top_builddir:-..}" +if [ -r "${top_builddir}"/t_client.rc ] ; then + . "${top_builddir}"/t_client.rc elif [ -r "${srcdir}"/t_client.rc ] ; then . "${srcdir}"/t_client.rc else - echo "$0: cannot find 't_client.rc' in current directory or" >&2 - echo "$0: source dir ('${srcdir}'). SKIPPING TEST." >&2 + echo "$0: cannot find 't_client.rc' in build dir ('${top_builddir}')" >&2 + echo "$0: or source directory ('${srcdir}'). SKIPPING TEST." >&2 exit 77 fi -if [ ! -x ./openvpn ] +if [ ! -x "${top_builddir}/src/openvpn/openvpn" ] then - echo "no (executable) openvpn binary in current directory. FAIL." >&2 + echo "no (executable) openvpn binary in current build tree. FAIL." >&2 exit 1 fi @@ -50,8 +52,12 @@ ID=`id` if expr "$ID" : "uid=0" >/dev/null then : else - echo "$0: this test must run be as root. SKIP." >&2 - exit 77 + 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 + fi fi LOGDIR=t_client-`hostname`-`date +%Y%m%d-%H%M%S` @@ -80,12 +86,12 @@ fail() get_ifconfig_route() { # linux / iproute2? (-> if configure got a path) - if [ "@IPROUTE@" != "ip" ] + if [ -n "@IPROUTE@" ] then echo "-- linux iproute2 --" @IPROUTE@ addr show | grep -v valid_lft @IPROUTE@ route show - @IPROUTE@ -6 route show | sed -e 's/expires [0-9]*sec //' + @IPROUTE@ -o -6 route show | grep -v ' cache' | sed -e 's/expires [0-9]*sec//' return fi @@ -197,21 +203,25 @@ run_ping_tests() # ---------------------------------------------------------- # main test loop # ---------------------------------------------------------- +SUMMARY_OK= +SUMMARY_FAIL= + for SUF in $TEST_RUN_LIST do - echo -e "\n### test run $SUF ###\n" - fail_count=0 - - echo "save pre-openvpn ifconfig + route" - get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt - # get config variables + eval test_run_title=\"\$RUN_TITLE_$SUF\" eval openvpn_conf=\"\$OPENVPN_CONF_$SUF\" eval expect_ifconfig4=\"\$EXPECT_IFCONFIG4_$SUF\" eval expect_ifconfig6=\"\$EXPECT_IFCONFIG6_$SUF\" eval ping4_hosts=\"\$PING4_HOSTS_$SUF\" eval ping6_hosts=\"\$PING6_HOSTS_$SUF\" + echo -e "\n### test run $SUF: '$test_run_title' ###\n" + fail_count=0 + + echo "save pre-openvpn ifconfig + route" + get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt + echo -e "\nrun pre-openvpn ping tests - targets must not be reachable..." run_ping_tests 4 want_fail "$ping4_hosts" run_ping_tests 6 want_fail "$ping6_hosts" @@ -223,19 +233,20 @@ do continue fi - echo " run ./openvpn $openvpn_conf" - ./openvpn $openvpn_conf >$LOGDIR/$SUF:openvpn.log & + echo " run openvpn $openvpn_conf" + echo "# src/openvpn/openvpn $openvpn_conf" >$LOGDIR/$SUF:openvpn.log + $RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf >>$LOGDIR/$SUF:openvpn.log & opid=$! # make sure openvpn client is terminated in case shell exits - trap "kill $opid" 0 - trap "kill $opid ; trap - 0 ; exit 1" 1 2 3 15 + 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 10 + sleep ${SETUP_TIME_WAIT:-10} # test whether OpenVPN process is still there - if kill -0 $opid + if $RUN_SUDO kill -0 $opid then : else echo -e "OpenVPN process has failed to start up, check log ($LOGDIR/$SUF:openvpn.log). FAIL.\ntail of logfile follows:\n..." >&2 @@ -266,7 +277,7 @@ do echo -e "ping tests done.\n" echo "stopping OpenVPN" - kill $opid + $RUN_SUDO kill $opid wait $! rc=$? if [ $rc != 0 ] ; then @@ -287,12 +298,19 @@ do fi if [ "$fail_count" = 0 ] ; then echo -e "test run $SUF: all tests OK.\n" + SUMMARY_OK="$SUMMARY_OK $SUF" else echo -e "test run $SUF: $fail_count test failures. FAIL.\n"; + SUMMARY_FAIL="$SUMMARY_FAIL $SUF" exit_code=30 fi done +if [ -z "$SUMMARY_OK" ] ; then SUMMARY_OK=" none"; fi +if [ -z "$SUMMARY_FAIL" ] ; then SUMMARY_FAIL=" none"; fi +echo "Test sets succeded:$SUMMARY_OK." +echo "Test sets failed:$SUMMARY_FAIL." + # remove trap handler trap - 0 1 2 3 15 exit $exit_code diff --git a/t_cltsrv-down.sh b/tests/t_cltsrv-down.sh index 2ef852a..2ef852a 100755 --- a/t_cltsrv-down.sh +++ b/tests/t_cltsrv-down.sh diff --git a/t_cltsrv.sh b/tests/t_cltsrv.sh index 808d719..752251e 100755 --- a/t_cltsrv.sh +++ b/tests/t_cltsrv.sh @@ -19,6 +19,9 @@ # 02110-1301, USA. set -e +srcdir="${srcdir:-.}" +top_srcdir="${top_srcdir:-..}" +top_builddir="${top_builddir:-..}" trap "rm -f log.$$ log.$$.signal ; trap 0 ; exit 77" 1 2 15 trap "rm -f log.$$ log.$$.signal ; exit 1" 0 3 addopts= @@ -33,7 +36,7 @@ case `uname -s` in echo "###" echo "### To run the test in a FreeBSD jail, you MUST add an IP alias for the jail's IP." echo "###" - exit 1 + exit 77 fi fi ;; @@ -41,8 +44,9 @@ esac # make sure that the --down script is executable -- fail (rather than # skip) test if it isn't. -downscript="t_cltsrv-down.sh" -test -x "${srcdir}"/$downscript || chmod +x "${srcdir}"/$downscript || { echo >&2 "$downscript is not executable, failing." ; exit 1 ; } +downscript="../tests/t_cltsrv-down.sh" +root="${top_srcdir}/sample" +test -x "${root}/${downscript}" || chmod +x "${root}/${downscript}" || { echo >&2 "${root}/${downscript} is not executable, failing." ; exit 1 ; } echo "The following test will take about two minutes." >&2 echo "If the addresses are in use, this test will retry up to two times." >&2 @@ -51,8 +55,8 @@ success=0 for i in 1 2 3 ; do set +e ( - ./openvpn --script-security 2 --cd "${srcdir}" ${addopts} --setenv role srv --down "$downscript" --tls-exit --ping-exit 180 --config sample-config-files/loopback-server & - ./openvpn --script-security 2 --cd "${srcdir}" ${addopts} --setenv role clt --down "$downscript" --tls-exit --ping-exit 180 --config sample-config-files/loopback-client + "${top_builddir}/src/openvpn/openvpn" --script-security 2 --cd "${root}" ${addopts} --setenv role srv --down "${downscript}" --tls-exit --ping-exit 180 --config "sample-config-files/loopback-server" & + "${top_builddir}/src/openvpn/openvpn" --script-security 2 --cd "${top_srcdir}/sample" ${addopts} --setenv role clt --down "${downscript}" --tls-exit --ping-exit 180 --config "sample-config-files/loopback-client" ) 3>log.$$.signal >log.$$ 2>&1 e1=$? wait $! diff --git a/t_lpback.sh b/tests/t_lpback.sh index b860de4..40767a1 100755 --- a/t_lpback.sh +++ b/tests/t_lpback.sh @@ -19,11 +19,12 @@ # 02110-1301, USA. set -e +top_builddir="${top_builddir:-..}" trap "rm -f key.$$ log.$$ ; trap 0 ; exit 77" 1 2 15 trap "rm -f key.$$ log.$$ ; exit 1" 0 3 -./openvpn --genkey --secret key.$$ +"${top_builddir}/src/openvpn/openvpn" --genkey --secret key.$$ set +e -( ./openvpn --test-crypto --secret key.$$ ) >log.$$ 2>&1 +( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ ) >log.$$ 2>&1 e=$? if [ $e != 0 ] ; then cat log.$$ ; fi rm key.$$ log.$$ @@ -1,6 +1,10 @@ dnl define the OpenVPN version -define(PRODUCT_VERSION,[2.2.1]) +define([PRODUCT_NAME], [OpenVPN]) +define([PRODUCT_TARNAME], [openvpn]) +define([PRODUCT_VERSION], [2.3_rc1]) +define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net]) +define([PRODUCT_VERSION_RESOURCE], [2,3,0,0]) dnl define the TAP version -define(PRODUCT_TAP_ID,[tap0901]) -define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9]) -define(PRODUCT_TAP_WIN32_MIN_MINOR,[8]) +define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) +define([PRODUCT_TAP_WIN_MIN_MAJOR], [9]) +define([PRODUCT_TAP_WIN_MIN_MINOR], [9]) diff --git a/version.sh.in b/version.sh.in new file mode 100644 index 0000000..2af5a36 --- /dev/null +++ b/version.sh.in @@ -0,0 +1,4 @@ +OPENVPN_PACKAGE_NAME="@PACKAGE_NAME@" +OPENVPN_PACKAGE_TARNAME="@PACKAGE_TARNAME@" +OPENVPN_PACKAGE_VERSION="@PACKAGE_VERSION@" +OPENVPN_PACKAGE_HOST="@host@" diff --git a/win/__init__.py b/win/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/win/__init__.py +++ /dev/null diff --git a/win/autodefs.h.in b/win/autodefs.h.in deleted file mode 100644 index ad0af19..0000000 --- a/win/autodefs.h.in +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef AUTODEFS_H -#define AUTODEFS_H - -/* - * Minimum TAP-Win32 version number expected by userspace - * - * The TAP-Win32 version number is defined in tap-win32/SOURCES - */ -#define TAP_ID "@PRODUCT_TAP_ID@" -#define TAP_WIN32_MIN_MAJOR @PRODUCT_TAP_WIN32_MIN_MAJOR@ -#define TAP_WIN32_MIN_MINOR @PRODUCT_TAP_WIN32_MIN_MINOR@ - -/* Friendly name for TAP driver */ -#define PRODUCT_TAP_DEVICE_DESCRIPTION "@PRODUCT_TAP_DEVICE_DESCRIPTION@" - -/* Version number of DDK/WDK used to build TAP driver */ -#define DDKVER_MAJOR @DDKVER_MAJOR@ - -/* Name of package */ -#define PACKAGE "@PRODUCT_UNIX_NAME@" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "@PRODUCT_NAME@" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "@PRODUCT_UNIX_NAME@" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@PRODUCT_VERSION@" - -#endif diff --git a/win/build.py b/win/build.py deleted file mode 100644 index 69137f2..0000000 --- a/win/build.py +++ /dev/null @@ -1,23 +0,0 @@ -import os, sys -from wb import system, config, home_fn, cd_home, cd_service_win32, run_in_vs_shell - -def main(): - """Build openvpn.exe and openvpnserv.exe""" - cd_home() - run_in_vs_shell("nmake /f %s" % (home_fn('msvc.mak'),)) - cd_service_win32() - run_in_vs_shell("nmake /f %s" % ('msvc.mak')) - -def clean(): - """Clean up after openvpn.exe and openvpnserv.exe build""" - cd_home() - run_in_vs_shell("nmake /f %s clean" % (home_fn('msvc.mak'),)) - os.chdir("service-win32") - run_in_vs_shell("nmake /f %s clean" % ('msvc.mak')) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - if len(sys.argv) == 2 and sys.argv[1] == 'clean': - clean() - else: - main() diff --git a/win/build_all.py b/win/build_all.py deleted file mode 100644 index 47716a1..0000000 --- a/win/build_all.py +++ /dev/null @@ -1,69 +0,0 @@ -import getopt, sys -from config_all import main as config_all -from build import main as build_openvpn -from build_ddk import main as build_ddk -from make_dist import main as make_dist - -def Usage(): - '''Show usage information''' - print "Usage: build_all.py [OPTIONS]..." - print "Build OpenVPN using Visual Studio tools" - print - print " -h, --help Show this help" - print " -u, --unsigned Do not sign the TAP drivers" - print " -n, --notap Don't build the TAP driver" - sys.exit(1) - -def main(config): - - # Do a signed build by default - signedBuild=True - - # Build the TAP driver by default - tap=True - - # Parse the command line argument(s) - try: - opts, args = getopt.getopt(sys.argv[1:], "hun", ["help", "unsigned", "notap"]) - except getopt.GetoptError: - Usage() - - for o, a in opts: - if o in ("-h","--help"): - Usage() - if o in ("-u", "--unsigned"): - signedBuild=False - if o in ("-n", "--notap"): - tap=False - - # Check if the SignTool module is present. This avoids ImportErrors popping - # up annoyingly _after_ the build. - if signedBuild: - try: - from signtool import SignTool - except (ImportError): - print "ERROR: SignTool python module not found! Can't do a signed build." - sys.exit(1) - else: - print "Doing an unsigned build as requested" - - # Start the build - config_all(config) - build_openvpn() - - if tap: - build_ddk(config, 'tap', 'all') - build_ddk(config, 'tapinstall', 'all') - if signedBuild: - sign(config, 'all') - make_dist(config,tap=True) - - else: - if 'TAP_PREBUILT' in config: - print "Using prebuilt TAP driver" - make_dist(config,tap=False) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/build_ddk.py b/win/build_ddk.py deleted file mode 100644 index a197bf5..0000000 --- a/win/build_ddk.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -from wb import system, home_fn, choose_arch - -def build_ddk(config, dir, x64): - ddk_path = config['DDK_PATH'] - ddk_major = int(config['DDKVER_MAJOR']) - debug = 'PRODUCT_TAP_DEBUG' in config - return build_tap(ddk_path, ddk_major, debug, dir, x64) - -def build_tap(ddk_path, ddk_major, debug, dir, x64): - """Build drivers using WinDDK tools""" - setenv_bat = os.path.realpath(os.path.join(ddk_path, 'bin/setenv.bat')) - target = 'chk' if debug else 'fre' - if x64: - target += ' x64' - else: - target += ' x86' - if ddk_major >= 7600: - if x64: - target += ' wlh' # vista - else: - target += ' wnet' # server 2003 - else: - if x64: - target += ' wnet' # server 2003 - else: - target += ' w2k' # 2000 - - system('cmd /c "%s %s %s && cd %s && build -cef"' % ( - setenv_bat, - os.path.realpath(ddk_path), - target, - dir - )) - -def main(config, proj, arch): - if proj == 'tap': - dir = home_fn('tap-win32') - elif proj == 'tapinstall': - dir = home_fn('tapinstall') - else: - raise ValueError("unknown project: %s" % (proj,)) - - for x64 in choose_arch(arch): - build_ddk(config, dir, x64) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - import sys - from wb import config - if len(sys.argv) >= 3: - main(config, sys.argv[1], sys.argv[2]) - else: - print "usage: build <tap|tapinstall> <x64|x86|all>" - sys.exit(2) diff --git a/win/build_exe.py b/win/build_exe.py deleted file mode 100644 index dae4825..0000000 --- a/win/build_exe.py +++ /dev/null @@ -1,15 +0,0 @@ -from config import main as config_main -from build import main as build_openvpn -from build_ddk import main as build_ddk -from sign import main as sign -from make_dist import main as make_dist - -def main(config): - config_main(config) - build_openvpn() - make_dist(config, tap=False) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/config.h.in b/win/config.h.in deleted file mode 100644 index 82344a0..0000000 --- a/win/config.h.in +++ /dev/null @@ -1,323 +0,0 @@ -/* - * 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-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 - */ - -/* - * Configuration header for Win32 using the MSVC environment. - */ - -#ifndef OPENVPN_CONFIG_H -#define OPENVPN_CONFIG_H - -#include <windows.h> -#include <winsock2.h> -#include "autodefs.h" /* machine generated */ - -//#define sleep(x) Sleep((x)*1000) - -//#define random rand -//#define srandom srand - -typedef unsigned long in_addr_t; - -#ifndef _SSIZE_T_ -#define _SSIZE_T_ - typedef unsigned int ssize_t; -#endif - -/* Append a label to program startup title */ -/*#define DEBUG_LABEL "DEBUG1"*/ - -/* Should we print debug info from driver? */ -#ifdef PRODUCT_TAP_DEBUG -#define TAP_WIN32_DEBUG -#endif - -/* Enable reading credentials from a file */ -#if @ENABLE_PASSWORD_SAVE@ != 0 -#define ENABLE_PASSWORD_SAVE @ENABLE_PASSWORD_SAVE@ -#endif - -/* Enable client/server capability */ -#if @ENABLE_CLIENT_SERVER@ != 0 -#define ENABLE_CLIENT_SERVER @ENABLE_CLIENT_SERVER@ -#endif - -/* Enable client capability only */ -#if @ENABLE_CLIENT_ONLY@ != 0 -#define ENABLE_CLIENT_ONLY @ENABLE_CLIENT_ONLY@ -#endif - -/* Enable management server capability */ -#if @ENABLE_MANAGEMENT@ != 0 -#define ENABLE_MANAGEMENT @ENABLE_MANAGEMENT@ -#endif - -/* Enable PKCS#11 support */ -/* #define USE_PKCS11 1 */ - -/* Enable HTTP proxy support */ -#if @ENABLE_HTTP_PROXY@ != 0 -#define ENABLE_HTTP_PROXY @ENABLE_HTTP_PROXY@ -#endif - -/* Enable Socks proxy support */ -#if @ENABLE_SOCKS@ != 0 -#define ENABLE_SOCKS @ENABLE_SOCKS@ -#endif - -/* Enable internal fragmentation support */ -#if @ENABLE_FRAGMENT@ != 0 -#define ENABLE_FRAGMENT @ENABLE_FRAGMENT@ -#endif - -/* Enable smaller executable size */ -/* #undef ENABLE_SMALL */ - -/* Enable debugging support */ -#if @ENABLE_DEBUG@ != 0 -#define ENABLE_DEBUG @ENABLE_DEBUG@ -#endif - -/* if defined, will allow usage of the --plugin directive */ -#define USE_LOAD_LIBRARY - -/* Dimension size to use for empty array declaration */ -#define EMPTY_ARRAY_SIZE 0 - -/* Define to 1 if you have the `getsockname' function. */ -#define HAVE_GETSOCKNAME 1 - -/* Define to 1 if you have the <openssl/engine.h> header file. */ -#define HAVE_OPENSSL_ENGINE_H 1 - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - -/* Define to 1 if you have the `ENGINE_register_all_complete' function. */ -#define HAVE_ENGINE_REGISTER_ALL_COMPLETE 1 - -/* Define to 1 if you have the `ENGINE_cleanup' function. */ -#define HAVE_ENGINE_CLEANUP 1 - -/* gettimeofday() is implemented in otime.c for Windows */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the 'chsize' function. */ -#define HAVE_CHSIZE 1 - -/* Define to 1 if you have the `chdir' function. */ -#define HAVE_CHDIR 1 - -/* Define to 1 if your compiler supports GNU GCC-style variadic macros */ -#ifndef _MSC_VER /* Defines MSFT compiler version. Defined as 1200 for MSVC++ 6.0. */ -#define HAVE_CPP_VARARG_MACRO_GCC 1 -#endif - -/* Define to 1 if you have the <ctype.h> header file. */ -#define HAVE_CTYPE_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `EVP_CIPHER_CTX_set_key_length' function. */ -#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `getsockopt' function. */ -#define HAVE_GETSOCKOPT 1 - -/* Define to 1 if you have the `inet_ntoa' function. */ -#define HAVE_INET_NTOA 1 - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the `setsockopt' function. */ -#define HAVE_SETSOCKOPT 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#ifndef _MSC_VER -#define HAVE_STDINT_H 1 -#endif - -/* Define to 1 if you have the <stdio.h> header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `system' function. */ -#define HAVE_SYSTEM 1 - -/* Define to 1 if you have the <sys/file.h> header file. */ -#ifndef _MSC_VER -#define HAVE_SYS_FILE_H 1 -#endif - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#ifndef _MSC_VER -#define HAVE_SYS_TIME_H 1 -#endif - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the `time' function. */ -#define HAVE_TIME 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#ifndef _MSC_VER -#define HAVE_UNISTD_H 1 -#endif - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Special Windows version of getpass() defined in io.c */ -#define HAVE_GETPASS 1 - -/* Define to the full name and version of this package. */ -#ifdef DEBUG_LABEL -#define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION " " DEBUG_LABEL -#else -#define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION -#endif - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* The size of a `unsigned int', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_INT 4 - -/* The size of a `unsigned long', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_LONG 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* A string representing our target */ -#ifdef _MSC_VER -#define TARGET_ALIAS "Win32-MSVC++" -#else -#define TARGET_ALIAS "Win32-MinGW" -#endif - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#ifndef _MSC_VER -#define TIME_WITH_SYS_TIME 1 -#endif - -/* Use OpenSSL crypto library */ -#define USE_CRYPTO 1 - -/* Use LZO compression library */ -#define USE_LZO 1 - -/* LZO version number */ -#define LZO_VERSION_NUM "2" - -/* Use lzo/ directory prefix for LZO header files (for LZO 2.0) */ -#define LZO_HEADER_DIR 1 - -/* Use OpenSSL SSL library */ -#define USE_SSL 1 - -/* Version number of package */ -#define VERSION PACKAGE_VERSION - -/* Define as `__inline' if that's what the C compiler calls it, or to nothing - if it is not supported. */ -#define inline __inline - -/* type to use in place of socklen_t if not defined */ -#define socklen_t unsigned int - -#ifndef __MINGW32__ -/* 32-bit unsigned type */ -#define uint32_t unsigned int - -/* 16-bit unsigned type */ -#define uint16_t unsigned short - -/* 8-bit unsigned type */ -#define uint8_t unsigned char -#endif /* __MINGW32__ */ - -/* Route command */ -#define ROUTE_PATH "route" - -#ifdef _MSC_VER -/* MSVC++ hacks */ -#pragma warning(disable:4244) // conversion from 'foo' to 'bar', possible loss of data -#pragma warning(disable:4018) // signed/unsigned mismatch -#include <io.h> -#include <direct.h> -//#define vsnprintf _vsnprintf -//#define vsnwprintf _vsnwprintf -#define snwprintf _snwprintf -#define write _write -#define open _open -#define read _read -#define close _close -#define lseek _lseek -#define chdir _chdir -#define strdup _strdup -#define strcasecmp _stricmp -#define chsize _chsize -#define S_IRUSR 0 -#define S_IWUSR 0 -#define TV_SEC_CAST (long) -#define TV_USEC_CAST (long) -typedef int intptr_t; -/* Visual Studio 2005 supports vararg macros */ -#if _MSC_VER >= 1400 -#define HAVE_CPP_VARARG_MACRO_ISO 1 -#endif -#endif - -#endif /* OPENVPN_CONFIG_H */ diff --git a/win/config.py b/win/config.py deleted file mode 100644 index b820510..0000000 --- a/win/config.py +++ /dev/null @@ -1,21 +0,0 @@ -from wb import preprocess, autogen, mod_fn, home_fn, build_config_h, build_configure_h, build_version_m4_vars, build_autodefs, make_headers_objs, dict_def - -def main(config): - build_config_h(config) - build_configure_h(config, mod_fn(home_fn('configure.h')), head_comment='/* %s */\n\n' % autogen) - build_version_m4_vars(mod_fn(mod_fn('version_m4_vars.tmp')), head_comment='/* %s */\n\n' % autogen) - build_autodefs(config, mod_fn('autodefs.h.in'), home_fn('autodefs.h')) - ho = make_headers_objs(home_fn('Makefile.am')) - - preprocess(dict_def(config, [('HEADERS_OBJS', ho)]), - in_fn=mod_fn('msvc.mak.in'), - out_fn=home_fn('msvc.mak'), - quote_begin='@', - quote_end='@', - if_prefix='!', - head_comment='# %s\n\n' % autogen) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/config_all.py b/win/config_all.py deleted file mode 100644 index ba6affe..0000000 --- a/win/config_all.py +++ /dev/null @@ -1,13 +0,0 @@ -from config import main as config_main -from config_tap import main as config_tap -from config_ti import main as config_ti - -def main(config): - config_main(config) - config_tap(config) - config_ti(config) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/config_tap.py b/win/config_tap.py deleted file mode 100644 index a5b1d6c..0000000 --- a/win/config_tap.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -from wb import preprocess, home_fn, autogen, dict_def - -def main(config): - preprocess(config, - in_fn=home_fn('tap-win32/SOURCES.in'), - out_fn=home_fn('tap-win32/SOURCES'), - quote_begin='@@', - quote_end='@@', - head_comment='# %s\n\n' % autogen) - - preprocess(config, - in_fn=home_fn('tap-win32/i386/OemWin2k.inf.in'), - out_fn=home_fn('tap-win32/i386/OemWin2k.inf'), - quote_begin='@@', - quote_end='@@', - if_prefix='!', - head_comment='; %s\n\n' % autogen) - - try: - os.mkdir(home_fn('tap-win32/amd64')) - except: - pass - preprocess(dict_def(config, [('AMD64', '1')]), - in_fn=home_fn('tap-win32/i386/OemWin2k.inf.in'), - out_fn=home_fn('tap-win32/amd64/OemWin2k.inf'), - quote_begin='@@', - quote_end='@@', - if_prefix='!', - head_comment='; %s\n\n' % autogen) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/config_ti.py b/win/config_ti.py deleted file mode 100644 index 8742caa..0000000 --- a/win/config_ti.py +++ /dev/null @@ -1,18 +0,0 @@ -import os, shutil -from wb import preprocess, home_fn, autogen - -def main(config): - src = os.path.join(home_fn(config['TISRC']), config['DDKVER_MAJOR']) - dest = home_fn('tapinstall') - shutil.rmtree(dest, ignore_errors=True) - shutil.copytree(src, dest) - preprocess(config, - in_fn=os.path.join(src, 'sources'), - out_fn=os.path.join(dest, 'sources'), - if_prefix='!', - head_comment='# %s\n\n' % autogen) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/js.py b/win/js.py deleted file mode 100644 index d1d4db3..0000000 --- a/win/js.py +++ /dev/null @@ -1,10 +0,0 @@ -import json - -# usage: -# print JSON().encode(kv) - -class JSON(json.JSONEncoder): - def __init__(self, **kwargs): - args = dict(sort_keys=True, indent=2) - args.update(kwargs) - json.JSONEncoder.__init__(self, **args) diff --git a/win/make_dist.py b/win/make_dist.py deleted file mode 100644 index edb0e6a..0000000 --- a/win/make_dist.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -from wb import home_fn, rm_rf, mkdir, cp_a, cp, rename, run_in_vs_shell - -def main(config, tap=True): - dist = config['DIST'] - assert dist - dist = home_fn(dist) - bin = os.path.join(dist, 'bin') - i386 = os.path.join(dist, 'i386') - amd64 = os.path.join(dist, 'amd64') - samples = os.path.join(dist, 'samples') - - # build dist and subdirectories - rm_rf(dist) - mkdir(dist) - mkdir(bin) - mkdir(i386) - mkdir(amd64) - mkdir(samples) - - # copy openvpn.exe, openvpnserv.exe and their manifests - cp(home_fn('openvpn.exe'), bin) - cp(home_fn('openvpn.exe.manifest'), bin) - cp(home_fn('service-win32/openvpnserv.exe'), bin) - cp(home_fn('service-win32/openvpnserv.exe.manifest'), bin) - - # copy openvpn-gui - cp(home_fn(config['OPENVPN_GUI_DIR']+"/"+config['OPENVPN_GUI']), bin) - - # copy DLL dependencies - cp(home_fn(config['LZO_DIR']+'/bin/lzo2.dll'), bin) - cp(home_fn(config['LZO_DIR']+'/bin/lzo2.dll.manifest'), bin) - cp(home_fn(config['OPENSSL_DIR']+'/bin/libeay32.dll'), bin) - cp(home_fn(config['OPENSSL_DIR']+'/bin/ssleay32.dll'), bin) - cp(home_fn(config['PKCS11_HELPER_DIR']+'/lib/libpkcs11-helper-1.dll'), bin) - cp(home_fn(config['PKCS11_HELPER_DIR']+'/lib/libpkcs11-helper-1.dll.manifest'), bin) - - # copy OpenSSL utilities (=openvpn.exe) - cp(home_fn(config['OPENSSL_DIR']+'/bin/openssl.exe'), bin) - - # copy sample config files; renaming is necessary due to openvpn.nsi script - cp(home_fn('install-win32/sample.ovpn'), samples) - cp(home_fn('sample-config-files/client.conf'), samples) - cp(home_fn('sample-config-files/server.conf'), samples) - rename(os.path.join(samples,'client.conf'), os.path.join(samples, 'client.ovpn')) - rename(os.path.join(samples,'server.conf'), os.path.join(samples, 'server.ovpn')) - - # embed manifests to executables and DLLs - for f in [ "openvpn.exe", "openvpnserv.exe", "lzo2.dll", "libpkcs11-helper-1.dll" ]: - - outputresource = os.path.join(bin,f) - manifest = outputresource+".manifest" - - # EXEs and DLLs require slightly different treatment - if f.endswith(".exe"): - type = "1" - elif f.endswith(".dll"): - type = "2" - else: - print "ERROR: Could not embed manifest to "+outputresouce+", bailing out." - sys.exit(1) - - # Embed the manifest - run_in_vs_shell('mt.exe -manifest %s -outputresource:%s;%s' % (manifest, outputresource, type)) - - # copy MSVC CRT - cp_a(home_fn(config['MSVC_CRT']), bin) - - # TAP-driver and tapinstall.exe were built, so copy those over - if tap: - drv_dir = 'tap-win32' - ti_dir = 'tapinstall' - - # we're using prebuilt TAP-driver and tapinstall.exe - elif 'TAP_PREBUILT' in config: - drv_dir = config['TAP_PREBUILT'] - ti_dir = config['TAP_PREBUILT'] - - else: - print "ERROR: Could not find prebuilt TAP-drivers or tapinstall.exe. Please check win/settings.in" - sys.exit(1) - - # copy TAP drivers - for dir_name, dest in (('amd64', amd64), ('i386', i386)): - dir = home_fn(os.path.join(drv_dir, dir_name)) - for dirpath, dirnames, filenames in os.walk(dir): - for f in filenames: - root, ext = os.path.splitext(f) - if ext in ('.inf', '.cat', '.sys'): - cp(os.path.join(dir, f), dest) - break - - # Copy tapinstall.exe (usually known as devcon.exe) - dest = {'amd64' : amd64, 'i386' : i386} - for dirpath, dirnames, filenames in os.walk(home_fn(ti_dir)): - for f in filenames: - if f in ( 'devcon.exe', 'tapinstall.exe' ): - dir_name = os.path.basename(dirpath) - src = os.path.join(dirpath, f) - dst = os.path.join(dest[dir_name],'tapinstall.exe') - if dir_name in dest: - cp(src, dst, dest_is_dir=False) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - from wb import config - main(config) diff --git a/win/msvc.mak.in b/win/msvc.mak.in deleted file mode 100644 index ac17ae9..0000000 --- a/win/msvc.mak.in +++ /dev/null @@ -1,57 +0,0 @@ -# This makefile builds the user-mode component of OpenVPN for Windows in the -# Visual Studio 2008 environment. Note that this file is basis for the real -# makefile (..\msvc.mak) but unusable as is. The real makefile is automatically -# generated during the build process by the Python build scripts. -# -# A few details are in order: -# -# - Everything between @<< and << is inserted into a s.c. "in-line file". This -# file drives the linker (link.exe). -# - HEADERS_OBJS is expanded to all all header and source files listed in -# ..\Makefile.am -# - OPENSSL_DIR and LZO_DIR are dynamically created from settings.in - -OPENSSL = @OPENSSL_DIR@ -OPENSSL_DYNAMIC = libeay32.lib ssleay32.lib - -LZO = @LZO_DIR@ -LZO_DYNAMIC = lzo2.lib - -INCLUDE_DIRS = -I$(OPENSSL)/include -I$(LZO)/include - -LIBS = $(OPENSSL_DYNAMIC) $(LZO_DYNAMIC) ws2_32.lib crypt32.lib iphlpapi.lib winmm.lib user32.lib gdi32.lib advapi32.lib wininet.lib - -LIB_DIRS = -LIBPATH:$(OPENSSL)\lib -LIBPATH:$(LZO)\lib - -EXE = openvpn.exe - -CPP=cl.exe -CPP_ARG_COMMON=/nologo /W3 -DWIN32 -DWIN32_LEAN_AND_MEAN -D_CONSOLE -D_MBCS -D_CRT_SECURE_NO_DEPRECATE $(INCLUDE_DIRS) /FD /c - -LINK32=link.exe - -!ifdef PRODUCT_OPENVPN_DEBUG -# debug: -CPP_PROJ=$(CPP_ARG_COMMON) /MD /Z7 -LINK32_FLAGS=/nologo /subsystem:console /incremental:no /opt:ref /opt:icf /debug -!else -# release: -CPP_PROJ=$(CPP_ARG_COMMON) /O2 /MD -DNDEBUG -LINK32_FLAGS=/nologo /subsystem:console /incremental:no -!endif - -# HEADERS and OBJS definitions, automatically generated from ../Makefile.am -@HEADERS_OBJS@ - -openvpn : $(OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) "/out:$(EXE)" $(LIB_DIRS) $(LIBS) $(OBJS) -<< - -clean : - del /Q $(OBJS) $(EXE) *.idb *.pdb - -.c.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< diff --git a/win/openvpn.nsi b/win/openvpn.nsi deleted file mode 100755 index 29d34f1..0000000 --- a/win/openvpn.nsi +++ /dev/null @@ -1,822 +0,0 @@ -; **************************************************************************** -; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * -; * 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. * -; **************************************************************************** - -; OpenVPN install script for Windows, using NSIS - -; Start menu entries don't get uninstalled properly on Windows Vista/7 unless we -; explicitly state that the installer requires admin privileges. This is -; caused by backwards compatibility tricks used on those platforms. For details, -; see http://nsis.sourceforge.net/Shortcuts_removal_fails_on_Windows_Vista -RequestExecutionLevel admin - -SetCompressor lzma - -!include "MUI.nsh" - -# Include basic build settings -!include "settings.in" - -# Include variables generated dynamically from version.m4 by wb.py -!include "version_m4_vars.tmp" - -;!include "guidefs.nsi" -!include "setpath.nsi" - -!ifdef EXTRACT_FILES -!include "MultiFileExtract.nsi" -!endif - -!define GEN "..\dist" -!define BIN "${GEN}\bin" -!define EASYRSA "..\easy-rsa" - -!define PRODUCT_ICON "icon.ico" - -!ifdef PRODUCT_TAP_DEBUG -!define DBG_POSTFIX "-DBG" -!else -!define DBG_POSTFIX "" -!endif - -!define VERSION "${PRODUCT_VERSION}${DBG_POSTFIX}" - -!define TAP "${PRODUCT_TAP_ID}" -!define TAPDRV "${TAP}.sys" - -; Default service settings -!define SERV_CONFIG_DIR "$INSTDIR\config" -!define SERV_CONFIG_EXT "${PRODUCT_FILE_EXT}" -!define SERV_EXE_PATH "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" -!define SERV_LOG_DIR "$INSTDIR\log" -!define SERV_PRIORITY "NORMAL_PRIORITY_CLASS" -!define SERV_LOG_APPEND "0" - -;-------------------------------- -;Configuration - - ;General - - OutFile "${GEN}\${PRODUCT_UNIX_NAME}-${VERSION}${OUTFILE_LABEL}-install.exe" - - ShowInstDetails show - ShowUninstDetails show - - ;Folder selection page - InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" - - ;Remember install folder - InstallDirRegKey HKCU "Software\${PRODUCT_NAME}" "" - -;-------------------------------- -;Modern UI Configuration - - Name "${PRODUCT_NAME} ${VERSION} ${TITLE_LABEL}" - - !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of ${PRODUCT_NAME}, an Open Source VPN package by James Yonan.\r\n\r\nNote that the Windows version of ${PRODUCT_NAME} only runs on XP, or higher.\r\n\r\n\r\n" - - !define MUI_COMPONENTSPAGE_TEXT_TOP "Select the components to install/upgrade. Stop any ${PRODUCT_NAME} processes or the ${PRODUCT_NAME} service if it is running. All DLLs are installed locally." - - !define MUI_COMPONENTSPAGE_SMALLDESC - !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\INSTALL-win32.txt" - !define MUI_FINISHPAGE_NOAUTOCLOSE - !define MUI_ABORTWARNING - !define MUI_ICON "..\images\${PRODUCT_ICON}" - !define MUI_UNICON "..\images\${PRODUCT_ICON}" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "..\images\install-whirl.bmp" - !define MUI_UNFINISHPAGE_NOAUTOCLOSE - - !insertmacro MUI_PAGE_WELCOME - !insertmacro MUI_PAGE_LICENSE "..\COPYRIGHT.GPL" - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_UNPAGE_FINISH - - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -;Language Strings - - LangString DESC_SecOpenVPNUserSpace ${LANG_ENGLISH} "Install ${PRODUCT_NAME} user-space components, including ${PRODUCT_UNIX_NAME}.exe." - -!ifdef USE_GUI - LangString DESC_SecOpenVPNGUI ${LANG_ENGLISH} "Install ${PRODUCT_NAME} GUI by Mathias Sundman" -!endif - - LangString DESC_SecOpenVPNEasyRSA ${LANG_ENGLISH} "Install ${PRODUCT_NAME} RSA scripts for X509 certificate management." - - LangString DESC_SecOpenSSLDLLs ${LANG_ENGLISH} "Install OpenSSL DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecPKCS11DLLs ${LANG_ENGLISH} "Install PKCS#11 helper DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecLZO2DLLs ${LANG_ENGLISH} "Install LZO2 DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecMSVCR90DLL ${LANG_ENGLISH} "Install Microsoft Visual C 9.0 Runtime (may be omitted if it is already installed globally)." - - LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP virtual device driver. Will not interfere with CIPE." - - LangString DESC_SecService ${LANG_ENGLISH} "Install the ${PRODUCT_NAME} service wrapper (${PRODUCT_UNIX_NAME}serv.exe)" - - LangString DESC_SecOpenSSLUtilities ${LANG_ENGLISH} "Install the OpenSSL Utilities (used for generating public/private key pairs)." - - LangString DESC_SecAddPath ${LANG_ENGLISH} "Add ${PRODUCT_NAME} executable directory to the current user's PATH." - - LangString DESC_SecAddShortcuts ${LANG_ENGLISH} "Add ${PRODUCT_NAME} shortcuts to the current user's Start Menu." - - LangString DESC_SecFileAssociation ${LANG_ENGLISH} "Register ${PRODUCT_NAME} config file association (*.${SERV_CONFIG_EXT})" - -;-------------------------------- -;Reserve Files - - ;Things that need to be extracted on first (keep these lines before any File command!) - ;Only useful for BZIP2 compression - - ReserveFile "..\images\install-whirl.bmp" - -;-------------------------------- -;Macros - -!macro WriteRegStringIfUndef ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 "" +1 +2 -WriteRegStr "${ROOT}" "${SUBKEY}" "${KEY}" '${VALUE}' -Pop $R0 -!macroend - -!macro DelRegStringIfUnchanged ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegValue "${ROOT}" "${SUBKEY}" "${KEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfUnchanged ROOT SUBKEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegKey "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfEmpty ROOT SUBKEY -Push $R0 -EnumRegValue $R0 "${ROOT}" "${SUBKEY}" 1 -StrCmp $R0 "" +1 +2 -DeleteRegKey /ifempty "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -;------------------------------------------ -;Set reboot flag based on tapinstall return - -Function CheckReboot - IntCmp $R0 1 "" noreboot noreboot - IntOp $R0 0 & 0 - SetRebootFlag true - DetailPrint "REBOOT flag set" - noreboot: -FunctionEnd - -;-------------------------------- -;Installer Sections - -Function .onInit - ClearErrors - -# Verify that user has admin privs - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to install ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: - -# Delete previous start menu - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - -# FIXME: reimplement Windows version checking code that was located here, but -# disabled intentionally to avoid Windows 7 issues. This should do it: -# -# http://nsis.sourceforge.net/Get_Windows_version -# -# Blacklisting should be safer than whitelisting used originally. - -FunctionEnd - -!ifndef SF_SELECTED -!define SF_SELECTED 1 -!endif - -;-------------------- -;Pre-install section - -Section -pre - - ; Stop OpenVPN if currently running - DetailPrint "Previous Service REMOVE (if exists)" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - - Sleep 3000 - - # Fix for Trac ticket 120. Remove after 2.3 has been released. - !ifdef USE_GUI - SetShellVarContext current - Delete "$DESKTOP\${PRODUCT_NAME} GUI.lnk" - !endif - -SectionEnd - -Section "${PRODUCT_NAME} User-Space Components" SecOpenVPNUserSpace - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${PRODUCT_UNIX_NAME}.exe" - -SectionEnd - -!ifdef USE_GUI -Section "${PRODUCT_NAME} GUI" SecOpenVPNGUI - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${OPENVPN_GUI}" - -SectionEnd -!endif - -Section "${PRODUCT_NAME} RSA Certificate Management Scripts" SecOpenVPNEasyRSA - - SetOverwrite on - SetOutPath "$INSTDIR\easy-rsa" - - # FIXME: the easy-rsa directory would need cleaning up - - # Original nsi script looked for ${EASYRSA}\2.0\openssl.cnf.sample. A newer - # openssl.cnf is needed on OpenVPN 2.2+. - File "${EASYRSA}\2.0\openssl-1.0.0.cnf" - - File "${EASYRSA}\Windows\vars.bat.sample" - - File "${EASYRSA}\Windows\init-config.bat" - - File "${EASYRSA}\Windows\README.txt" - File "${EASYRSA}\Windows\build-ca.bat" - File "${EASYRSA}\Windows\build-dh.bat" - File "${EASYRSA}\Windows\build-key-server.bat" - File "${EASYRSA}\Windows\build-key.bat" - File "${EASYRSA}\Windows\build-key-pkcs12.bat" - File "${EASYRSA}\Windows\clean-all.bat" - File "${EASYRSA}\Windows\index.txt.start" - File "${EASYRSA}\Windows\revoke-full.bat" - File "${EASYRSA}\Windows\serial.start" - -SectionEnd - -Section "${PRODUCT_NAME} Service" SecService - - SetOverwrite on - - SetOutPath "$INSTDIR\bin" - File "${BIN}\${PRODUCT_UNIX_NAME}serv.exe" - - SetOutPath "$INSTDIR\config" - - FileOpen $R0 "$INSTDIR\config\README.txt" w - FileWrite $R0 "This directory should contain ${PRODUCT_NAME} configuration files$\r$\n" - FileWrite $R0 "each having an extension of .${SERV_CONFIG_EXT}$\r$\n" - FileWrite $R0 "$\r$\n" - FileWrite $R0 "When ${PRODUCT_NAME} is started as a service, a separate ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "process will be instantiated for each configuration file.$\r$\n" - FileClose $R0 - - SetOutPath "$INSTDIR\sample-config" - File "${GEN}\samples\sample.${SERV_CONFIG_EXT}" - File "${GEN}\samples\client.${SERV_CONFIG_EXT}" - File "${GEN}\samples\server.${SERV_CONFIG_EXT}" - - CreateDirectory "$INSTDIR\log" - FileOpen $R0 "$INSTDIR\log\README.txt" w - FileWrite $R0 "This directory will contain the log files for ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "sessions which are being run as a service.$\r$\n" - FileClose $R0 - -SectionEnd - -Section "${PRODUCT_NAME} File Associations" SecFileAssociation -SectionEnd - -Section "OpenSSL DLLs" SecOpenSSLDLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\libeay32.dll" - File "${BIN}\ssleay32.dll" - -SectionEnd - -Section "OpenSSL Utilities" SecOpenSSLUtilities - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\openssl.exe" - -SectionEnd - -Section "PKCS#11 DLLs" SecPKCS11DLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\libpkcs11-helper-1.dll" - -SectionEnd - -Section "LZO2 DLLs" SecLZO2DLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\lzo2.dll" - -SectionEnd - -Section "Microsoft Visual C 9.0 Runtime DLL" SecMSVCR90DLL - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\Microsoft.VC90.CRT\msvcr90.dll" - File "${BIN}\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest" - -SectionEnd - - - - -Section "TAP Virtual Ethernet Adapter" SecTAP - - SetOverwrite on - - # Generate TAP driver install script dynamically - FileOpen $R0 "$INSTDIR\bin\addtap.bat" w - FileWrite $R0 "rem Add a new TAP virtual ethernet adapter$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - # Generate TAP driver removal script dynamically - FileOpen $R0 "$INSTDIR\bin\deltapall.bat" w - FileWrite $R0 "echo WARNING: this script will delete ALL TAP virtual adapters (use the device manager to delete adapters one at a time)$\r$\n" - FileWrite $R0 "pause$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - ; Check if we are running on a 64 bit system. - System::Call "kernel32::GetCurrentProcess() i .s" - System::Call "kernel32::IsWow64Process(i s, *i .r0)" - IntCmp $0 0 tap-32bit - -; tap-64bit: - - DetailPrint "We are running on a 64-bit system." - - SetOutPath "$INSTDIR\bin" - - File "${GEN}\amd64\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - - File "${GEN}\amd64\OemWin2k.inf" - File "${GEN}\amd64\${TAPDRV}" - - # Don't try to install TAP driver signature if it does not exist. - File /nonfatal "${GEN}\amd64\${PRODUCT_TAP_ID}.cat" - -goto tapend - -tap-32bit: - - DetailPrint "We are running on a 32-bit system." - - SetOutPath "$INSTDIR\bin" - File "${GEN}\i386\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - File "${GEN}\i386\OemWin2k.inf" - File "${GEN}\i386\${TAPDRV}" - - # Don't try to install TAP driver signature if it does not exist. - File /nonfatal "${GEN}\i386\${PRODUCT_TAP_ID}.cat" - - tapend: - -SectionEnd - -Section "Add ${PRODUCT_NAME} to PATH" SecAddPath - - ; remove previously set path (if any) - Push "$INSTDIR\bin" - Call RemoveFromPath - - ; append our bin directory to end of current user path - Push "$INSTDIR\bin" - Call AddToPath - -SectionEnd - -Section "Add Shortcuts to Start Menu" SecAddShortcuts - - ; Required to handle shortcuts properly on Vista/7 - SetShellVarContext all - SetOverwrite on - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Documentation" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Windows Notes.url" "InternetShortcut" "URL" "http://openvpn.net/INSTALL-win32.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Manual Page.url" "InternetShortcut" "URL" "http://openvpn.net/man.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} HOWTO.url" "InternetShortcut" "URL" "http://openvpn.net/howto.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Web Site.url" "InternetShortcut" "URL" "http://openvpn.net/" - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk" "$INSTDIR\Uninstall.exe" - -SectionEnd - -;-------------------- -;Post-install section - -Section -post - - SetOverwrite on - - ; delete old tapinstall.exe - ;Delete "$INSTDIR\bin\tapinstall.exe" - - ; Store README, license, icon - SetOverwrite on - SetOutPath $INSTDIR - File "..\INSTALL-win32.txt" - File "..\COPYRIGHT.GPL" - File "..\images\${PRODUCT_ICON}" - - ; store sample config files - !ifdef SAMPCONF_DIR - SetOverwrite on - SetOutPath "$INSTDIR\config" - !ifdef SAMPCONF_CONF - File "${GEN}\conf\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - File "${GEN}\conf\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - File "${GEN}\conf\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - File "${GEN}\conf\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - File "${GEN}\conf\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - File "${GEN}\conf\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - File "${GEN}\conf\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - File "${GEN}\conf\${SAMPCONF_DH}" - !endif - !endif - - ; Try to extract files if present - !ifdef EXTRACT_FILES - Push "$INSTDIR" - Call MultiFileExtract - Pop $R0 - IntCmp $R0 0 +3 +1 +1 - DetailPrint "MultiFileExtract Failed status=$R0" - goto +2 - DetailPrint "MultiFileExtract Succeeded" - !endif - - ; - ; install/upgrade TAP driver if selected, using tapinstall.exe - ; - SectionGetFlags ${SecTAP} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" notap notap - ; TAP install/update was selected. - ; Should we install or update? - ; If tapinstall error occurred, $5 will - ; be nonzero. - IntOp $5 0 & 0 - nsExec::ExecToStack '"$INSTDIR\bin\tapinstall.exe" hwids ${TAP}' - Pop $R0 # return value/error/timeout - IntOp $5 $5 | $R0 - DetailPrint "tapinstall hwids returned: $R0" - - ; If tapinstall output string contains "${TAP}" we assume - ; that TAP device has been previously installed, - ; therefore we will update, not install. - Push "${TAP}" - Call StrStr - Pop $R0 - - IntCmp $5 0 "" tapinstall_check_error tapinstall_check_error - IntCmp $R0 -1 tapinstall - - ;tapupdate: - DetailPrint "TAP UPDATE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" update "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall update returned: $R0" - Goto tapinstall_check_error - - tapinstall: - DetailPrint "TAP REMOVE OLD TAP" - - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove TAP0801' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove TAP0801 returned: $R0" - - DetailPrint "TAP INSTALL (${TAP})" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall install returned: $R0" - - tapinstall_check_error: - DetailPrint "tapinstall cumulative status: $5" - IntCmp $5 0 notap - MessageBox MB_OK "An error occurred installing the TAP device driver." - - notap: - - ; Store install folder in registry - WriteRegStr HKLM SOFTWARE\${PRODUCT_NAME} "" $INSTDIR - - ; install as a service if requested - SectionGetFlags ${SecService} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noserv noserv - - ; set registry parameters for openvpnserv - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_dir" "${SERV_CONFIG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_ext" "${SERV_CONFIG_EXT}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "exe_path" "${SERV_EXE_PATH}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_dir" "${SERV_LOG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "priority" "${SERV_PRIORITY}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_append" "${SERV_LOG_APPEND}" - - ; install openvpnserv as a service (to be started manually from service control manager) - DetailPrint "Service INSTALL" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -install' - Pop $R0 # return value/error/timeout - - noserv: - - ; Create file association if requested - fileass: - SectionGetFlags ${SecFileAssociation} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noass noass - WriteRegStr HKCR ".${SERV_CONFIG_EXT}" "" "${PRODUCT_NAME}File" - WriteRegStr HKCR "${PRODUCT_NAME}File" "" "${PRODUCT_NAME} Config File" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell" "" "open" - WriteRegStr HKCR "${PRODUCT_NAME}File\DefaultIcon" "" "$INSTDIR\${PRODUCT_ICON},0" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\open\command" "" 'notepad.exe "%1"' - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run" "" "Start ${PRODUCT_NAME} on this config file" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run\command" "" '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" --pause-exit --config "%1"' - - ; Create start menu folders - noass: - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Utilities" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts" - - ; Create start menu and desktop shortcuts to OpenVPN GUI - !ifdef USE_GUI - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" "" - CreateShortcut "$DESKTOP\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" - !endif - - ; Create start menu shortcuts to addtap.bat and deltapall.bat - tryaddtap: - IfFileExists "$INSTDIR\bin\addtap.bat" "" trydeltap - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Add a new TAP virtual ethernet adapter.lnk" "$INSTDIR\bin\addtap.bat" "" - - trydeltap: - IfFileExists "$INSTDIR\bin\deltapall.bat" "" config_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Delete ALL TAP virtual ethernet adapters.lnk" "$INSTDIR\bin\deltapall.bat" "" - - ; Create start menu shortcuts for config and log directories - config_shortcut: - IfFileExists "$INSTDIR\config" "" log_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} configuration file directory.lnk" "$INSTDIR\config" "" - - log_shortcut: - IfFileExists "$INSTDIR\log" "" samp_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} log file directory.lnk" "$INSTDIR\log" "" - - samp_shortcut: - IfFileExists "$INSTDIR\sample-config" "" genkey_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} Sample Configuration Files.lnk" "$INSTDIR\sample-config" "" - - genkey_shortcut: - IfFileExists "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" "" noshortcuts - IfFileExists "$INSTDIR\config" "" noshortcuts - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Generate a static ${PRODUCT_NAME} key.lnk" "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" '--pause-exit --verb 3 --genkey --secret "$INSTDIR\config\key.txt"' "$INSTDIR\${PRODUCT_ICON}" 0 - - noshortcuts: - ; Create uninstaller - WriteUninstaller "$INSTDIR\Uninstall.exe" - - ; Show up in Add/Remove programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME} ${VERSION}" - WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\${PRODUCT_ICON}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${VERSION}" - - ; Advise a reboot - ;Messagebox MB_OK "IMPORTANT: Rebooting the system is advised in order to finalize TAP driver installation/upgrade (this is an informational message only, pressing OK will not reboot)." - -SectionEnd - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNUserSpace} $(DESC_SecOpenVPNUserSpace) - !ifdef USE_GUI - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNGUI} $(DESC_SecOpenVPNGUI) - !endif - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNEasyRSA} $(DESC_SecOpenVPNEasyRSA) - !insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLUtilities} $(DESC_SecOpenSSLUtilities) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLDLLs} $(DESC_SecOpenSSLDLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecPKCS11DLLs} $(DESC_SecPKCS11DLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecLZO2DLLs} $(DESC_SecLZO2DLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecMSVCR90DLL} $(DESC_SecMSVCR90DLL) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddPath} $(DESC_SecAddPath) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddShortcuts} $(DESC_SecAddShortcuts) - - !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService) - !insertmacro MUI_DESCRIPTION_TEXT ${SecFileAssociation} $(DESC_SecFileAssociation) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;-------------------------------- -;Uninstaller Section - -Function un.onInit - ClearErrors - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to uninstall ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: -FunctionEnd - -Section "Uninstall" - - ; Required to handle shortcuts properly on Vista/7 - SetShellVarContext all - - ; Stop OpenVPN if currently running - - DetailPrint "Service REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - - Sleep 3000 - - DetailPrint "TAP REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove returned: $R0" - - Push "$INSTDIR\bin" - Call un.RemoveFromPath - - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - - ; delete sample config files - !ifdef SAMPCONF_DIR - !ifdef SAMPCONF_CONF - Delete "$INSTDIR\config\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - Delete "$INSTDIR\config\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - Delete "$INSTDIR\config\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - Delete "$INSTDIR\config\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - Delete "$INSTDIR\config\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - Delete "$INSTDIR\config\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - Delete "$INSTDIR\config\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - Delete "$INSTDIR\config\${SAMPCONF_DH}" - !endif - !endif - - !ifdef USE_GUI - Delete "$INSTDIR\bin\${OPENVPN_GUI}" - Delete "$DESKTOP\${PRODUCT_NAME} GUI.lnk" - !endif - - # Files installed by openvpn-2.2-beta5 and earlier - Delete "$INSTDIR\easy-rsa\openssl.cnf.sample" - Delete "$INSTDIR\license" - Delete "$INSTDIR\bin\libssl32.dll" - - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" - Delete "$INSTDIR\bin\libeay32.dll" - Delete "$INSTDIR\bin\ssleay32.dll" - Delete "$INSTDIR\bin\libpkcs11-helper-1.dll" - Delete "$INSTDIR\bin\lzo2.dll" - Delete "$INSTDIR\bin\msvcr90.dll" - Delete "$INSTDIR\bin\Microsoft.VC90.CRT.manifest" - Delete "$INSTDIR\bin\tapinstall.exe" - Delete "$INSTDIR\bin\addtap.bat" - Delete "$INSTDIR\bin\deltapall.bat" - - Delete "$INSTDIR\config\README.txt" - Delete "$INSTDIR\config\sample.${SERV_CONFIG_EXT}.txt" - - Delete "$INSTDIR\log\README.txt" - - Delete "$INSTDIR\driver\OemWin2k.inf" - Delete "$INSTDIR\driver\${PRODUCT_TAP_ID}.cat" - Delete "$INSTDIR\driver\${TAPDRV}" - - Delete "$INSTDIR\bin\openssl.exe" - - Delete "$INSTDIR\INSTALL-win32.txt" - Delete "$INSTDIR\${PRODUCT_ICON}" - Delete "$INSTDIR\COPYRIGHT.GPL" - Delete "$INSTDIR\Uninstall.exe" - - Delete "$INSTDIR\easy-rsa\openssl.cnf" - Delete "$INSTDIR\easy-rsa\vars.bat.sample" - Delete "$INSTDIR\easy-rsa\init-config.bat" - Delete "$INSTDIR\easy-rsa\README.txt" - Delete "$INSTDIR\easy-rsa\build-ca.bat" - Delete "$INSTDIR\easy-rsa\build-dh.bat" - Delete "$INSTDIR\easy-rsa\build-key-server.bat" - Delete "$INSTDIR\easy-rsa\build-key.bat" - Delete "$INSTDIR\easy-rsa\build-key-pkcs12.bat" - Delete "$INSTDIR\easy-rsa\clean-all.bat" - Delete "$INSTDIR\easy-rsa\index.txt.start" - Delete "$INSTDIR\easy-rsa\revoke-key.bat" - Delete "$INSTDIR\easy-rsa\revoke-full.bat" - Delete "$INSTDIR\easy-rsa\serial.start" - - Delete "$INSTDIR\sample-config\*.${PRODUCT_FILE_EXT}" - - RMDir "$INSTDIR\bin" - RMDir "$INSTDIR\config" - RMDir "$INSTDIR\driver" - RMDir "$INSTDIR\easy-rsa" - RMDir "$INSTDIR\sample-config" - RMDir /r "$INSTDIR\log" - RMDir "$INSTDIR" - - !insertmacro DelRegKeyIfUnchanged HKCR ".${SERV_CONFIG_EXT}" "${PRODUCT_NAME}File" - DeleteRegKey HKCR "${PRODUCT_NAME}File" - DeleteRegKey HKLM SOFTWARE\${PRODUCT_NAME} - DeleteRegKey HKCU "Software\${PRODUCT_NAME}" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" - -SectionEnd diff --git a/win/openvpn.nsi.orig b/win/openvpn.nsi.orig deleted file mode 100755 index d667d76..0000000 --- a/win/openvpn.nsi.orig +++ /dev/null @@ -1,822 +0,0 @@ -; **************************************************************************** -; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * -; * 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. * -; **************************************************************************** - -; OpenVPN install script for Windows, using NSIS - -; Start menu entries don't get uninstalled properly on Windows Vista/7 unless we -; explicitly state that the installer requires admin privileges. This is -; caused by backwards compatibility tricks used on those platforms. For details, -; see http://nsis.sourceforge.net/Shortcuts_removal_fails_on_Windows_Vista -RequestExecutionLevel admin - -SetCompressor lzma - -!include "MUI.nsh" - -# Include basic build settings -!include "settings.in" - -# Include variables generated dynamically from version.m4 by wb.py -!include "version_m4_vars.tmp" - -;!include "guidefs.nsi" -!include "setpath.nsi" - -!ifdef EXTRACT_FILES -!include "MultiFileExtract.nsi" -!endif - -!define GEN "..\dist" -!define BIN "${GEN}\bin" -!define EASYRSA "..\easy-rsa" - -!define PRODUCT_ICON "icon.ico" - -!ifdef PRODUCT_TAP_DEBUG -!define DBG_POSTFIX "-DBG" -!else -!define DBG_POSTFIX "" -!endif - -!define VERSION "${PRODUCT_VERSION}${DBG_POSTFIX}" - -!define TAP "${PRODUCT_TAP_ID}" -!define TAPDRV "${TAP}.sys" - -; Default service settings -!define SERV_CONFIG_DIR "$INSTDIR\config" -!define SERV_CONFIG_EXT "${PRODUCT_FILE_EXT}" -!define SERV_EXE_PATH "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" -!define SERV_LOG_DIR "$INSTDIR\log" -!define SERV_PRIORITY "NORMAL_PRIORITY_CLASS" -!define SERV_LOG_APPEND "0" - -;-------------------------------- -;Configuration - - ;General - - OutFile "${GEN}\${PRODUCT_UNIX_NAME}-${VERSION}${OUTFILE_LABEL}-install.exe" - - ShowInstDetails show - ShowUninstDetails show - - ;Folder selection page - InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" - - ;Remember install folder - InstallDirRegKey HKCU "Software\${PRODUCT_NAME}" "" - -;-------------------------------- -;Modern UI Configuration - - Name "${PRODUCT_NAME} ${VERSION} ${TITLE_LABEL}" - - !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of ${PRODUCT_NAME}, an Open Source VPN package by James Yonan.\r\n\r\nNote that the Windows version of ${PRODUCT_NAME} only runs on XP, or higher.\r\n\r\n\r\n" - - !define MUI_COMPONENTSPAGE_TEXT_TOP "Select the components to install/upgrade. Stop any ${PRODUCT_NAME} processes or the ${PRODUCT_NAME} service if it is running. All DLLs are installed locally." - - !define MUI_COMPONENTSPAGE_SMALLDESC - !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\INSTALL-win32.txt" - !define MUI_FINISHPAGE_NOAUTOCLOSE - !define MUI_ABORTWARNING - !define MUI_ICON "..\images\${PRODUCT_ICON}" - !define MUI_UNICON "..\images\${PRODUCT_ICON}" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "..\images\install-whirl.bmp" - !define MUI_UNFINISHPAGE_NOAUTOCLOSE - - !insertmacro MUI_PAGE_WELCOME - !insertmacro MUI_PAGE_LICENSE "..\COPYRIGHT.GPL" - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_UNPAGE_FINISH - - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -;Language Strings - - LangString DESC_SecOpenVPNUserSpace ${LANG_ENGLISH} "Install ${PRODUCT_NAME} user-space components, including ${PRODUCT_UNIX_NAME}.exe." - -!ifdef USE_GUI - LangString DESC_SecOpenVPNGUI ${LANG_ENGLISH} "Install ${PRODUCT_NAME} GUI by Mathias Sundman" -!endif - - LangString DESC_SecOpenVPNEasyRSA ${LANG_ENGLISH} "Install ${PRODUCT_NAME} RSA scripts for X509 certificate management." - - LangString DESC_SecOpenSSLDLLs ${LANG_ENGLISH} "Install OpenSSL DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecPKCS11DLLs ${LANG_ENGLISH} "Install PKCS#11 helper DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecLZO2DLLs ${LANG_ENGLISH} "Install LZO2 DLLs locally (may be omitted if DLLs are already installed globally)." - - LangString DESC_SecMSVCR90DLL ${LANG_ENGLISH} "Install Microsoft Visual C 9.0 Runtime (may be omitted if it is already installed globally)." - - LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP virtual device driver. Will not interfere with CIPE." - - LangString DESC_SecService ${LANG_ENGLISH} "Install the ${PRODUCT_NAME} service wrapper (${PRODUCT_UNIX_NAME}serv.exe)" - - LangString DESC_SecOpenSSLUtilities ${LANG_ENGLISH} "Install the OpenSSL Utilities (used for generating public/private key pairs)." - - LangString DESC_SecAddPath ${LANG_ENGLISH} "Add ${PRODUCT_NAME} executable directory to the current user's PATH." - - LangString DESC_SecAddShortcuts ${LANG_ENGLISH} "Add ${PRODUCT_NAME} shortcuts to the current user's Start Menu." - - LangString DESC_SecFileAssociation ${LANG_ENGLISH} "Register ${PRODUCT_NAME} config file association (*.${SERV_CONFIG_EXT})" - -;-------------------------------- -;Reserve Files - - ;Things that need to be extracted on first (keep these lines before any File command!) - ;Only useful for BZIP2 compression - - ReserveFile "..\images\install-whirl.bmp" - -;-------------------------------- -;Macros - -!macro WriteRegStringIfUndef ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 "" +1 +2 -WriteRegStr "${ROOT}" "${SUBKEY}" "${KEY}" '${VALUE}' -Pop $R0 -!macroend - -!macro DelRegStringIfUnchanged ROOT SUBKEY KEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "${KEY}" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegValue "${ROOT}" "${SUBKEY}" "${KEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfUnchanged ROOT SUBKEY VALUE -Push $R0 -ReadRegStr $R0 "${ROOT}" "${SUBKEY}" "" -StrCmp $R0 '${VALUE}' +1 +2 -DeleteRegKey "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -!macro DelRegKeyIfEmpty ROOT SUBKEY -Push $R0 -EnumRegValue $R0 "${ROOT}" "${SUBKEY}" 1 -StrCmp $R0 "" +1 +2 -DeleteRegKey /ifempty "${ROOT}" "${SUBKEY}" -Pop $R0 -!macroend - -;------------------------------------------ -;Set reboot flag based on tapinstall return - -Function CheckReboot - IntCmp $R0 1 "" noreboot noreboot - IntOp $R0 0 & 0 - SetRebootFlag true - DetailPrint "REBOOT flag set" - noreboot: -FunctionEnd - -;-------------------------------- -;Installer Sections - -Function .onInit - ClearErrors - -# Verify that user has admin privs - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to install ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: - -# Delete previous start menu - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - -# FIXME: reimplement Windows version checking code that was located here, but -# disabled intentionally to avoid Windows 7 issues. This should do it: -# -# http://nsis.sourceforge.net/Get_Windows_version -# -# Blacklisting should be safer than whitelisting used originally. - -FunctionEnd - -!ifndef SF_SELECTED -!define SF_SELECTED 1 -!endif - -;-------------------- -;Pre-install section - -Section -pre - - ; Stop OpenVPN if currently running - DetailPrint "Previous Service REMOVE (if exists)" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - - Sleep 3000 - - # Fix for Trac ticket 120. Remove after 2.3 has been released. - !ifdef USE_GUI - SetShellVarContext current - Delete "$DESKTOP\${PRODUCT_NAME} GUI.lnk" - !endif - -SectionEnd - -Section "${PRODUCT_NAME} User-Space Components" SecOpenVPNUserSpace - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${PRODUCT_UNIX_NAME}.exe" - -SectionEnd - -!ifdef USE_GUI -Section "${PRODUCT_NAME} GUI" SecOpenVPNGUI - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - - File "${BIN}\${OPENVPN_GUI}" - -SectionEnd -!endif - -Section "${PRODUCT_NAME} RSA Certificate Management Scripts" SecOpenVPNEasyRSA - - SetOverwrite on - SetOutPath "$INSTDIR\easy-rsa" - - # FIXME: the easy-rsa directory would need cleaning up - - # Original nsi script looked for ${EASYRSA}\2.0\openssl.cnf.sample. A newer - # openssl.cnf is needed on OpenVPN 2.2+. - File "${EASYRSA}\Windows\openssl.cnf" - - File "${EASYRSA}\Windows\vars.bat.sample" - - File "${EASYRSA}\Windows\init-config.bat" - - File "${EASYRSA}\Windows\README.txt" - File "${EASYRSA}\Windows\build-ca.bat" - File "${EASYRSA}\Windows\build-dh.bat" - File "${EASYRSA}\Windows\build-key-server.bat" - File "${EASYRSA}\Windows\build-key.bat" - File "${EASYRSA}\Windows\build-key-pkcs12.bat" - File "${EASYRSA}\Windows\clean-all.bat" - File "${EASYRSA}\Windows\index.txt.start" - File "${EASYRSA}\Windows\revoke-full.bat" - File "${EASYRSA}\Windows\serial.start" - -SectionEnd - -Section "${PRODUCT_NAME} Service" SecService - - SetOverwrite on - - SetOutPath "$INSTDIR\bin" - File "${BIN}\${PRODUCT_UNIX_NAME}serv.exe" - - SetOutPath "$INSTDIR\config" - - FileOpen $R0 "$INSTDIR\config\README.txt" w - FileWrite $R0 "This directory should contain ${PRODUCT_NAME} configuration files$\r$\n" - FileWrite $R0 "each having an extension of .${SERV_CONFIG_EXT}$\r$\n" - FileWrite $R0 "$\r$\n" - FileWrite $R0 "When ${PRODUCT_NAME} is started as a service, a separate ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "process will be instantiated for each configuration file.$\r$\n" - FileClose $R0 - - SetOutPath "$INSTDIR\sample-config" - File "${GEN}\samples\sample.${SERV_CONFIG_EXT}" - File "${GEN}\samples\client.${SERV_CONFIG_EXT}" - File "${GEN}\samples\server.${SERV_CONFIG_EXT}" - - CreateDirectory "$INSTDIR\log" - FileOpen $R0 "$INSTDIR\log\README.txt" w - FileWrite $R0 "This directory will contain the log files for ${PRODUCT_NAME}$\r$\n" - FileWrite $R0 "sessions which are being run as a service.$\r$\n" - FileClose $R0 - -SectionEnd - -Section "${PRODUCT_NAME} File Associations" SecFileAssociation -SectionEnd - -Section "OpenSSL DLLs" SecOpenSSLDLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\libeay32.dll" - File "${BIN}\ssleay32.dll" - -SectionEnd - -Section "OpenSSL Utilities" SecOpenSSLUtilities - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\openssl.exe" - -SectionEnd - -Section "PKCS#11 DLLs" SecPKCS11DLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\libpkcs11-helper-1.dll" - -SectionEnd - -Section "LZO2 DLLs" SecLZO2DLLs - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\lzo2.dll" - -SectionEnd - -Section "Microsoft Visual C 9.0 Runtime DLL" SecMSVCR90DLL - - SetOverwrite on - SetOutPath "$INSTDIR\bin" - File "${BIN}\Microsoft.VC90.CRT\msvcr90.dll" - File "${BIN}\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest" - -SectionEnd - - - - -Section "TAP Virtual Ethernet Adapter" SecTAP - - SetOverwrite on - - # Generate TAP driver install script dynamically - FileOpen $R0 "$INSTDIR\bin\addtap.bat" w - FileWrite $R0 "rem Add a new TAP virtual ethernet adapter$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - # Generate TAP driver removal script dynamically - FileOpen $R0 "$INSTDIR\bin\deltapall.bat" w - FileWrite $R0 "echo WARNING: this script will delete ALL TAP virtual adapters (use the device manager to delete adapters one at a time)$\r$\n" - FileWrite $R0 "pause$\r$\n" - FileWrite $R0 '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}$\r$\n' - FileWrite $R0 "pause$\r$\n" - FileClose $R0 - - ; Check if we are running on a 64 bit system. - System::Call "kernel32::GetCurrentProcess() i .s" - System::Call "kernel32::IsWow64Process(i s, *i .r0)" - IntCmp $0 0 tap-32bit - -; tap-64bit: - - DetailPrint "We are running on a 64-bit system." - - SetOutPath "$INSTDIR\bin" - - File "${GEN}\amd64\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - - File "${GEN}\amd64\OemWin2k.inf" - File "${GEN}\amd64\${TAPDRV}" - - # Don't try to install TAP driver signature if it does not exist. - File /nonfatal "${GEN}\amd64\${PRODUCT_TAP_ID}.cat" - -goto tapend - -tap-32bit: - - DetailPrint "We are running on a 32-bit system." - - SetOutPath "$INSTDIR\bin" - File "${GEN}\i386\tapinstall.exe" - - SetOutPath "$INSTDIR\driver" - File "${GEN}\i386\OemWin2k.inf" - File "${GEN}\i386\${TAPDRV}" - - # Don't try to install TAP driver signature if it does not exist. - File /nonfatal "${GEN}\i386\${PRODUCT_TAP_ID}.cat" - - tapend: - -SectionEnd - -Section "Add ${PRODUCT_NAME} to PATH" SecAddPath - - ; remove previously set path (if any) - Push "$INSTDIR\bin" - Call RemoveFromPath - - ; append our bin directory to end of current user path - Push "$INSTDIR\bin" - Call AddToPath - -SectionEnd - -Section "Add Shortcuts to Start Menu" SecAddShortcuts - - ; Required to handle shortcuts properly on Vista/7 - SetShellVarContext all - SetOverwrite on - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Documentation" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Windows Notes.url" "InternetShortcut" "URL" "http://openvpn.net/INSTALL-win32.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Manual Page.url" "InternetShortcut" "URL" "http://openvpn.net/man.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} HOWTO.url" "InternetShortcut" "URL" "http://openvpn.net/howto.html" - WriteINIStr "$SMPROGRAMS\${PRODUCT_NAME}\Documentation\${PRODUCT_NAME} Web Site.url" "InternetShortcut" "URL" "http://openvpn.net/" - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk" "$INSTDIR\Uninstall.exe" - -SectionEnd - -;-------------------- -;Post-install section - -Section -post - - SetOverwrite on - - ; delete old tapinstall.exe - ;Delete "$INSTDIR\bin\tapinstall.exe" - - ; Store README, license, icon - SetOverwrite on - SetOutPath $INSTDIR - File "..\INSTALL-win32.txt" - File "..\COPYRIGHT.GPL" - File "..\images\${PRODUCT_ICON}" - - ; store sample config files - !ifdef SAMPCONF_DIR - SetOverwrite on - SetOutPath "$INSTDIR\config" - !ifdef SAMPCONF_CONF - File "${GEN}\conf\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - File "${GEN}\conf\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - File "${GEN}\conf\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - File "${GEN}\conf\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - File "${GEN}\conf\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - File "${GEN}\conf\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - File "${GEN}\conf\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - File "${GEN}\conf\${SAMPCONF_DH}" - !endif - !endif - - ; Try to extract files if present - !ifdef EXTRACT_FILES - Push "$INSTDIR" - Call MultiFileExtract - Pop $R0 - IntCmp $R0 0 +3 +1 +1 - DetailPrint "MultiFileExtract Failed status=$R0" - goto +2 - DetailPrint "MultiFileExtract Succeeded" - !endif - - ; - ; install/upgrade TAP driver if selected, using tapinstall.exe - ; - SectionGetFlags ${SecTAP} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" notap notap - ; TAP install/update was selected. - ; Should we install or update? - ; If tapinstall error occurred, $5 will - ; be nonzero. - IntOp $5 0 & 0 - nsExec::ExecToStack '"$INSTDIR\bin\tapinstall.exe" hwids ${TAP}' - Pop $R0 # return value/error/timeout - IntOp $5 $5 | $R0 - DetailPrint "tapinstall hwids returned: $R0" - - ; If tapinstall output string contains "${TAP}" we assume - ; that TAP device has been previously installed, - ; therefore we will update, not install. - Push "${TAP}" - Call StrStr - Pop $R0 - - IntCmp $5 0 "" tapinstall_check_error tapinstall_check_error - IntCmp $R0 -1 tapinstall - - ;tapupdate: - DetailPrint "TAP UPDATE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" update "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall update returned: $R0" - Goto tapinstall_check_error - - tapinstall: - DetailPrint "TAP REMOVE OLD TAP" - - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove TAP0801' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove TAP0801 returned: $R0" - - DetailPrint "TAP INSTALL (${TAP})" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" install "$INSTDIR\driver\OemWin2k.inf" ${TAP}' - Pop $R0 # return value/error/timeout - Call CheckReboot - IntOp $5 $5 | $R0 - DetailPrint "tapinstall install returned: $R0" - - tapinstall_check_error: - DetailPrint "tapinstall cumulative status: $5" - IntCmp $5 0 notap - MessageBox MB_OK "An error occurred installing the TAP device driver." - - notap: - - ; Store install folder in registry - WriteRegStr HKLM SOFTWARE\${PRODUCT_NAME} "" $INSTDIR - - ; install as a service if requested - SectionGetFlags ${SecService} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noserv noserv - - ; set registry parameters for openvpnserv - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_dir" "${SERV_CONFIG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "config_ext" "${SERV_CONFIG_EXT}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "exe_path" "${SERV_EXE_PATH}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_dir" "${SERV_LOG_DIR}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "priority" "${SERV_PRIORITY}" - !insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\${PRODUCT_NAME}" "log_append" "${SERV_LOG_APPEND}" - - ; install openvpnserv as a service (to be started manually from service control manager) - DetailPrint "Service INSTALL" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -install' - Pop $R0 # return value/error/timeout - - noserv: - - ; Create file association if requested - fileass: - SectionGetFlags ${SecFileAssociation} $R0 - IntOp $R0 $R0 & ${SF_SELECTED} - IntCmp $R0 ${SF_SELECTED} "" noass noass - WriteRegStr HKCR ".${SERV_CONFIG_EXT}" "" "${PRODUCT_NAME}File" - WriteRegStr HKCR "${PRODUCT_NAME}File" "" "${PRODUCT_NAME} Config File" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell" "" "open" - WriteRegStr HKCR "${PRODUCT_NAME}File\DefaultIcon" "" "$INSTDIR\${PRODUCT_ICON},0" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\open\command" "" 'notepad.exe "%1"' - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run" "" "Start ${PRODUCT_NAME} on this config file" - WriteRegStr HKCR "${PRODUCT_NAME}File\shell\run\command" "" '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" --pause-exit --config "%1"' - - ; Create start menu folders - noass: - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Utilities" - CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts" - - ; Create start menu and desktop shortcuts to OpenVPN GUI - !ifdef USE_GUI - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" "" - CreateShortcut "$DESKTOP\${PRODUCT_NAME} GUI.lnk" "$INSTDIR\bin\${OPENVPN_GUI}" - !endif - - ; Create start menu shortcuts to addtap.bat and deltapall.bat - tryaddtap: - IfFileExists "$INSTDIR\bin\addtap.bat" "" trydeltap - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Add a new TAP virtual ethernet adapter.lnk" "$INSTDIR\bin\addtap.bat" "" - - trydeltap: - IfFileExists "$INSTDIR\bin\deltapall.bat" "" config_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Delete ALL TAP virtual ethernet adapters.lnk" "$INSTDIR\bin\deltapall.bat" "" - - ; Create start menu shortcuts for config and log directories - config_shortcut: - IfFileExists "$INSTDIR\config" "" log_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} configuration file directory.lnk" "$INSTDIR\config" "" - - log_shortcut: - IfFileExists "$INSTDIR\log" "" samp_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} log file directory.lnk" "$INSTDIR\log" "" - - samp_shortcut: - IfFileExists "$INSTDIR\sample-config" "" genkey_shortcut - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Shortcuts\${PRODUCT_NAME} Sample Configuration Files.lnk" "$INSTDIR\sample-config" "" - - genkey_shortcut: - IfFileExists "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" "" noshortcuts - IfFileExists "$INSTDIR\config" "" noshortcuts - CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Generate a static ${PRODUCT_NAME} key.lnk" "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" '--pause-exit --verb 3 --genkey --secret "$INSTDIR\config\key.txt"' "$INSTDIR\${PRODUCT_ICON}" 0 - - noshortcuts: - ; Create uninstaller - WriteUninstaller "$INSTDIR\Uninstall.exe" - - ; Show up in Add/Remove programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME} ${VERSION}" - WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\${PRODUCT_ICON}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${VERSION}" - - ; Advise a reboot - ;Messagebox MB_OK "IMPORTANT: Rebooting the system is advised in order to finalize TAP driver installation/upgrade (this is an informational message only, pressing OK will not reboot)." - -SectionEnd - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNUserSpace} $(DESC_SecOpenVPNUserSpace) - !ifdef USE_GUI - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNGUI} $(DESC_SecOpenVPNGUI) - !endif - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenVPNEasyRSA} $(DESC_SecOpenVPNEasyRSA) - !insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLUtilities} $(DESC_SecOpenSSLUtilities) - !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLDLLs} $(DESC_SecOpenSSLDLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecPKCS11DLLs} $(DESC_SecPKCS11DLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecLZO2DLLs} $(DESC_SecLZO2DLLs) - !insertmacro MUI_DESCRIPTION_TEXT ${SecMSVCR90DLL} $(DESC_SecMSVCR90DLL) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddPath} $(DESC_SecAddPath) - !insertmacro MUI_DESCRIPTION_TEXT ${SecAddShortcuts} $(DESC_SecAddShortcuts) - - !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService) - !insertmacro MUI_DESCRIPTION_TEXT ${SecFileAssociation} $(DESC_SecFileAssociation) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;-------------------------------- -;Uninstaller Section - -Function un.onInit - ClearErrors - UserInfo::GetName - IfErrors ok - Pop $R0 - UserInfo::GetAccountType - Pop $R1 - StrCmp $R1 "Admin" ok - Messagebox MB_OK "Administrator privileges required to uninstall ${PRODUCT_NAME} [$R0/$R1]" - Abort - ok: -FunctionEnd - -Section "Uninstall" - - ; Required to handle shortcuts properly on Vista/7 - SetShellVarContext all - - ; Stop OpenVPN if currently running - - DetailPrint "Service REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" -remove' - Pop $R0 # return value/error/timeout - - Sleep 3000 - - DetailPrint "TAP REMOVE" - nsExec::ExecToLog '"$INSTDIR\bin\tapinstall.exe" remove ${TAP}' - Pop $R0 # return value/error/timeout - DetailPrint "tapinstall remove returned: $R0" - - Push "$INSTDIR\bin" - Call un.RemoveFromPath - - RMDir /r $SMPROGRAMS\${PRODUCT_NAME} - - ; delete sample config files - !ifdef SAMPCONF_DIR - !ifdef SAMPCONF_CONF - Delete "$INSTDIR\config\${SAMPCONF_CONF}" - !endif - !ifdef SAMPCONF_CONF2 - Delete "$INSTDIR\config\${SAMPCONF_CONF2}" - !endif - !ifdef SAMPCONF_P12 - Delete "$INSTDIR\config\${SAMPCONF_P12}" - !endif - !ifdef SAMPCONF_TA - Delete "$INSTDIR\config\${SAMPCONF_TA}" - !endif - !ifdef SAMPCONF_CA - Delete "$INSTDIR\config\${SAMPCONF_CA}" - !endif - !ifdef SAMPCONF_CRT - Delete "$INSTDIR\config\${SAMPCONF_CRT}" - !endif - !ifdef SAMPCONF_KEY - Delete "$INSTDIR\config\${SAMPCONF_KEY}" - !endif - !ifdef SAMPCONF_DH - Delete "$INSTDIR\config\${SAMPCONF_DH}" - !endif - !endif - - !ifdef USE_GUI - Delete "$INSTDIR\bin\${OPENVPN_GUI}" - Delete "$DESKTOP\${PRODUCT_NAME} GUI.lnk" - !endif - - # Files installed by openvpn-2.2-beta5 and earlier - Delete "$INSTDIR\easy-rsa\openssl.cnf.sample" - Delete "$INSTDIR\license" - Delete "$INSTDIR\bin\libssl32.dll" - - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}.exe" - Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe" - Delete "$INSTDIR\bin\libeay32.dll" - Delete "$INSTDIR\bin\ssleay32.dll" - Delete "$INSTDIR\bin\libpkcs11-helper-1.dll" - Delete "$INSTDIR\bin\lzo2.dll" - Delete "$INSTDIR\bin\msvcr90.dll" - Delete "$INSTDIR\bin\Microsoft.VC90.CRT.manifest" - Delete "$INSTDIR\bin\tapinstall.exe" - Delete "$INSTDIR\bin\addtap.bat" - Delete "$INSTDIR\bin\deltapall.bat" - - Delete "$INSTDIR\config\README.txt" - Delete "$INSTDIR\config\sample.${SERV_CONFIG_EXT}.txt" - - Delete "$INSTDIR\log\README.txt" - - Delete "$INSTDIR\driver\OemWin2k.inf" - Delete "$INSTDIR\driver\${PRODUCT_TAP_ID}.cat" - Delete "$INSTDIR\driver\${TAPDRV}" - - Delete "$INSTDIR\bin\openssl.exe" - - Delete "$INSTDIR\INSTALL-win32.txt" - Delete "$INSTDIR\${PRODUCT_ICON}" - Delete "$INSTDIR\COPYRIGHT.GPL" - Delete "$INSTDIR\Uninstall.exe" - - Delete "$INSTDIR\easy-rsa\openssl.cnf" - Delete "$INSTDIR\easy-rsa\vars.bat.sample" - Delete "$INSTDIR\easy-rsa\init-config.bat" - Delete "$INSTDIR\easy-rsa\README.txt" - Delete "$INSTDIR\easy-rsa\build-ca.bat" - Delete "$INSTDIR\easy-rsa\build-dh.bat" - Delete "$INSTDIR\easy-rsa\build-key-server.bat" - Delete "$INSTDIR\easy-rsa\build-key.bat" - Delete "$INSTDIR\easy-rsa\build-key-pkcs12.bat" - Delete "$INSTDIR\easy-rsa\clean-all.bat" - Delete "$INSTDIR\easy-rsa\index.txt.start" - Delete "$INSTDIR\easy-rsa\revoke-key.bat" - Delete "$INSTDIR\easy-rsa\revoke-full.bat" - Delete "$INSTDIR\easy-rsa\serial.start" - - Delete "$INSTDIR\sample-config\*.${PRODUCT_FILE_EXT}" - - RMDir "$INSTDIR\bin" - RMDir "$INSTDIR\config" - RMDir "$INSTDIR\driver" - RMDir "$INSTDIR\easy-rsa" - RMDir "$INSTDIR\sample-config" - RMDir /r "$INSTDIR\log" - RMDir "$INSTDIR" - - !insertmacro DelRegKeyIfUnchanged HKCR ".${SERV_CONFIG_EXT}" "${PRODUCT_NAME}File" - DeleteRegKey HKCR "${PRODUCT_NAME}File" - DeleteRegKey HKLM SOFTWARE\${PRODUCT_NAME} - DeleteRegKey HKCU "Software\${PRODUCT_NAME}" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" - -SectionEnd diff --git a/win/setpath.nsi b/win/setpath.nsi deleted file mode 100755 index a9626c3..0000000 --- a/win/setpath.nsi +++ /dev/null @@ -1,231 +0,0 @@ -; Modify the user's PATH variable. -; -; Modified by JY to have both a RemoveFromPath -; and an un.RemoveFromPath which are basically -; copies of each other. Why does NSIS demand -; this nonsense? -; -; Modified Feb 14, 2005 by Mathias Sundman: -; Added code to remove the semicolon at the end of the path -; when uninstalling. -; -; Added code to make sure we don't insert an extra semicolon -; before our path if there already exist one at the end of -; the original path. -; -; Removed duplicated "un. and install" functions and made -; macros to duplicate the code instead. - -; example usage -; -;Section "Add to path" -; Push $INSTDIR -; Call AddToPath -;SectionEnd -; -;# ... -; -;Section "uninstall" -; # ... -; Push $INSTDIR -; Call un.RemoveFromPath -; # ... -;SectionEnd - -!verbose 3 -!include "WinMessages.NSH" -!verbose 4 - -;==================================================== -; AddToPath - Adds the given dir to the search path. -; Input - head of the stack -; Note - Win9x systems requires reboot -;==================================================== -Function AddToPath - Exch $0 - Push $1 - Push $2 - - Call IsNT - Pop $1 - StrCmp $1 1 AddToPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" a - FileSeek $1 0 END - GetFullPathName /SHORT $0 $0 - FileWrite $1 "$\r$\nSET PATH=%PATH%;$0$\r$\n" - FileClose $1 - Goto AddToPath_done - - AddToPath_NT: - ReadRegStr $1 HKCU "Environment" "PATH" - StrCpy $2 $1 1 -1 # copy last char - StrCmp $2 ";" 0 +2 # if last char == ; - StrCpy $1 $1 -1 # remove last char - - StrCmp $1 "" AddToPath_NTdoIt - StrCpy $0 "$1;$0" - Goto AddToPath_NTdoIt - AddToPath_NTdoIt: - WriteRegExpandStr HKCU "Environment" "PATH" $0 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - AddToPath_done: - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - -;==================================================== -; RemoveFromPath - Remove a given dir from the path -; Input: head of the stack -;==================================================== -!macro RemoveFromPath un -Function ${un}RemoveFromPath - Exch $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - - Call ${un}IsNT - Pop $1 - StrCmp $1 1 RemoveFromPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" r - GetTempFileName $4 - FileOpen $2 $4 w - GetFullPathName /SHORT $0 $0 - StrCpy $0 "SET PATH=%PATH%;$0" - SetRebootFlag true - Goto RemoveFromPath_dosLoop - - RemoveFromPath_dosLoop: - FileRead $1 $3 - StrCmp $3 "$0$\r$\n" RemoveFromPath_dosLoop - StrCmp $3 "$0$\n" RemoveFromPath_dosLoop - StrCmp $3 "$0" RemoveFromPath_dosLoop - StrCmp $3 "" RemoveFromPath_dosLoopEnd - FileWrite $2 $3 - Goto RemoveFromPath_dosLoop - - RemoveFromPath_dosLoopEnd: - FileClose $2 - FileClose $1 - StrCpy $1 $WINDIR 2 - Delete "$1\autoexec.bat" - CopyFiles /SILENT $4 "$1\autoexec.bat" - Delete $4 - Goto RemoveFromPath_done - - RemoveFromPath_NT: - StrLen $2 $0 - ReadRegStr $1 HKCU "Environment" "PATH" - Push $1 - Push $0 - Call ${un}StrStr ; Find $0 in $1 - Pop $0 ; pos of our dir - IntCmp $0 -1 RemoveFromPath_done - ; else, it is in path - StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir - IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';') - IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon. - StrLen $0 $1 - StrCpy $1 $1 $0 $2 - StrCpy $3 "$3$1" - - StrCpy $5 $3 1 -1 # copy last char - StrCmp $5 ";" 0 +2 # if last char == ; - StrCpy $3 $3 -1 # remove last char - - WriteRegExpandStr HKCU "Environment" "PATH" $3 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - RemoveFromPath_done: - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd -!macroend -!insertmacro RemoveFromPath "" -!insertmacro RemoveFromPath "un." - - -;==================================================== -; StrStr - Finds a given string in another given string. -; Returns -1 if not found and the pos if found. -; Input: head of the stack - string to find -; second in the stack - string to find in -; Output: head of the stack -;==================================================== -!macro StrStr un -Function ${un}StrStr - Push $0 - Exch - Pop $0 ; $0 now have the string to find - Push $1 - Exch 2 - Pop $1 ; $1 now have the string to find in - Exch - Push $2 - Push $3 - Push $4 - Push $5 - - StrCpy $2 -1 - StrLen $3 $0 - StrLen $4 $1 - IntOp $4 $4 - $3 - - StrStr_loop: - IntOp $2 $2 + 1 - IntCmp $2 $4 0 0 StrStrReturn_notFound - StrCpy $5 $1 $3 $2 - StrCmp $5 $0 StrStr_done StrStr_loop - - StrStrReturn_notFound: - StrCpy $2 -1 - - StrStr_done: - Pop $5 - Pop $4 - Pop $3 - Exch $2 - Exch 2 - Pop $0 - Pop $1 -FunctionEnd -!macroend -!insertmacro StrStr "" -!insertmacro StrStr "un." - -;==================================================== -; IsNT - Returns 1 if the current system is NT, 0 -; otherwise. -; Output: head of the stack -;==================================================== -!macro IsNT un -Function ${un}IsNT - Push $0 - ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $0 "" 0 IsNT_yes - ; we are not NT. - Pop $0 - Push 0 - Return - - IsNT_yes: - ; NT!!! - Pop $0 - Push 1 -FunctionEnd -!macroend -!insertmacro IsNT "" -!insertmacro IsNT "un." - diff --git a/win/settings.in b/win/settings.in deleted file mode 100644 index 10c7926..0000000 --- a/win/settings.in +++ /dev/null @@ -1,87 +0,0 @@ -# Version numbers, settings, and dependencies -# for Windows OpenVPN installer. -# -# Note that some variables are parsed by wb.py from version.m4 and are not -# stored in this file. This is done to allow using the old and new Windows build -# systems side-by-side - -# Features to include. DO NOT comment these out, use 1 to enable and 0 to -# disable. -!define ENABLE_PASSWORD_SAVE 1 - -# ENABLE_CLIENT_SERVER enables the point-to-multipoint support. Normally you -# want to have this enabled. -!define ENABLE_CLIENT_SERVER 1 - -# ENABLE_CLIENT_ONLY removes server-side point-to-multipoint features. This -# depends on ENABLE_CLIENT_SERVER being set to 1. -!define ENABLE_CLIENT_ONLY 0 - -!define ENABLE_MANAGEMENT 1 -!define ENABLE_HTTP_PROXY 1 -!define ENABLE_SOCKS 1 -!define ENABLE_FRAGMENT 1 -!define ENABLE_DEBUG 1 - -# Branding -!define PRODUCT_NAME "OpenVPN" -!define PRODUCT_UNIX_NAME "openvpn" -!define PRODUCT_FILE_EXT "ovpn" - -# Include the OpenVPN GUI exe in the installer. Comment out USE_GUI to disable. -!define USE_GUI -!define OPENVPN_GUI_DIR "../openvpn-gui" -!define OPENVPN_GUI "openvpn-gui-1.0.3.exe" - -# Prebuilt libraries. DMALLOC is optional. -!define OPENSSL_DIR "../openssl" -!define LZO_DIR "../lzo" -!define PKCS11_HELPER_DIR "../pkcs11-helper" - -# write output files here -!define DIST "dist" - -# tapinstall.exe (a.k.a. devcon.exe) source code. Not needed if DRVBINSRC is -# defined (or if using pre-built mode). -!define TISRC "../tapinstall" - -# TAP adapter icon -- visible=0x81 or hidden=0x89 -!define PRODUCT_TAP_CHARACTERISTICS 0x81 - -# TAP adapter metadata. Version information in ../version.m4. -!define PRODUCT_TAP_RELDATE "04/19/2010" -!define PRODUCT_TAP_DEVICE_DESCRIPTION "TAP-Win32 Adapter V9" -!define PRODUCT_TAP_PROVIDER "TAP-Win32 Provider V9" - -# Build debugging version of TAP driver -;!define PRODUCT_TAP_DEBUG - -# Build debugging version of openvpn.exe -;!define PRODUCT_OPENVPN_DEBUG - -# DDK path -- currently Windows 7 WDK -!define DDK_PATH "c:/winddk/7600.16385.1" -;!define DDK_PATH "c:/winddk/6001.18002" - -# output path for tap_span.py -!define TAP_DIST "tap_dist" - -# Visual studio path -!define MSVC "C:/Program Files/Microsoft Visual Studio 9.0" - -# Visual studio C run-time library path -!define MSVC_CRT "../Microsoft.VC90.CRT" - -# Code Signing. -# If undefined, don't sign any files. -!define SIGNTOOL "../signtool" -!define PRODUCT_SIGN_CN "openvpn" - -# Directory with prebuilt TAP drivers and tapinstall.exes -!define TAP_PREBUILT "../tap-prebuilt" - -; DEBUGGING -- set to something like "-DBG2" -!define OUTFILE_LABEL "" - -; DEBUGGING -- set to something like "DEBUG2" -!define TITLE_LABEL "" diff --git a/win/show.py b/win/show.py deleted file mode 100644 index ac56e98..0000000 --- a/win/show.py +++ /dev/null @@ -1,9 +0,0 @@ -from wb import get_config -from js import JSON - -def main(): - print JSON().encode(get_config()) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - main() diff --git a/win/sign.py b/win/sign.py deleted file mode 100644 index 67d1cbc..0000000 --- a/win/sign.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -from wb import config, choose_arch, home_fn - -if 'SIGNTOOL' in config: - sys.path.append(home_fn(config['SIGNTOOL'])) - -def main(conf, arch): - from signtool import SignTool - st = SignTool(conf) - for x64 in choose_arch(arch): - st.sign_verify(x64=x64) - -# if we are run directly, and not loaded as a module -if __name__ == "__main__": - if len(sys.argv) >= 2: - main(config, sys.argv[1]) - else: - print "usage: sign <x64|x86|all>" - sys.exit(2) diff --git a/win/tap_span.py b/win/tap_span.py deleted file mode 100644 index 749f6f3..0000000 --- a/win/tap_span.py +++ /dev/null @@ -1,129 +0,0 @@ -import sys, os, shutil -from wb import config, home_fn, mod_fn, preprocess, autogen, dict_def, build_autodefs, rm_rf, mkdir_silent, cp -if 'SIGNTOOL' in config: - sys.path.append(home_fn(config['SIGNTOOL'])) -from signtool import SignTool -from build_ddk import build_tap - -ti_dir = "c:/src/tapinstall" -hi = ("c:/winddk/7600.16385.1", 7600, 7600, ("i386", "amd64")) -low = ("c:/winddk/6001.18002", 6001, 5600, ("win2k",)) -dest_top = home_fn('tap_build') -dist = home_fn(config['TAP_DIST']) - -def copy_tap(src, dest, x64): - dir = os.path.join(src, { False : 'i386', True: 'amd64' }[x64]) - mkdir_silent(dest) - for dirpath, dirnames, filenames in os.walk(dir): - for f in filenames: - root, ext = os.path.splitext(f) - if ext in ('.inf', '.cat', '.sys'): - cp(os.path.join(dir, f), dest) - break - -def copy_tapinstall(src, dest, x64): - base = { False : 'i386', True: 'amd64' }[x64] - mkdir_silent(dest) - for dirpath, dirnames, filenames in os.walk(home_fn(src)): - for f in filenames: - if f == 'devcon.exe': - dir_name = os.path.basename(dirpath) - s = os.path.join(dirpath, f) - if dir_name == base: - cp(s, dest) - -def main(): - rm_rf(dest_top) - os.mkdir(dest_top) - - rm_rf(dist) - os.mkdir(dist) - - for ver in hi, low: - top = os.path.join(dest_top, str(ver[1])) - os.mkdir(top) - tap_dest = os.path.join(top, "tap-win32") - ti_dest = os.path.join(top, "tapinstall") - ti_src = os.path.join(ti_dir, str(ver[2])) - shutil.copytree(home_fn("tap-win32"), tap_dest) - shutil.copytree(ti_src, ti_dest) - - i386 = os.path.join(tap_dest, "i386") - amd64 = os.path.join(tap_dest, "amd64") - - build_amd64 = (len(ver[3]) >= 2) - - build_autodefs(config, mod_fn('autodefs.h.in'), os.path.join(top, 'autodefs.h')) - - st = SignTool(config, tap_dest) - - preprocess(config, - in_fn=os.path.join(tap_dest, 'SOURCES.in'), - out_fn=os.path.join(tap_dest, 'SOURCES'), - quote_begin='@@', - quote_end='@@', - head_comment='# %s\n\n' % autogen) - - preprocess(config, - in_fn=os.path.join(i386, 'OemWin2k.inf.in'), - out_fn=os.path.join(i386, 'OemWin2k.inf'), - quote_begin='@@', - quote_end='@@', - if_prefix='!', - head_comment='; %s\n\n' % autogen) - - preprocess(config, - in_fn=os.path.join(ti_dest, 'sources.in'), - out_fn=os.path.join(ti_dest, 'sources'), - if_prefix='!', - head_comment='# %s\n\n' % autogen) - - build_tap(ddk_path=ver[0], - ddk_major=ver[1], - debug=False, - dir=tap_dest, - x64=False) - - st.sign_verify(x64=False) - - build_tap(ddk_path=ver[0], - ddk_major=ver[1], - debug=False, - dir=ti_dest, - x64=False) - - tap_dist = os.path.join(dist, ver[3][0]) - - copy_tap(tap_dest, tap_dist, x64=False) - copy_tapinstall(ti_dest, tap_dist, x64=False) - - if build_amd64: - os.mkdir(amd64) - preprocess(dict_def(config, [('AMD64', '1')]), - in_fn=os.path.join(i386, 'OemWin2k.inf.in'), - out_fn=os.path.join(amd64, 'OemWin2k.inf'), - quote_begin='@@', - quote_end='@@', - if_prefix='!', - head_comment='; %s\n\n' % autogen) - - build_tap(ddk_path=ver[0], - ddk_major=ver[1], - debug=False, - dir=tap_dest, - x64=True) - - build_tap(ddk_path=ver[0], - ddk_major=ver[1], - debug=False, - dir=ti_dest, - x64=True) - - st.sign_verify(x64=True) - - tap_dist_x64 = os.path.join(dist, ver[3][1]) - - copy_tap(tap_dest, tap_dist_x64, x64=True) - copy_tapinstall(ti_dest, tap_dist_x64, x64=True) - -main() diff --git a/win/wb.py b/win/wb.py deleted file mode 100644 index 39eadec..0000000 --- a/win/wb.py +++ /dev/null @@ -1,322 +0,0 @@ -# Python module containing general build functions -# for OpenVPN on Windows - -import os, re, shutil, stat - -autogen = "Automatically generated by OpenVPN Windows build system" - -def get_config(): - kv = {} - parse_version_m4(kv, home_fn('version.m4')) - parse_settings_in(kv, mod_fn('settings.in')) - - # config fixups - kv['DDKVER'] = os.path.basename(kv['DDK_PATH']) - kv['DDKVER_MAJOR'] = re.match(r'^(\d+)\.', kv['DDKVER']).groups()[0] - - if 'VERSION_SUFFIX' in kv: - kv['PRODUCT_VERSION'] += kv['VERSION_SUFFIX'] - - return kv - -def get_build_params(): - kv = {} - parse_build_params(kv,mod_fn('settings.in')) - - return kv - -def mod_fn(fn, src=__file__, real=True): - p = os.path.join(os.path.dirname(src), os.path.normpath(fn)) - if real: - p = os.path.realpath(p) - return p - -def home_fn(fn, real=True): - return mod_fn(os.path.join('..', fn), real=real) - -def cd_home(): - os.chdir(os.path.join(os.path.dirname(__file__), '..')) - -def cd_service_win32(): - os.chdir(os.path.join(os.path.dirname(__file__), '../service-win32')) - -def system(cmd): - print "RUN:", cmd - os.system(cmd) - -def run_in_vs_shell(cmd): - """Make sure environment variables are setup before running command""" - os.environ['PATH'] += ";%s\\VC" % (os.path.normpath(config['MSVC']),) - system('cmd /c "vcvarsall.bat x86 && %s"' % (cmd,)) - -def parse_version_m4(kv, version_m4): - '''Parse define lines in version.m4''' - r = re.compile(r'^define\((\w+),\[(.*)\]\)$') - f = open(version_m4) - for line in f: - line = line.rstrip() - m = re.match(r, line) - - if m: - g = m.groups() - - # If we encounter PRODUCT_TAP_WIN32_MIN_MAJOR or - # PRODUCT_TAP_WIN32_MIN_MAJOR then we need to generate extra - # variables, PRODUCT_TAP_MAJOR_VER and PRODUCT_TAP_MINOR_VER with - # the same contents. This is necessary because tap-win32/tapdrv.c - # build depends on those. - if g[0] == 'PRODUCT_TAP_WIN32_MIN_MAJOR': - kv['PRODUCT_TAP_MAJOR_VER'] = g[1] - elif g[0] == 'PRODUCT_TAP_WIN32_MIN_MINOR': - kv['PRODUCT_TAP_MINOR_VER'] = g[1] - - # Add the variable to build configuration - kv[g[0]] = g[1] - f.close() - -def parse_settings_in(kv, settings_in): - r = re.compile(r'^!define\s+(\w+)(?:\s+"?(.*?)"?)?$') - f = open(settings_in) - for line in f: - line = line.rstrip() - m = re.match(r, line) - if m: - g = m.groups() - kv[g[0]] = g[1] or '' - f.close() - -def parse_build_params(kv, settings_in): - r = re.compile(r'^!define\s+(ENABLE_\w+)\s+(\w+)') - - f = open(settings_in) - - for line in f: - line = line.rstrip() - - # Check if this is a #define line starts with ENABLE_ - m = re.match(r, line) - - if m: - g = m.groups() - kv[g[0]] = g[1] or '' - f.close() - -def dict_def(dict, newdefs): - ret = dict.copy() - ret.update(newdefs) - return ret - -def build_autodefs(kv, autodefs_in, autodefs_out): - preprocess(kv, - in_fn=autodefs_in, - out_fn=autodefs_out, - quote_begin='@', - quote_end='@', - head_comment='/* %s */\n\n' % autogen) - -def build_config_h(kv): - """Generate static win/config.h to config.h to mimic autotools behavior""" - preprocess(kv, - in_fn=mod_fn('config.h.in'), - out_fn=home_fn('config.h'), - quote_begin='@', - quote_end='@', - head_comment='/* %s */\n\n' % autogen) - -def build_configure_h(kv, configure_h_out, head_comment): - """Generate a configure.h dynamically""" - fout = open(configure_h_out, 'w') - - # These two variables are required to view build parameters during runtime - configure_defines='#define CONFIGURE_DEFINES \"' - configure_call='#define CONFIGURE_CALL \" config_all.py \"' - - # Initialize the list of enabled features - features = '' - - # Write the header - fout.write(head_comment) - - dict = get_build_params() - - for key, value in dict.iteritems(): - # Add enabled features - features = features + "#define " + key + " " + value + "\n" - - # Add each enabled feature to CONFIGURE_DEFINES list - configure_defines = configure_defines + " " + key + "=" + value + "," - - configure_defines = configure_defines + "\"" + "\n" - - fout.write(features) - fout.write(configure_defines) - fout.write(configure_call) - - - fout.close() - -def build_version_m4_vars(version_m4_vars_out, head_comment): - """Generate a temporary file containing variables from version.m4 in -win/settings.in format. This done to allow importing them in win/openvpn.nsi""" - - fout = open(version_m4_vars_out, 'w') - fout.write(head_comment) - - kv = {} - parse_version_m4(kv, home_fn('version.m4')) - - for key, value in kv.iteritems(): - line = "!define " + key + "\t" + "\"" + value + "\"" + "\n" - fout.write(line) - - fout.close() - -def preprocess(kv, in_fn, out_fn, quote_begin=None, quote_end=None, if_prefix=None, head_comment=None): - def repfn(m): - var, = m.groups() - return kv.get(var, '') - - re_macro = re_ifdef = None - - if quote_begin and quote_end: - re_macro = re.compile(r'%s(\w+)%s' % (re.escape(quote_begin), re.escape(quote_end))) - - if if_prefix: - re_ifdef = re.compile(r'^\s*%sifdef\s+(\w+)\b' % (re.escape(if_prefix),)) - re_else = re.compile(r'^\s*%selse\b' % (re.escape(if_prefix),)) - re_endif = re.compile(r'^\s*%sendif\b' % (re.escape(if_prefix),)) - - if_stack = [] - fin = open(in_fn) - fout = open(out_fn, 'w') - if head_comment: - fout.write(head_comment) - for line in fin: - if re_ifdef: - m = re.match(re_ifdef, line) - if m: - var, = m.groups() - if_stack.append(int(var in kv)) - continue - elif re.match(re_else, line): - if_stack[-1] ^= 1 - continue - elif re.match(re_endif, line): - if_stack.pop() - continue - if not if_stack or min(if_stack): - if re_macro: - line = re.sub(re_macro, repfn, line) - fout.write(line) - assert not if_stack - fin.close() - fout.close() - -def print_key_values(kv): - for k, v in sorted(kv.items()): - print "%s%s%s" % (k, ' '*(32-len(k)), repr(v)) - -def get_sources(makefile_am): - """Parse ../Makefile.am to obtain a list of .h and .c files""" - c = set() - h = set() - f = open(makefile_am) - state = False - for line in f: - line = line.rstrip() - if line == 'openvpn_SOURCES = \\': - state = True - elif not line: - state = False - elif state: - for sf in line.split(): - if sf.endswith('.c'): - c.add(sf[:-2]) - elif sf.endswith('.h'): - h.add(sf[:-2]) - elif sf == '\\': - pass - else: - print >>sys.stderr, "Unrecognized filename:", sf - f.close() - return [ sorted(list(s)) for s in (c, h) ] - -def output_mak_list(title, srclist, ext): - ret = "%s =" % (title,) - for x in srclist: - ret += " \\\n\t%s.%s" % (x, ext) - ret += '\n\n' - return ret - -def make_headers_objs(makefile_am): - """Generate HEADER and OBJS entries dynamically from ../Makefile.am""" - c, h = get_sources(makefile_am) - ret = output_mak_list('HEADERS', h, 'h') - ret += output_mak_list('OBJS', c, 'obj') - return ret - -def choose_arch(arch_name): - if arch_name == 'x64': - return (True,) - elif arch_name == 'x86': - return (False,) - elif arch_name == 'all': - return (True, False) - else: - raise ValueError("architecture ('%s') must be x86, x64, or all" % (arch_name,)) - -def rm_rf(dir): - print "REMOVE", dir - shutil.rmtree(dir, ignore_errors=True) - -def mkdir(dir): - print "MKDIR", dir - os.mkdir(dir) - -def cp_a(src, dest, dest_is_dir=True): - if dest_is_dir: - dest = os.path.join(dest, os.path.basename(src)) - print "COPY_DIR %s %s" % (src, dest) - shutil.copytree(src, dest) - -def cp(src, dest, dest_is_dir=True): - if dest_is_dir: - dest = os.path.join(dest, os.path.basename(src)) - print "COPY %s %s" % (src, dest) - shutil.copyfile(src, dest) - -def rename(src, dest): - print "RENAME %s %s" % (src, dest) - shutil.move(src, dest) - -def rm_rf(path): - try: - shutil.rmtree(path, onerror=onerror) - except: - pass - -def onerror(func, path, exc_info): - """ - Error handler for ``shutil.rmtree``. - - If the error is due to an access error (read only file) - it attempts to add write permission and then retries. - - If the error is for another reason it re-raises the error. - - Usage : ``shutil.rmtree(path, onerror=onerror)`` - """ - if not os.access(path, os.W_OK): - # Is the error an access error ? - os.chmod(path, stat.S_IWUSR) - func(path) - else: - raise - -def mkdir_silent(dir): - try: - os.mkdir(dir) - except: - pass - -config = get_config() |