diff --git a/Makefile.OpenSSL.inc b/Makefile.OpenSSL.inc index 76f3e85c..1e4e8f0b 100644 --- a/Makefile.OpenSSL.inc +++ b/Makefile.OpenSSL.inc @@ -1,2 +1,3 @@ CRYPTO_CSOURCES = openssl.c CRYPTO_HHEADERS = openssl.h +CRYPTO_LTLIBS = $(LTLIBSSL) diff --git a/Makefile.WinCNG.inc b/Makefile.WinCNG.inc index c18350ee..bbcb82bf 100644 --- a/Makefile.WinCNG.inc +++ b/Makefile.WinCNG.inc @@ -1,2 +1,3 @@ CRYPTO_CSOURCES = wincng.c CRYPTO_HHEADERS = wincng.h +CRYPTO_LTLIBS = $(LTLIBBCRYPT) $(LTLIBCRYPT32) diff --git a/Makefile.libgcrypt.inc b/Makefile.libgcrypt.inc index 5d56292c..0a3aae9a 100644 --- a/Makefile.libgcrypt.inc +++ b/Makefile.libgcrypt.inc @@ -1,2 +1,3 @@ CRYPTO_CSOURCES = libgcrypt.c CRYPTO_HHEADERS = libgcrypt.h +CRYPTO_LTLIBS = $(LTLIBGCRYPT) diff --git a/Makefile.mbedTLS.inc b/Makefile.mbedTLS.inc index 7e978642..c22e51ad 100644 --- a/Makefile.mbedTLS.inc +++ b/Makefile.mbedTLS.inc @@ -1,2 +1,3 @@ CRYPTO_CSOURCES = mbedtls.c CRYPTO_HHEADERS = mbedtls.h +CRYPTO_LTLIBS = $(LTLIBMBEDTLS) diff --git a/acinclude.m4 b/acinclude.m4 index c78260c6..e0bef469 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -382,86 +382,85 @@ AC_DEFUN([CURL_CONFIGURE_REENTRANT], [ # ]) -AC_DEFUN([LIBSSH2_CHECKFOR_MBEDTLS], [ +dnl LIBSSH2_LIB_HAVE_LINKFLAGS +dnl -------------------------- +dnl Wrapper around AC_LIB_HAVE_LINKFLAGS to also check $prefix/lib, if set. +dnl +dnl autoconf only checks $prefix/lib64 if gcc -print-search-dirs output +dnl includes a directory named lib64. So, to find libraries in $prefix/lib +dnl we append -L$prefix/lib to LDFLAGS before checking. +dnl +dnl For conveniece, $4 is expanded if [lib]$1 is found. - old_LDFLAGS=$LDFLAGS - old_CFLAGS=$CFLAGS - if test -n "$use_mbedtls" && test "$use_mbedtls" != "no"; then - LDFLAGS="$LDFLAGS -L$use_mbedtls/lib" - CFLAGS="$CFLAGS -I$use_mbedtls/include" +AC_DEFUN([LIBSSH2_LIB_HAVE_LINKFLAGS], [ + libssh2_lib_have_linkflags_LDFLAGS="$LDFLAGS" + + test "${with_lib$1_prefix+set}" = set && + LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_lib$1_prefix}/lib" + + AC_LIB_HAVE_LINKFLAGS([$1], [$2], [$3]) + + LDFLAGS="$libssh2_lib_have_linkflags_LDFLAGS" + + if test "$ac_cv_lib$1" = "yes"; then : + $4 fi +]) - AC_LIB_HAVE_LINKFLAGS([mbedtls], [], [ - #include +AC_DEFUN([LIBSSH2_CHECK_CRYPTO], [ +if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "$1"; then +m4_case([$1], +[openssl], [ + LIBSSH2_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include ], [ + AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use $1]) + LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto" + + # Not all OpenSSL have AES-CTR functions. + AC_CHECK_FUNCS(EVP_aes_128_ctr) + + found_crypto="$1" + found_crypto_str="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" ]) +], - if test "$ac_cv_libmbedtls" = "yes"; then - AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use mbedtls]) - LIBSREQUIRED= # mbedtls doesn't provide a .pc file - LIBS="$LIBS -lmbedtls -lmbedcrypto" - found_crypto=libmbedtls +[libgcrypt], [ + LIBSSH2_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include ], [ + AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use $1]) + found_crypto="$1" + ]) +], + +[mbedtls], [ + LIBSSH2_LIB_HAVE_LINKFLAGS([mbedtls], [], [#include ], [ + AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1]) + found_crypto="$1" support_clear_memory=yes - else - # restore - LDFLAGS=$old_LDFLAGS - CFLAGS=$old_CFLAGS - fi -]) - -AC_DEFUN([LIBSSH2_CHECKFOR_GCRYPT], [ - - old_LDFLAGS=$LDFLAGS - old_CFLAGS=$CFLAGS - if test -n "$with_libgcrypt_prefix" && test "$use_libgcrypt" != "no"; then - LDFLAGS="$LDFLAGS -L$with_libgcrypt_prefix/lib" - CFLAGS="$CFLAGS -I$with_libgcrypt_prefix/include" - fi - AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [ - #include ]) +], - if test "$ac_cv_libgcrypt" = "yes"; then - AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt]) - LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face. - LIBS="$LIBS -lgcrypt" - found_crypto=libgcrypt - else - # restore - LDFLAGS=$old_LDFLAGS - CFLAGS=$old_CFLAGS - fi -]) - - -AC_DEFUN([LIBSSH2_CHECKFOR_WINCNG], [ - +[wincng], [ # Look for Windows Cryptography API: Next Generation - AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [ - #include - #include - ]) - AC_LIB_HAVE_LINKFLAGS([crypt32], [], [ + AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [#include ]) + AC_CHECK_DECLS([SecureZeroMemory], [], [], [#include ]) + + LIBSSH2_LIB_HAVE_LINKFLAGS([crypt32], [], [ #include #include ]) - AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [ + LIBSSH2_LIB_HAVE_LINKFLAGS([bcrypt], [], [ #include + #include + ], [ + AC_DEFINE(LIBSSH2_WINCNG, 1, [Use $1]) + found_crypto="$1" + found_crypto_str="Windows Cryptography API: Next Generation" + support_clear_memory="$ac_cv_have_decl_SecureZeroMemory" ]) - AC_CHECK_DECLS([SecureZeroMemory], [], [], [ - #include - ]) - - if test "$ac_cv_libbcrypt" = "yes"; then - AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG]) - LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face. - LIBS="$LIBS -lbcrypt" - if test "$ac_cv_libcrypt32" = "yes"; then - LIBS="$LIBS -lcrypt32" - fi - found_crypto="Windows Cryptography API: Next Generation" - if test "$ac_cv_have_decl_SecureZeroMemory" = "yes"; then - support_clear_memory=yes - fi - fi +], +) + test "$found_crypto" = "none" && + crypto_errors="${crypto_errors}No $1 crypto library found! +" +fi ]) diff --git a/configure.ac b/configure.ac index f7fe2472..c6ff7535 100644 --- a/configure.ac +++ b/configure.ac @@ -83,78 +83,81 @@ AC_C_BIGENDIAN dnl check for how to do large files AC_SYS_LARGEFILE -found_crypto=none - # Configure parameters -AC_ARG_WITH(openssl, - AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]), - use_openssl=$withval,use_openssl=auto) -AC_ARG_WITH(libgcrypt, - AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]), - [ use_libgcrypt=$withval - LIBSSH2_CHECKFOR_GCRYPT - ], use_libgcrypt=auto) -AC_ARG_WITH(wincng, - AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]), - [ use_wincng=$withval - LIBSSH2_CHECKFOR_WINCNG - ] ,use_wincng=auto) -AC_ARG_WITH([mbedtls], - AC_HELP_STRING([--with-mbedtls],[Use mbedTLS for crypto]), - [ use_mbedtls=$withval - LIBSSH2_CHECKFOR_MBEDTLS - ], use_mbedtls=auto -) -AC_ARG_WITH(libz, - AC_HELP_STRING([--with-libz],[Use zlib for compression]), - use_libz=$withval,use_libz=auto) + +# Crypto backends + +found_crypto=none +found_crypto_str="" support_clear_memory=no +crypto_errors="" -# Look for OpenSSL -if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then - AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include ]) -fi -if test "$ac_cv_libssl" = "yes"; then - AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use OpenSSL]) - LIBSREQUIRED=libssl,libcrypto +m4_set_add([crypto_backends], [openssl]) +m4_set_add([crypto_backends], [libgcrypt]) +m4_set_add([crypto_backends], [mbedtls]) +m4_set_add([crypto_backends], [wincng]) - # Not all OpenSSL have AES-CTR functions. - save_LIBS="$LIBS" - LIBS="$LIBS $LIBSSL" - AC_CHECK_FUNCS(EVP_aes_128_ctr) - LIBS="$save_LIBS" +AC_ARG_WITH([crypto], + AC_HELP_STRING([--with-crypto=auto|]m4_set_contents([crypto_backends], [|]), + [Select crypto backend (default: auto)]), + use_crypto=$withval, + use_crypto=auto +) - found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" -fi +case "${use_crypto}" in + auto|m4_set_contents([crypto_backends], [|])) + m4_set_map([crypto_backends], [LIBSSH2_CHECK_CRYPTO]) + ;; + yes|"") + crypto_errors="No crypto backend specified!" + ;; + *) + crypto_errors="Unknown crypto backend '${use_crypto}' specified!" + ;; +esac -AM_CONDITIONAL(OPENSSL, test "$ac_cv_libssl" = "yes") -AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes") -AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes") -AM_CONDITIONAL(MBEDTLS, test "$ac_cv_libmbedtls" = "yes") - -# Check if crypto library was found if test "$found_crypto" = "none"; then - AC_MSG_ERROR([No crypto library found! -Try --with-libssl-prefix=PATH - or --with-libgcrypt-prefix=PATH - or --with-libmbedtls-prefix=PATH - or --with-wincng on Windows\ -]) + crypto_errors="${crypto_errors} +Specify --with-crypto=\$backend and/or the neccessary library search prefix. + +Known crypto backends: auto, m4_set_contents([crypto_backends], [, ])" + AS_MESSAGE([ERROR: ${crypto_errors}]) +else + test "$found_crypto_str" = "" && found_crypto_str="$found_crypto" fi -# Look for Libz -if test "$use_libz" != "no"; then +m4_set_foreach([crypto_backends], [backend], + [AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")] +) +m4_undefine([backend]) + + +# libz + +AC_ARG_WITH([libz], + AC_HELP_STRING([--with-libz],[Use libz for compression]), + use_libz=$withval, + use_libz=auto) + +found_libz=no +libz_errors="" + +if test "$use_libz" != no; then AC_LIB_HAVE_LINKFLAGS([z], [], [#include ]) if test "$ac_cv_libz" != yes; then - AC_MSG_NOTICE([Cannot find zlib, disabling compression]) - AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it]) + if test "$use_libz" = auto; then + AC_MSG_NOTICE([Cannot find libz, disabling compression]) + found_libz="disabled; no libz found" + else + libz_errors="No libz found! +Try --with-libz-prefix=PATH if you know that you have it." + AS_MESSAGE([ERROR: $libz_errors]) + fi else AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support]) - if test "${LIBSREQUIRED}" != ""; then - LIBSREQUIRED="${LIBSREQUIRED}," - fi - LIBSREQUIRED="${LIBSREQUIRED}zlib" + LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }zlib" + found_libz="yes" fi fi @@ -351,6 +354,22 @@ AC_C_INLINE CURL_CHECK_NONBLOCKING_SOCKET +missing_required_deps=0 + +if test "${libz_errors}" != ""; then + AS_MESSAGE([ERROR: ${libz_errors}]) + missing_required_deps=1 +fi + +if test "$found_crypto" = "none"; then + AS_MESSAGE([ERROR: ${crypto_errors}]) + missing_required_deps=1 +fi + +if test $missing_required_deps = 1; then + AC_MSG_ERROR([Required dependencies are missing!]) +fi + AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile @@ -367,10 +386,10 @@ AC_MSG_NOTICE([summary of build options: Compiler: ${CC} Compiler flags: ${CFLAGS} Library types: Shared=${enable_shared}, Static=${enable_static} - Crypto library: ${found_crypto} + Crypto library: ${found_crypto_str} Clear memory: $enable_clear_memory Debug build: $enable_debug Build examples: $build_examples Path to sshd: $ac_cv_path_SSHD (only for self-tests) - zlib compression: $ac_cv_libz + zlib compression: ${found_libz} ]) diff --git a/docs/HACKING.CRYPTO b/docs/HACKING.CRYPTO index 6fdcf715..21c99c3a 100644 --- a/docs/HACKING.CRYPTO +++ b/docs/HACKING.CRYPTO @@ -13,6 +13,33 @@ Procedures listed as "void" may indeed have a result type: the void indication indicates the libssh2 core modules never use the function result. +0) Build system. + +Add a new crypto backend to the autotools build system (./configure) as such: + +* Add one new line to configure.ac: + +m4_set_add([crypto_backends], [newname]) + +This automatically creates a new --with-crypto=newname option which users can +specify when invoking configure at compile-time to select the new backend. + +* Add a new m4_case stanza to acinclude.m4 within LIBSSH2_CRYPTO_CHECK, + with checks for library availability. A successful check should set + library linking variables. The LIBSSH2_LIB_HAVE_LINKFLAGS macro creates + such a variable automatically if the checked library can be found. + +* Add a Makefile.newname.inc in the top-level directory which sets + CRYPTO_CSOURCES and CRYPTO_HHEADERS to the new backend source files, + and CRYPTO_LTLIBS to the libtool linking parameters for the library, set + e.g. by a LIBSSH2_LIB_HAVE_LINKFLAGS call in LIBSSH2_CRYPTO_CHECK. + +* Add a new block to src/Makefile.am: + if NEWNAME + include ../Makefile.newname.inc + endif + + 1) Crypto library initialization/termination. void libssh2_crypto_init(void); diff --git a/src/Makefile.am b/src/Makefile.am index 1fa07516..31d58ed5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $ AUTOMAKE_OPTIONS = foreign nostdinc -# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines +# Get the CRYPTO_CSOURCES, CRYPTO_HHEADERS and CRYPTO_LTLIBS defines if OPENSSL include ../Makefile.OpenSSL.inc endif @@ -62,4 +62,4 @@ VERSION=-version-info 1:1:0 libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ -export-symbols-regex '^libssh2_.*' \ - $(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) + $(CRYPTO_LTLIBS) $(LTLIBZ)