diff options
author | Matthias Andree <matthias.andree@gmx.de> | 2021-11-20 16:48:10 +0100 |
---|---|---|
committer | Matthias Andree <matthias.andree@gmx.de> | 2021-11-21 00:33:34 +0100 |
commit | cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44 (patch) | |
tree | 337fa4b5691643fea540e5026a4c64dc8a9a3509 | |
parent | 9dadc0e51c91e98d4f23b3385fd2ef20fbdb3358 (diff) | |
download | fetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.tar.gz fetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.tar.bz2 fetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.zip |
wolfSSL: support 5.0.0+.
-rw-r--r-- | COPYING | 4 | ||||
-rw-r--r-- | INSTALL | 25 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | README | 12 | ||||
-rw-r--r-- | README.SSL | 19 | ||||
-rw-r--r-- | configure.ac | 48 | ||||
-rw-r--r-- | fetchmail.c | 2 | ||||
-rw-r--r-- | fetchmail.man | 7 | ||||
-rw-r--r-- | socket.c | 56 | ||||
-rw-r--r-- | tls-aux.c | 1 | ||||
-rw-r--r-- | tls-aux.h | 38 |
11 files changed, 174 insertions, 42 deletions
@@ -28,6 +28,10 @@ If linking against OpenSSL versions licensed under the Apache License version the GPLv2, so that effectively, distributors need to pull the "or any later version" grant in the GPLv2 and apply the GPLv3 which is considered compatible with the Apache License 2.0 by the FSF and the ASF. + + +Fetchmail can be linked against wolfSSL, which is under GNU General Public License v2, +or optionally, any later version. ~~~~~~~~~~~~~~~~~~~~~~~~~~ The support for SMB authentication is copyright by Andrew Tridgell and @@ -18,7 +18,22 @@ running fetchmail. 1. PREPARATIONS: USEFUL THINGS TO INSTALL FIRST -1.1 OpenSSL +1.1 Choose a TLS/SSL library. + +OpenSSL has been used for a long time and is tested and proven. +See README.SSL for details. + +Forked libraries deriving from OpenSSL and under the SSLeay or OpenSSL license +cannot be used due to licensing issues, and are not supported. +This affects, f.i., LibreSSL. + +Since 6.4.25, there is experimental support for wolfSSL 5.0.0 or newer, +which is under GNU GPL v2 or later license and hence may be easier for +a consistent GPLv2+ licensing of fetchmail. + +Choose between OpenSSL or wolfSSL. + +1.1a OpenSSL If you are installing OpenSSL yourself, it is recommended that you build shared OpenSSL libraries, it works better and updating OpenSSL does not @@ -28,6 +43,14 @@ Try after unpacking OpenSSL: ./config shared && make && make test && make install +1.1b wolfSSL + +If you are installing wolfSSL yourself, be sure to use a hardened build +with all OpenSSL APIs (as of 5.0.0): + + ./configure --enable-opensslall --enable-harden + make && make test && make install + 1.2 gettext (internationalization) Internationalization of fetchmail requires GNU gettext (libintl and @@ -106,6 +106,10 @@ fetchmail-6.4.25 (not yet released): contained a typo and would not kick in properly. * Library and/or rpath setting from configure.ac was fixed. +# CHANGES +* fetchmail can now be used with wolfSSL 5's OpenSSL compatibility layer, + see README.SSL. This is considered experimental. Feedback solicited. + -------------------------------------------------------------------------------- fetchmail-6.4.24 (released 2021-11-20, 30218 LoC): @@ -20,12 +20,12 @@ Fetchmail also fully supports authentication via GSSAPI, Kerberos 4 and 5, RFC1938 one-time passwords, Compuserve's POP3 with RPA, Microsoft's NTLM, Demon Internet's SDPS, or CRAM-MD5 authentication a la RFC2195. -Fetchmail supports end-to-end encryption with OpenSSL, do read README.SSL for -details on fetchmail's configuration and README.SSL-SERVER for server-side -requirements. NOTE! To be compatible with earlier releases, fetchmail 6.4 -default behaviour is more relaxed than dictated by recommendations - while it -does away with SSLv2, only negotiates SSLv3 if forced to, it will by default -still negotiate TLS v1.0. +Fetchmail supports end-to-end encryption with OpenSSL or wolfSSL, do read +README.SSL for details on fetchmail's configuration and README.SSL-SERVER for +server-side requirements. NOTE! To be compatible with earlier releases, +fetchmail 6.4 default behaviour is more relaxed than dictated by +recommendations - while it does away with SSLv2, only negotiates SSLv3 if +forced to, it will by default still negotiate TLS v1.0. Portability ----------- @@ -21,18 +21,25 @@ below and in the manual). fetchmail 6.4.0 will auto-negotiate TLSv1 or newer only. -Fetchmail 6.4.22 supports OpenSSL 3.0.0 and 1.1.1. +Fetchmail 6.4.25 supports OpenSSL 3.0 and 1.1.1 and WolfSSL 5.0. - -- Matthias Andree, 2021-09-09 +The configure options --with-wolfssl takes precedence over --with-ssl. + + -- Matthias Andree, 2021-11-20 Quickstart ---------- -Use an up-to-date release of OpenSSL v1.1.1 or v3.0.0 or newer, so as to get -TLSv1.3 support. Older OpenSSL versions are unsupported upstream, and -fetchmail rejects versions before v1.0.2f and warns about versions before -v1.1.1. +Use an up-to-date release of OpenSSL v1.1.1 or v3.0.0 or wolfSSL 5.0.0 or +newer, so as to get TLSv1.3 support. Older OpenSSL versions are unsupported +upstream, and fetchmail rejects versions before v1.0.2f and warns about +versions before v1.1.1. + +wolfSSL needs to be configured with --enable-opensslall --enable-harden, +else some required OpenSSL APIs are missing, especially for SNI (server name +indication), which is required to fetch mail from Google and some other mail +server providers. In all four examples below, the (--)sslcertck has become redundant since fetchmail v6.4.0, but since fetchmail 6.3 releases will be in circulation diff --git a/configure.ac b/configure.ac index 140489e6..14d8c8ab 100644 --- a/configure.ac +++ b/configure.ac @@ -719,13 +719,56 @@ if test "$KERBEROS_V4" = 1 ; then fi AM_CONDITIONAL(KERBEROS_V4_ENABLE, test "$KERBEROS_V4" = 1) +openssldefault=yes +AC_ARG_WITH(wolfssl, + [AS_HELP_STRING([--with-wolfssl={DIR|no}], + [Use wolfSSL and its OpenSSL compatibility layer])], + [with_wolfssl=$withval], [with_wolfssl=no]) +if test "$with_wolfssl" != "no" ; then + if test -x "$WOLFSSL_CONFIG" ; then + _WOLFSSLCONF="$WOLFSSL_CONFIG" + elif test yes != "$with_wolfssl" -a -x "${with_wolfssl}/bin/wolfssl-config" ; then + _WOLFSSLCONF=${with_wolfssl}/bin/wolfssl-config + else + _WOLFSSLCONF=wolfssl-config + fi + if test yes = "$with_wolfssl" && "$_WOLFSSLCONF" >/dev/null --version ; then + with_wolfssl="$(${_WOLFSSLCONF} --prefix)" + fi + if "$_WOLFSSLCONF" >/dev/null --version ; then + wolfCFLAGS="$(${_WOLFSSLCONF} --cflags)" + wolfLIBS="$(${_WOLFSSLCONF} --libs)" + elif test -d "${with_wolfssl}/include" -a -d "${with_wolfssl}/lib" ; then + wolfCFLAGS="-I${with_wolfssl}/include" + wolfLIBS="-L${with_wolfssl}/lib -lwolfssl -lpthread" + AS_MESSAGE([wolfssl-config not found nor executable, falling back to CFLAGS $wolfCFLAGS, LIBS $wolfLIBS]) + else + AC_MSG_ERROR([WolfSSL not found - please specify proper location to --with-wolfssl]) + fi + set -- $wolfLIBS + while test $# -ge 1 ; do + case $1 in -l*|lib*) : ;; + *) LDFLAGS="$LDFLAGS $1" ;; + esac + shift + done + CPPFLAGS="$CPPFLAGS $wolfCFLAGS -I${with_wolfssl}/include/wolfssl" + AC_CHECK_HEADERS([wolfssl/options.h]) + AC_LIB_LINKFLAGS([wolfssl]) + LIBS="$LIBWOLFSSL $LIBS" + openssldefault=no + AC_DEFINE(SSL_ENABLE, 1) + AS_MESSAGE(Enabling SSL support through wolfSSL.) + with_ssl=yes +else + ### use option --with-ssl to compile in the SSL support AC_ARG_WITH(ssl, [AS_HELP_STRING([--with-ssl[[={yes|no|DIR}]]],[Use OpenSSL from DIR/include/openssl and DIR/lib (default: yes). Yes means try to find it.])], [with_ssl=$withval], - [with_ssl=yes]) + [with_ssl=$openssldefault]) if test "$with_ssl" = "yes" then @@ -803,8 +846,9 @@ else AC_MSG_WARN(Disabling SSL support.) AC_MSG_WARN(Consider re-running configure --with-ssl.) fi +fi -if test "$cross_compiling" != yes -a "$with_ssl" != "no" +if test "$cross_compiling" != yes -a "$with_ssl" != "no" -a "$with_wolfssl" = "no" then AC_LIB_LINKFLAGS([ssl], [crypto]) LIBS="$LIBSSL $LIBS" diff --git a/fetchmail.c b/fetchmail.c index 060e0a9f..70b4d3a9 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -55,9 +55,9 @@ #endif /* ENETUNREACH */ #ifdef SSL_ENABLE +#include "tls-aux.h" /* compatibility and helper functions */ #include <openssl/ssl.h> /* for OPENSSL_NO_SSL2 and ..._SSL3 checks */ #include <openssl/opensslv.h> /* for version queries */ -#include "tls-aux.h" /* compatibility and helper functions */ #endif /* prototypes for internal functions */ diff --git a/fetchmail.man b/fetchmail.man index 6aa19b91..5e5ec015 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -2944,6 +2944,13 @@ The latter locations take precedence over the system default locations. This is useful in case there are broken certificates in the system directories and the user has no administrator privileges to remedy the problem. +.IP \fBFETCHMAIL_WOLFSSL_DEBUG\fP +(since v6.4.25): +If fetchmail is compiled and linked with wolfSSL, if wolfSSL was built with +\-\-enable\-debug, and if this environment variable is set and not empty, +then enable wolfSSL's debug mode. This will emit huge amounts of debug output +to stderr. + .IP \fBHOME\fP (documented since 6.4.1): This variable is normally set to the user's home directory. If it is set @@ -400,7 +400,6 @@ va_dcl { #define OPENSSL_NO_DEPRECATED 23 #endif #include "tls-aux.h" -#include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/pem.h> #include <openssl/x509v3.h> @@ -412,19 +411,24 @@ va_dcl { #error "FAILED - LibreSSL cannot be used legally, for lack of GPL clause 2b exception, see COPYING." #endif -#if OPENSSL_VERSION_NUMBER < 0x1010100fL -#pragma message "WARNING - OpenSSL SHOULD be at least version 1.1.1." -#endif - -#if OPENSSL_VERSION_NUMBER < fm_MIN_OPENSSL_VER -#error Your OpenSSL version must be at least 1.0.2f release. Older OpenSSL versions are unsupported. -#else +#ifdef USING_WOLFSSL +# if LIBWOLFSSL_VERSION_HEX < 0x05000000L +# error "FAILED - wolfSSL 5.0.0 or newer required." +# endif +#else /* USING_WOLFSSL */ +# if OPENSSL_VERSION_NUMBER < 0x1010100fL +# pragma message "WARNING - OpenSSL SHOULD be at least version 1.1.1." +# endif +# if OPENSSL_VERSION_NUMBER < fm_MIN_OPENSSL_VER +# error Your OpenSSL version must be at least 1.0.2f release. Older OpenSSL versions are unsupported. +# else /* OpenSSL too old */ /* #define __fm_ossl_ver(x) #x #define _fm_ossl_ver(x) __fm_ossl_ver(x) #pragma message "Building with OpenSSL headers version " _fm_ossl_ver(OPENSSL_VERSION_NUMBER) ", " OPENSSL_VERSION_TEXT */ -#endif +# endif /* OpenSSL too old */ +#endif /* USING_WOLFSSL */ static void report_SSL_errors(FILE *stream) { @@ -642,10 +646,10 @@ SSL *SSLGetContext( int sock ) return _ssl_context[sock]; } -/* ok_return (preverify_ok) is 1 if this stage of certificate verification +/* ok_return is 1 if this stage of certificate verification passed, or 0 if it failed. This callback lets us display informative errors, and perform additional validation (e.g. CN matches) */ -static int SSL_verify_callback(int ok_return, X509_STORE_CTX *ctx, int strict) +static int SSL_verify_callback(int ok_return, X509_STORE_CTX *ctx, const int strict) { #define SSLverbose (((outlevel) >= O_DEBUG) || ((outlevel) >= O_VERBOSE && (depth) == 0)) char buf[257]; @@ -667,7 +671,7 @@ static int SSL_verify_callback(int ok_return, X509_STORE_CTX *ctx, int strict) if (outlevel >= O_DEBUG) { if (SSLverbose) - report(stdout, GT_("SSL verify callback depth %d: preverify_ok == %d, err = %d, %s\n"), + report(stdout, GT_("SSL verify callback depth %d: verify_ok == %d, err = %d, %s\n"), depth, ok_return, err, X509_verify_cert_error_string(err)); } @@ -1090,6 +1094,14 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck #endif ver = OpenSSL_version_num(); /* version switch through tls-aux.h */ +#ifdef USING_WOLFSSL + { char *tmp; + if (NULL != (tmp = getenv("FETCHMAIL_WOLFSSL_DEBUG"))) { + if (*tmp) wolfSSL_Debugging_ON(); + } + } +#endif + if (ver < OPENSSL_VERSION_NUMBER) { report(stderr, GT_("Loaded OpenSSL library %#lx older than headers %#lx, refusing to work.\n"), (long)ver, (long)(OPENSSL_VERSION_NUMBER)); return -1; @@ -1136,9 +1148,11 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck if(_ctx[sock] == NULL) { unsigned long ec = ERR_peek_last_error(); ERR_print_errors_fp(stderr); +#ifdef SSL_R_NULL_SSL_METHOD_PASSED /* wolfSSL does not define this error */ if (ERR_GET_REASON(ec) == SSL_R_NULL_SSL_METHOD_PASSED) { report(stderr, GT_("Note that some distributions disable older protocol versions in weird non-standard ways. Try a newer protocol version.\n")); } +#endif return(-1); } @@ -1210,7 +1224,22 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck } } - /* set host name for verification, only available since OpenSSL 1.0.2 */ +#ifdef USING_WOLFSSL + { + /* workaround for WolfSSL 5.0.0 compatibility issue, + * which leaves errors in the X509 ctx passed to the + * SSL_verify_callback() in a preverify_ok==1 case, + * where OpenSSL will not return an error. + * https://github.com/wolfSSL/wolfssl/issues/4592 */ + int r = wolfSSL_check_domain_name(_ssl_context[sock], servercname); + if (WOLFSSL_SUCCESS != r) { + report(stderr, GT_("fetchmail: sock %d: wolfSSL_check_domain_name(%#p, \"%s\") returned %d, trying to continue\n"), + sock, _ssl_context[sock], servercname, r); + } + } +#else + /* set host name for verification, only available since OpenSSL 1.0.2 + * */ /* XXX FIXME: do we need to change the function's signature and pass the akalist to * permit the other hostnames through SSL? */ /* https://wiki.openssl.org/index.php/Hostname_validation */ @@ -1240,6 +1269,7 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck /* param is a pointer to internal OpenSSL data, must not be freed, * and just goes out of scope */ } +#endif if( mycert || mykey ) { @@ -4,6 +4,7 @@ #ifdef SSL_ENABLE #include <stdlib.h> #include <string.h> +#include "tls-aux.h" #include <openssl/x509.h> /** return a constant copy of the default SSL certificate path, i. e. @@ -1,25 +1,37 @@ #ifndef TLS_AUX_H #define TLS_AUX_H 1 +#undef LIBWOLFSSL_VERSION_STRING + #include "config.h" #include "fetchmail.h" - #ifdef SSL_ENABLE -#include <openssl/opensslv.h> -# if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x1010000fL -# undef OSSL110_API -# else -# define OSSL110_API 1 -# endif -# if OPENSSL_VERSION_NUMBER < 0x1010000fL -# define OpenSSL_version(t) SSLeay_version((t)) -# define OpenSSL_version_num() SSLeay() -# define OPENSSL_VERSION (SSLEAY_VERSION) -# define OPENSSL_DIR (SSLEAY_DIR) -# define OPENSSL_ENGINES_DIR (-1) +# ifdef HAVE_WOLFSSL_OPTIONS_H +# include <wolfssl/options.h> # endif + +# include <openssl/ssl.h> + +# undef USING_WOLFSSL +# ifdef LIBWOLFSSL_VERSION_HEX +# define USING_WOLFSSL 1 +# define OSSL110_API 1 +# else +# if OPENSSL_VERSION_NUMBER < 0x1010000fL +# undef OSSL110_API +# else +# define OSSL110_API 1 +# endif +# if OPENSSL_VERSION_NUMBER < 0x1010000fL +# define OpenSSL_version(t) SSLeay_version((t)) +# define OpenSSL_version_num() SSLeay() +# define OPENSSL_VERSION (SSLEAY_VERSION) +# define OPENSSL_DIR (SSLEAY_DIR) +# define OPENSSL_ENGINES_DIR (-1) +# endif +# endif /* LIBWOLFSSL_VERSION_STRING */ #endif /* SSL_ENABLE */ #endif /* TLS_AUX_H */ |