aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2021-11-20 16:48:10 +0100
committerMatthias Andree <matthias.andree@gmx.de>2021-11-21 00:33:34 +0100
commitcc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44 (patch)
tree337fa4b5691643fea540e5026a4c64dc8a9a3509
parent9dadc0e51c91e98d4f23b3385fd2ef20fbdb3358 (diff)
downloadfetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.tar.gz
fetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.tar.bz2
fetchmail-cc5c80eb4d6f98b94f20e5abd4cd50c5bf0e5a44.zip
wolfSSL: support 5.0.0+.
-rw-r--r--COPYING4
-rw-r--r--INSTALL25
-rw-r--r--NEWS4
-rw-r--r--README12
-rw-r--r--README.SSL19
-rw-r--r--configure.ac48
-rw-r--r--fetchmail.c2
-rw-r--r--fetchmail.man7
-rw-r--r--socket.c56
-rw-r--r--tls-aux.c1
-rw-r--r--tls-aux.h38
11 files changed, 174 insertions, 42 deletions
diff --git a/COPYING b/COPYING
index 7499e673..c22cfdff 100644
--- a/COPYING
+++ b/COPYING
@@ -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
diff --git a/INSTALL b/INSTALL
index 9ac5208e..0fb7aca1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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
diff --git a/NEWS b/NEWS
index 3fcefab4..4e741555 100644
--- a/NEWS
+++ b/NEWS
@@ -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):
diff --git a/README b/README
index 3394c755..a0e028f0 100644
--- a/README
+++ b/README
@@ -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
-----------
diff --git a/README.SSL b/README.SSL
index 519e986f..63620b55 100644
--- a/README.SSL
+++ b/README.SSL
@@ -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
diff --git a/socket.c b/socket.c
index 0b762411..5cf0567c 100644
--- a/socket.c
+++ b/socket.c
@@ -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 ) {
diff --git a/tls-aux.c b/tls-aux.c
index a2c2a080..51b78916 100644
--- a/tls-aux.c
+++ b/tls-aux.c
@@ -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.
diff --git a/tls-aux.h b/tls-aux.h
index 696020a3..0d6bac48 100644
--- a/tls-aux.h
+++ b/tls-aux.h
@@ -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 */