Blame SOURCES/fetchmail-6.3.24-ssl-backport.patch

afea54
diff -up fetchmail-6.3.24/configure.ac.orig fetchmail-6.3.24/configure.ac
afea54
--- fetchmail-6.3.24/configure.ac.orig	2012-12-23 16:40:43.000000000 +0100
afea54
+++ fetchmail-6.3.24/configure.ac	2017-03-07 12:35:18.961038361 +0100
afea54
@@ -803,6 +803,7 @@ fi
afea54
 
afea54
 case "$LIBS" in *-lssl*)
afea54
 	AC_CHECK_DECLS([SSLv2_client_method],,,[#include <openssl/ssl.h>])
afea54
+	AC_CHECK_DECLS([SSLv3_client_method],,,[#include <openssl/ssl.h>])
afea54
 	;;
afea54
 esac
afea54
 
afea54
diff -up fetchmail-6.3.24/fetchmail.c.orig fetchmail-6.3.24/fetchmail.c
afea54
--- fetchmail-6.3.24/fetchmail.c.orig	2012-12-14 00:56:41.000000000 +0100
afea54
+++ fetchmail-6.3.24/fetchmail.c	2017-03-07 12:35:18.962038368 +0100
afea54
@@ -263,6 +263,12 @@ int main(int argc, char **argv)
afea54
 #ifdef SSL_ENABLE
afea54
 	"+SSL"
afea54
 #endif
afea54
+#if HAVE_DECL_SSLV2_CLIENT_METHOD + 0 == 0
afea54
+ 	"-SSLv2"
afea54
+#endif
afea54
+#if HAVE_DECL_SSLV3_CLIENT_METHOD + 0 == 0
afea54
+ 	"-SSLv3"
afea54
+#endif
afea54
 #ifdef OPIE_ENABLE
afea54
 	"+OPIE"
afea54
 #endif /* OPIE_ENABLE */
afea54
diff -up fetchmail-6.3.24/fetchmail.h.orig fetchmail-6.3.24/fetchmail.h
afea54
--- fetchmail-6.3.24/fetchmail.h.orig	2012-12-14 00:56:41.000000000 +0100
afea54
+++ fetchmail-6.3.24/fetchmail.h	2017-03-07 12:35:18.962038368 +0100
afea54
@@ -771,9 +771,9 @@ int servport(const char *service);
afea54
 int fm_getaddrinfo(const char *node, const char *serv, const struct addrinfo *hints, struct addrinfo **res);
afea54
 void fm_freeaddrinfo(struct addrinfo *ai);
afea54
 
afea54
-/* prototypes from tls.c */
afea54
-int maybe_tls(struct query *ctl);
afea54
-int must_tls(struct query *ctl);
afea54
+/* prototypes from starttls.c */
afea54
+int maybe_starttls(struct query *ctl);
afea54
+int must_starttls(struct query *ctl);
afea54
 
afea54
 /* prototype from rfc822valid.c */
afea54
 int rfc822_valid_msgid(const unsigned char *);
afea54
diff -up fetchmail-6.3.24/fetchmail.man.orig fetchmail-6.3.24/fetchmail.man
afea54
--- fetchmail-6.3.24/fetchmail.man.orig	2012-12-13 22:50:38.000000000 +0100
afea54
+++ fetchmail-6.3.24/fetchmail.man	2017-03-07 12:35:18.968038409 +0100
afea54
@@ -412,23 +412,22 @@ from. The folder information is written
afea54
 .B \-\-ssl
afea54
 (Keyword: ssl)
afea54
 .br
afea54
-Causes the connection to the mail server to be encrypted
afea54
-via SSL.  Connect to the server using the specified base protocol over a
afea54
-connection secured by SSL. This option defeats opportunistic starttls
afea54
-negotiation. It is highly recommended to use \-\-sslproto 'SSL3'
afea54
-\-\-sslcertck to validate the certificates presented by the server and
afea54
-defeat the obsolete SSLv2 negotiation. More information is available in
afea54
-the \fIREADME.SSL\fP file that ships with fetchmail.
afea54
-.IP
afea54
-Note that fetchmail may still try to negotiate SSL through starttls even
afea54
-if this option is omitted. You can use the \-\-sslproto option to defeat
afea54
-this behavior or tell fetchmail to negotiate a particular SSL protocol.
afea54
+Causes the connection to the mail server to be encrypted via SSL, by
afea54
+negotiating SSL directly after connecting (SSL-wrapped mode).  It is
afea54
+highly recommended to use \-\-sslcertck to validate the certificates
afea54
+presented by the server.  Please see the description of \-\-sslproto
afea54
+below!  More information is available in the \fIREADME.SSL\fP file that
afea54
+ships with fetchmail.
afea54
+.IP
afea54
+Note that even if this option is omitted, fetchmail may still negotiate
afea54
+SSL in-band for POP3 or IMAP, through the STLS or STARTTLS feature.  You
afea54
+can use the \-\-sslproto option to modify that behavior.
afea54
 .IP
afea54
 If no port is specified, the connection is attempted to the well known
afea54
 port of the SSL version of the base protocol.  This is generally a
afea54
 different port than the port used by the base protocol.  For IMAP, this
afea54
 is port 143 for the clear protocol and port 993 for the SSL secured
afea54
-protocol, for POP3, it is port 110 for the clear text and port 995 for
afea54
+protocol; for POP3, it is port 110 for the clear text and port 995 for
afea54
 the encrypted variant.
afea54
 .IP
afea54
 If your system lacks the corresponding entries from /etc/services, see
afea54
@@ -470,39 +469,77 @@ cause some complications in daemon mode.
afea54
 .IP
afea54
 Also see \-\-sslcert above.
afea54
 .TP
afea54
-.B \-\-sslproto <name>
afea54
+.B \-\-sslproto <value>
afea54
 (Keyword: sslproto)
afea54
 .br
afea54
-Forces an SSL/TLS protocol. Possible values are \fB''\fP,
afea54
-\&'\fBSSL2\fP' (not supported on all systems),
afea54
-\&'\fBSSL23\fP', (use of these two values is discouraged
afea54
-and should only be used as a last resort) \&'\fBSSL3\fP', and
afea54
-\&'\fBTLS1\fP'.  The default behaviour if this option is unset is: for
afea54
-connections without \-\-ssl, use \&'\fBTLS1\fP' so that fetchmail will
afea54
-opportunistically try STARTTLS negotiation with TLS1. You can configure
afea54
-this option explicitly if the default handshake (TLS1 if \-\-ssl is not
afea54
-used) does not work for your server.
afea54
-.IP
afea54
-Use this option with '\fBTLS1\fP' value to enforce a STARTTLS
afea54
-connection. In this mode, it is highly recommended to also use
afea54
-\-\-sslcertck (see below).  Note that this will then cause fetchmail
afea54
-v6.3.19 to force STARTTLS negotiation even if it is not advertised by
afea54
-the server.
afea54
-.IP
afea54
-To defeat opportunistic TLSv1 negotiation when the server advertises
afea54
-STARTTLS or STLS, and use a cleartext connection use \fB''\fP.  This
afea54
-option, even if the argument is the empty string, will also suppress the
afea54
-diagnostic 'SERVER: opportunistic upgrade to TLS.' message in verbose
afea54
-mode. The default is to try appropriate protocols depending on context.
afea54
+This option has a dual use, out of historic fetchmail behaviour. It
afea54
+controls both the SSL/TLS protocol version and, if \-\-ssl is not
afea54
+specified, the STARTTLS behaviour (upgrading the protocol to an SSL or
afea54
+TLS connection in-band). Some other options may however make TLS
afea54
+mandatory.
afea54
+.PP
afea54
+Only if this option and \-\-ssl are both missing for a poll, there will
afea54
+be opportunistic TLS for POP3 and IMAP, where fetchmail will attempt to
afea54
+upgrade to TLSv1 or newer.
afea54
+.PP
afea54
+Recognized values for \-\-sslproto are given below. You should normally
afea54
+chose one of the auto-negotiating options, i. e. '\fBauto\fP' or one of
afea54
+the options ending in a plus (\fB+\fP) character. Note that depending
afea54
+on OpenSSL library version and configuration, some options cause
afea54
+run-time errors because the requested SSL or TLS versions are not
afea54
+supported by the particular installed OpenSSL library.
afea54
+.RS
afea54
+.IP "\fB''\fP, the empty string"
afea54
+Disable STARTTLS. If \-\-ssl is given for the same server, log an error
afea54
+and pretend that '\fBauto\fP' had been used instead.
afea54
+.IP '\fBauto\fP'
afea54
+(default). Require TLS. Auto-negotiate TLSv1 or newer, disable SSLv3 downgrade.
afea54
+(previous releases of fetchmail have auto-negotiated all protocols that
afea54
+their OpenSSL library supported, including the broken SSLv3).
afea54
+.IP "\&'\fBSSL23\fP'
afea54
+see '\fBauto\fP'.
afea54
+.IP \&'\fBSSL2\fP'
afea54
+Require SSLv2 exactly. SSLv2 is broken, not supported on all systems, avoid it
afea54
+if possible. This will make fetchmail negotiate SSLv2 only, and is the
afea54
+only way to have fetchmail permit SSLv2.
afea54
+.IP \&'\fBSSL3\fP'
afea54
+Require SSLv3 exactly. SSLv3 is broken, not supported on all systems, avoid it
afea54
+if possible. This will make fetchmail negotiate SSLv3 only, and is the
afea54
+only way besides '\fBSSL3+\fP' to have fetchmail permit SSLv3.
afea54
+.IP \&'\fBSSL3+\fP'
afea54
+same as '\fBauto\fP', but permit SSLv3 as well. This is the only way
afea54
+besides '\fBSSL3\fP' to have fetchmail permit SSLv3.
afea54
+.IP \&'\fBTLS1\fP'
afea54
+Require TLSv1. This does not negotiate TLSv1.1 or newer, and is
afea54
+discouraged. Replace by TLS1+ unless the latter chokes your server.
afea54
+.IP \&'\fBTLS1+\fP'
afea54
+See '\fBauto\fP'.
afea54
+.IP \&'\fBTLS1.1\fP'
afea54
+Require TLS v1.1 exactly.
afea54
+.IP \&'\fBTLS1.1+\fP'
afea54
+Require TLS. Auto-negotiate TLSv1.1 or newer.
afea54
+.IP \&'\fBTLS1.2\fP'
afea54
+Require TLS v1.2 exactly.
afea54
+.IP '\fBTLS1.2+\fP'
afea54
+Require TLS. Auto-negotiate TLSv1.2 or newer.
afea54
+.IP "Unrecognized parameters"
afea54
+are treated the same as '\fBauto\fP'.
afea54
+.RE
afea54
+.IP
afea54
+NOTE: you should hardly ever need to use anything other than '' (to
afea54
+force an unencrypted connection) or 'auto' (to enforce TLS).
afea54
 .TP
afea54
 .B \-\-sslcertck
afea54
 (Keyword: sslcertck)
afea54
 .br
afea54
-Causes fetchmail to strictly check the server certificate against a set of
afea54
-local trusted certificates (see the \fBsslcertfile\fP and \fBsslcertpath\fP
afea54
-options). If the server certificate cannot be obtained or is not signed by one
afea54
-of the trusted ones (directly or indirectly), the SSL connection will fail,
afea54
-regardless of the \fBsslfingerprint\fP option.
afea54
+Causes fetchmail to require that SSL/TLS be used and disconnect if it
afea54
+can not successfully negotiate SSL or TLS, or if it cannot successfully
afea54
+verify and validate the certificate and follow it to a trust anchor (or
afea54
+trusted root certificate). The trust anchors are given as a set of local
afea54
+trusted certificates (see the \fBsslcertfile\fP and \fBsslcertpath\fP
afea54
+options). If the server certificate cannot be obtained or is not signed
afea54
+by one of the trusted ones (directly or indirectly), fetchmail will
afea54
+disconnect, regardless of the \fBsslfingerprint\fP option.
afea54
 .IP
afea54
 Note that CRL (certificate revocation lists) are only supported in
afea54
 OpenSSL 0.9.7 and newer! Your system clock should also be reasonably
afea54
@@ -1202,31 +1239,33 @@ capability response. Specify a user opti
afea54
 username and the part to the right as the NTLM domain.
afea54
 
afea54
 .SS Secure Socket Layers (SSL) and Transport Layer Security (TLS)
afea54
+.PP All retrieval protocols can use SSL or TLS wrapping for the
afea54
+transport. Additionally, POP3 and IMAP retrival can also negotiate
afea54
+SSL/TLS by means of STARTTLS (or STLS).
afea54
 .PP
afea54
 Note that fetchmail currently uses the OpenSSL library, which is
afea54
 severely underdocumented, so failures may occur just because the
afea54
 programmers are not aware of OpenSSL's requirement of the day.
afea54
 For instance, since v6.3.16, fetchmail calls
afea54
 OpenSSL_add_all_algorithms(), which is necessary to support certificates
afea54
-with SHA256 on OpenSSL 0.9.8 -- this information is deeply hidden in the
afea54
-documentation and not at all obvious.  Please do not hesitate to report
afea54
-subtle SSL failures.
afea54
-.PP
afea54
-You can access SSL encrypted services by specifying the \-\-ssl option.
afea54
-You can also do this using the "ssl" user option in the .fetchmailrc
afea54
-file. With SSL encryption enabled, queries are initiated over a
afea54
-connection after negotiating an SSL session, and the connection fails if
afea54
-SSL cannot be negotiated.  Some services, such as POP3 and IMAP, have
afea54
+using SHA256 on OpenSSL 0.9.8 -- this information is deeply hidden in
afea54
+the documentation and not at all obvious.  Please do not hesitate to
afea54
+report subtle SSL failures.
afea54
+.PP
afea54
+You can access SSL encrypted services by specifying the options starting
afea54
+with \-\-ssl, such as \-\-ssl, \-\-sslproto, \-\-sslcertck, and others.
afea54
+You can also do this using the corresponding user options in the .fetchmailrc
afea54
+file.  Some services, such as POP3 and IMAP, have
afea54
 different well known ports defined for the SSL encrypted services.  The
afea54
 encrypted ports will be selected automatically when SSL is enabled and
afea54
-no explicit port is specified. The \-\-sslproto 'SSL3' option should be
afea54
-used to select the SSLv3 protocol (default if unset: v2 or v3).  Also,
afea54
-the \-\-sslcertck command line or sslcertck run control file option
afea54
-should be used to force strict certificate checking - see below.
afea54
+no explicit port is specified.   Also, the \-\-sslcertck command line or
afea54
+sslcertck run control file option should be used to force strict
afea54
+certificate checking - see below.
afea54
 .PP
afea54
 If SSL is not configured, fetchmail will usually opportunistically try to use
afea54
-STARTTLS. STARTTLS can be enforced by using \-\-sslproto "TLS1". TLS
afea54
-connections use the same port as the unencrypted version of the
afea54
+STARTTLS. STARTTLS can be enforced by using \-\-sslproto\~auto and
afea54
+defeated by using \-\-sslproto\~''.
afea54
+TLS connections use the same port as the unencrypted version of the
afea54
 protocol and negotiate TLS via special command. The \-\-sslcertck
afea54
 command line or sslcertck run control file option should be used to
afea54
 force strict certificate checking - see below.
afea54
diff -up fetchmail-6.3.24/imap.c.orig fetchmail-6.3.24/imap.c
afea54
--- fetchmail-6.3.24/imap.c.orig	2012-12-13 22:12:26.000000000 +0100
afea54
+++ fetchmail-6.3.24/imap.c	2017-03-07 12:35:18.962038368 +0100
afea54
@@ -405,6 +405,8 @@ static int imap_getauth(int sock, struct
afea54
 /* apply for connection authorization */
afea54
 {
afea54
     int ok = 0;
afea54
+    char *commonname;
afea54
+
afea54
     (void)greeting;
afea54
 
afea54
     /*
afea54
@@ -429,25 +431,21 @@ static int imap_getauth(int sock, struct
afea54
         return(PS_SUCCESS);
afea54
     }
afea54
 
afea54
-#ifdef SSL_ENABLE
afea54
-    if (maybe_tls(ctl)) {
afea54
-	char *commonname;
afea54
-
afea54
-	commonname = ctl->server.pollname;
afea54
-	if (ctl->server.via)
afea54
-	    commonname = ctl->server.via;
afea54
-	if (ctl->sslcommonname)
afea54
-	    commonname = ctl->sslcommonname;
afea54
+    commonname = ctl->server.pollname;
afea54
+    if (ctl->server.via)
afea54
+       commonname = ctl->server.via;
afea54
+    if (ctl->sslcommonname)
afea54
+       commonname = ctl->sslcommonname;
afea54
 
afea54
-	if (strstr(capabilities, "STARTTLS")
afea54
-		|| must_tls(ctl)) /* if TLS is mandatory, ignore capabilities */
afea54
+#ifdef SSL_ENABLE
afea54
+    if (maybe_starttls(ctl)) {
afea54
+       if ((strstr(capabilities, "STARTTLS") && maybe_starttls(ctl))
afea54
+               || must_starttls(ctl)) /* if TLS is mandatory, ignore capabilities */
afea54
 	{
afea54
-	    /* Use "tls1" rather than ctl->sslproto because tls1 is the only
afea54
-	     * protocol that will work with STARTTLS.  Don't need to worry
afea54
-	     * whether TLS is mandatory or opportunistic unless SSLOpen() fails
afea54
-	     * (see below). */
afea54
+	    /* Don't need to worry whether TLS is mandatory or
afea54
+	     * opportunistic unless SSLOpen() fails (see below). */
afea54
 	    if (gen_transact(sock, "STARTTLS") == PS_SUCCESS
afea54
-		    && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, "tls1", ctl->sslcertck,
afea54
+		    && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, ctl->sslproto, ctl->sslcertck,
afea54
 			ctl->sslcertfile, ctl->sslcertpath, ctl->sslfingerprint, commonname,
afea54
 			ctl->server.pollname, &ctl->remotename)) != -1)
afea54
 	    {
afea54
@@ -470,7 +468,7 @@ static int imap_getauth(int sock, struct
afea54
 		{
afea54
 		    report(stdout, GT_("%s: upgrade to TLS succeeded.\n"), commonname);
afea54
 		}
afea54
-	    } else if (must_tls(ctl)) {
afea54
+	    } else if (must_starttls(ctl)) {
afea54
 		/* Config required TLS but we couldn't guarantee it, so we must
afea54
 		 * stop. */
afea54
 		set_timeout(0);
afea54
@@ -492,6 +490,10 @@ static int imap_getauth(int sock, struct
afea54
 		/* Usable.  Proceed with authenticating insecurely. */
afea54
 	    }
afea54
 	}
afea54
+    } else {
afea54
+	if (strstr(capabilities, "STARTTLS") && outlevel >= O_VERBOSE) {
afea54
+	    report(stdout, GT_("%s: WARNING: server offered STARTTLS but sslproto '' given.\n"), commonname);
afea54
+	}
afea54
     }
afea54
 #endif /* SSL_ENABLE */
afea54
 
afea54
diff -up fetchmail-6.3.24/Makefile.am.orig fetchmail-6.3.24/Makefile.am
afea54
--- fetchmail-6.3.24/Makefile.am.orig	2012-12-23 16:40:57.000000000 +0100
afea54
+++ fetchmail-6.3.24/Makefile.am	2017-03-07 12:35:18.962038368 +0100
afea54
@@ -31,7 +31,7 @@ libfm_a_SOURCES=	xmalloc.c base64.c rfc8
afea54
 			servport.c ntlm.h smbbyteorder.h smbdes.h smbmd4.h \
afea54
 			smbencrypt.h smbdes.c smbencrypt.c smbmd4.c smbutil.c \
afea54
 			libesmtp/gethostbyname.h libesmtp/gethostbyname.c \
afea54
-			smbtypes.h fm_getaddrinfo.c tls.c rfc822valid.c \
afea54
+			smbtypes.h fm_getaddrinfo.c starttls.c rfc822valid.c \
afea54
 			xmalloc.h sdump.h sdump.c x509_name_match.c \
afea54
 			fm_strl.h md5c.c
afea54
 if NTLM_ENABLE
afea54
diff -up fetchmail-6.3.24/Makefile.in.orig fetchmail-6.3.24/Makefile.in
afea54
--- fetchmail-6.3.24/Makefile.in.orig	2012-12-23 17:29:56.000000000 +0100
afea54
+++ fetchmail-6.3.24/Makefile.in	2017-03-07 12:35:18.963038375 +0100
afea54
@@ -97,14 +97,14 @@ am__libfm_a_SOURCES_DIST = xmalloc.c bas
afea54
 	rfc2047e.c servport.c ntlm.h smbbyteorder.h smbdes.h smbmd4.h \
afea54
 	smbencrypt.h smbdes.c smbencrypt.c smbmd4.c smbutil.c \
afea54
 	libesmtp/gethostbyname.h libesmtp/gethostbyname.c smbtypes.h \
afea54
-	fm_getaddrinfo.c tls.c rfc822valid.c xmalloc.h sdump.h sdump.c \
afea54
+	fm_getaddrinfo.c starttls.c rfc822valid.c xmalloc.h sdump.h sdump.c \
afea54
 	x509_name_match.c fm_strl.h md5c.c ntlmsubr.c
afea54
 @NTLM_ENABLE_TRUE@am__objects_1 = ntlmsubr.$(OBJEXT)
afea54
 am_libfm_a_OBJECTS = xmalloc.$(OBJEXT) base64.$(OBJEXT) \
afea54
 	rfc822.$(OBJEXT) report.$(OBJEXT) rfc2047e.$(OBJEXT) \
afea54
 	servport.$(OBJEXT) smbdes.$(OBJEXT) smbencrypt.$(OBJEXT) \
afea54
 	smbmd4.$(OBJEXT) smbutil.$(OBJEXT) gethostbyname.$(OBJEXT) \
afea54
-	fm_getaddrinfo.$(OBJEXT) tls.$(OBJEXT) rfc822valid.$(OBJEXT) \
afea54
+	fm_getaddrinfo.$(OBJEXT) starttls.$(OBJEXT) rfc822valid.$(OBJEXT) \
afea54
 	sdump.$(OBJEXT) x509_name_match.$(OBJEXT) md5c.$(OBJEXT) \
afea54
 	$(am__objects_1)
afea54
 libfm_a_OBJECTS = $(am_libfm_a_OBJECTS)
afea54
@@ -483,7 +483,7 @@ libfm_a_SOURCES = xmalloc.c base64.c rfc
afea54
 	servport.c ntlm.h smbbyteorder.h smbdes.h smbmd4.h \
afea54
 	smbencrypt.h smbdes.c smbencrypt.c smbmd4.c smbutil.c \
afea54
 	libesmtp/gethostbyname.h libesmtp/gethostbyname.c smbtypes.h \
afea54
-	fm_getaddrinfo.c tls.c rfc822valid.c xmalloc.h sdump.h sdump.c \
afea54
+	fm_getaddrinfo.c starttls.c rfc822valid.c xmalloc.h sdump.h sdump.c \
afea54
 	x509_name_match.c fm_strl.h md5c.c $(am__append_1)
afea54
 libfm_a_LIBADD = $(EXTRAOBJ)
afea54
 libfm_a_DEPENDENCIES = $(EXTRAOBJ)
afea54
diff -up fetchmail-6.3.24/NEWS.orig fetchmail-6.3.24/NEWS
afea54
--- fetchmail-6.3.24/NEWS.orig	2017-03-07 12:35:18.958038341 +0100
afea54
+++ fetchmail-6.3.24/NEWS	2017-03-07 12:35:18.968038409 +0100
afea54
@@ -56,6 +56,29 @@ removed from a 6.4.0 or newer release.)
afea54
 
afea54
 --------------------------------------------------------------------------------
afea54
 
afea54
+## SECURITY FIXES THAT AFFECT BEHAVIOUR AND MAY WANT RECONFIGURATION
afea54
+* Fetchmail no longer attempts to negotiate SSLv3 by default,
afea54
+  even with --sslproto ssl23. Fetchmail can now use SSLv3, or TLSv1.1 or a newer
afea54
+  TLS version, with STLS/STARTTLS (it would previously force TLSv1.0).  If the
afea54
+  OpenSSL version used at build and run-time supports these versions, -sslproto
afea54
+  ssl3 can be used to enable this specific version.  Doing so is discouraged
afea54
+  because these protocols are broken.
afea54
+
afea54
+  Along the lines suggested - as patch - by Kurt Roeckx, Debian Bug #768843.
afea54
+
afea54
+  While this change is supposed to be compatible with common configurations,
afea54
+  users are advised to change all explicit --sslproto ssl2, --sslproto
afea54
+  ssl3, --sslproto tls1 to --sslproto auto, so that they can enable TLSv1.1 and
afea54
+  TLSv1.2 on systems with OpenSSL 1.0.1 or newer.
afea54
+
afea54
+  The --sslproto option now understands the values auto, tls1+, tls1.1+,
afea54
+  tls1.2+ (case insensitively).
afea54
+
afea54
+## CHANGES
afea54
+* Fetchmail now supports --sslproto auto and --sslproto tls1+ (same as ssl23).
afea54
+* --sslproto tls1.1+ and tls1.2+ are now supported for auto-negotiation with a
afea54
+  minimum specified TLS protocol version.
afea54
+
afea54
 fetchmail-6.3.24 (released 2012-12-23, 26108 LoC):
afea54
 
afea54
 # NOTE THAT THE RELEASE OF FUTURE FETCHMAIL 6.3.X VERSIONS IS UNCLEAR.
afea54
diff -up fetchmail-6.3.24/pop3.c.orig fetchmail-6.3.24/pop3.c
afea54
--- fetchmail-6.3.24/pop3.c.orig	2012-12-13 22:50:38.000000000 +0100
afea54
+++ fetchmail-6.3.24/pop3.c	2017-03-07 12:35:18.963038375 +0100
afea54
@@ -281,6 +281,7 @@ static int pop3_getauth(int sock, struct
afea54
 #endif /* OPIE_ENABLE */
afea54
 #ifdef SSL_ENABLE
afea54
     flag connection_may_have_tls_errors = FALSE;
afea54
+    char *commonname;
afea54
 #endif /* SSL_ENABLE */
afea54
 
afea54
     done_capa = FALSE;
afea54
@@ -393,7 +394,7 @@ static int pop3_getauth(int sock, struct
afea54
 		(ctl->server.authenticate == A_KERBEROS_V5) ||
afea54
 		(ctl->server.authenticate == A_OTP) ||
afea54
 		(ctl->server.authenticate == A_CRAM_MD5) ||
afea54
-		maybe_tls(ctl))
afea54
+		maybe_starttls(ctl))
afea54
 	{
afea54
 	    if ((ok = capa_probe(sock)) != PS_SUCCESS)
afea54
 		/* we are in STAGE_GETAUTH => failure is PS_AUTHFAIL! */
afea54
@@ -406,12 +407,12 @@ static int pop3_getauth(int sock, struct
afea54
 		    (ok == PS_SOCKET && !ctl->wehaveauthed))
afea54
 		{
afea54
 #ifdef SSL_ENABLE
afea54
-		    if (must_tls(ctl)) {
afea54
+		    if (must_starttls(ctl)) {
afea54
 			/* fail with mandatory STLS without repoll */
afea54
 			report(stderr, GT_("TLS is mandatory for this session, but server refused CAPA command.\n"));
afea54
 			report(stderr, GT_("The CAPA command is however necessary for TLS.\n"));
afea54
 			return ok;
afea54
-		    } else if (maybe_tls(ctl)) {
afea54
+		    } else if (maybe_starttls(ctl)) {
afea54
 			/* defeat opportunistic STLS */
afea54
 			xfree(ctl->sslproto);
afea54
 			ctl->sslproto = xstrdup("");
afea54
@@ -431,24 +432,19 @@ static int pop3_getauth(int sock, struct
afea54
 	}
afea54
 
afea54
 #ifdef SSL_ENABLE
afea54
-	if (maybe_tls(ctl)) {
afea54
-	    char *commonname;
afea54
+	commonname = ctl->server.pollname;
afea54
+	if (ctl->server.via)
afea54
+	    commonname = ctl->server.via;
afea54
+	if (ctl->sslcommonname)
afea54
+	   commonname = ctl->sslcommonname;
afea54
 
afea54
-	    commonname = ctl->server.pollname;
afea54
-	    if (ctl->server.via)
afea54
-		commonname = ctl->server.via;
afea54
-	    if (ctl->sslcommonname)
afea54
-		commonname = ctl->sslcommonname;
afea54
-
afea54
-	   if (has_stls
afea54
-		   || must_tls(ctl)) /* if TLS is mandatory, ignore capabilities */
afea54
+	if (maybe_starttls(ctl)) {
afea54
+	   if (has_stls || must_starttls(ctl)) /* if TLS is mandatory, ignore capabilities */
afea54
 	   {
afea54
-	       /* Use "tls1" rather than ctl->sslproto because tls1 is the only
afea54
-		* protocol that will work with STARTTLS.  Don't need to worry
afea54
-		* whether TLS is mandatory or opportunistic unless SSLOpen() fails
afea54
-		* (see below). */
afea54
+	       /* Don't need to worry whether TLS is mandatory or
afea54
+	        * opportunistic unless SSLOpen() fails (see below). */
afea54
 	       if (gen_transact(sock, "STLS") == PS_SUCCESS
afea54
-		       && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, "tls1", ctl->sslcertck,
afea54
+		       && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, ctl->sslproto, ctl->sslcertck,
afea54
 			   ctl->sslcertfile, ctl->sslcertpath, ctl->sslfingerprint, commonname,
afea54
 			   ctl->server.pollname, &ctl->remotename)) != -1)
afea54
 	       {
afea54
@@ -475,7 +471,7 @@ static int pop3_getauth(int sock, struct
afea54
 		   {
afea54
 		       report(stdout, GT_("%s: upgrade to TLS succeeded.\n"), commonname);
afea54
 		   }
afea54
-	       } else if (must_tls(ctl)) {
afea54
+	       } else if (must_starttls(ctl)) {
afea54
 		   /* Config required TLS but we couldn't guarantee it, so we must
afea54
 		    * stop. */
afea54
 		   set_timeout(0);
afea54
@@ -495,7 +491,11 @@ static int pop3_getauth(int sock, struct
afea54
 		   }
afea54
 	       }
afea54
 	   }
afea54
-	} /* maybe_tls() */
afea54
+	} else { /* maybe_starttls() */
afea54
+	    if (has_stls && outlevel >= O_VERBOSE) {
afea54
+	        report(stdout, GT_("%s: WARNING: server offered STLS, but sslproto '' given.\n"), commonname);
afea54
+	    }
afea54
+	} /* maybe_starttls() */
afea54
 #endif /* SSL_ENABLE */
afea54
 
afea54
 	/*
afea54
diff -up fetchmail-6.3.24/README.SSL.orig fetchmail-6.3.24/README.SSL
afea54
--- fetchmail-6.3.24/README.SSL.orig	2011-08-16 13:24:53.000000000 +0200
afea54
+++ fetchmail-6.3.24/README.SSL	2017-03-07 12:35:18.963038375 +0100
afea54
@@ -11,36 +11,48 @@ specific to fetchmail.
afea54
 In case of troubles, mail the README.SSL-SERVER file to your ISP and 
afea54
 have them check their server configuration against it.
afea54
 
afea54
-Unfortunately, fetchmail confuses SSL/TLS protocol levels with whether 
afea54
-a service needs to use in-band negotiation (STLS/STARTTLS for POP3/IMAP4) or is 
afea54
-totally SSL-wrapped on a separate port.  For compatibility reasons, this cannot 
afea54
-be fixed in a bugfix release.
afea54
+Unfortunately, fetchmail confuses SSL/TLS protocol levels with whether a
afea54
+service needs to use in-band negotiation (STLS/STARTTLS for POP3/IMAP4)
afea54
+or is totally SSL-wrapped on a separate port.  For compatibility
afea54
+reasons, this cannot be fixed in a bugfix or minor release.
afea54
 
afea54
 	-- Matthias Andree, 2009-05-09
afea54
 
afea54
+Also, fetchmail 6.4.0 and newer releases (this is also true for this release,
afea54
+as the changes were backported from upstream - noted by Red Hat) changed
afea54
+some of the semantics as the result of a bug-fix, and will auto-negotiate
afea54
+TLSv1 or newer only. If your server does not support this, you may have
afea54
+to specify --sslproto ssl3.  This is in order to prefer the newer TLS
afea54
+protocols, because SSLv2 and v3 are broken.
afea54
+
afea54
+       -- Matthias Andree, 2015-01-16
afea54
+
afea54
 
afea54
 Quickstart
afea54
 ----------
afea54
 
afea54
+Use an up-to-date release of OpenSSL 1.0.1 or newer, so as to get
afea54
+TLSv1.2 support.
afea54
+
afea54
 For use of SSL or TLS with in-band negotiation on the regular service's port, 
afea54
 i. e. with STLS or STARTTLS, use these command line options
afea54
 
afea54
-    --sslproto tls1 --sslcertck
afea54
+    --sslproto auto --sslcertck
afea54
 
afea54
 or these options in the rcfile (after the respective "user"... options)
afea54
 
afea54
-      sslproto tls1   sslcertck
afea54
+      sslproto auto   sslcertck
afea54
 
afea54
 
afea54
 For use of SSL or TLS on a separate port, if the whole TCP connection is 
afea54
-SSL-encrypted from the very beginning, use these command line options (in the 
afea54
-rcfile, omit all leading "--"):
afea54
+SSL-encrypted from the very beginning (SSL- or TLS-wrapped), use these
afea54
+command line options (in the rcfile, omit all leading "--"):
afea54
 
afea54
-    --ssl --sslproto ssl3 --sslcertck
afea54
+    --ssl --sslproto auto --sslcertck
afea54
 
afea54
 or these options in the rcfile (after the respective "user"... options)
afea54
 
afea54
-      ssl   sslproto ssl3   sslcertck
afea54
+      ssl   sslproto auto   sslcertck
afea54
 
afea54
 
afea54
 Background and use (long version :-))
afea54
diff -up fetchmail-6.3.24/socket.c.orig fetchmail-6.3.24/socket.c
afea54
--- fetchmail-6.3.24/socket.c.orig	2012-12-13 23:32:29.000000000 +0100
afea54
+++ fetchmail-6.3.24/socket.c	2017-03-07 12:41:24.558502332 +0100
afea54
@@ -844,6 +844,9 @@ int SSLOpen(int sock, char *mycert, char
afea54
 {
afea54
         struct stat randstat;
afea54
         int i;
afea54
+	/* disable SSLv2 and SSLv3 by default. SSLv2 can be enabled with '--sslproto ssl2'.
afea54
+	   SSLv3 can be enabled with '--sslproto ssl3' or '--sslproto ssl3+' */
afea54
+        int avoid_ssl_versions = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
afea54
 	long sslopts = SSL_OP_ALL;
afea54
 
afea54
 	SSL_load_error_strings();
afea54
@@ -873,28 +876,68 @@ int SSLOpen(int sock, char *mycert, char
afea54
 
afea54
 	/* Make sure a connection referring to an older context is not left */
afea54
 	_ssl_context[sock] = NULL;
afea54
-	if(myproto) {
afea54
-		if(!strcasecmp("ssl2",myproto)) {
afea54
+        if(myproto) {
afea54
+                if(!strcasecmp("ssl2",myproto)) {
afea54
 #if HAVE_DECL_SSLV2_CLIENT_METHOD + 0 > 0
afea54
-			_ctx[sock] = SSL_CTX_new(SSLv2_client_method());
afea54
+                        _ctx[sock] = SSL_CTX_new(SSLv2_client_method());
afea54
 #else
afea54
-			report(stderr, GT_("Your operating system does not support SSLv2.\n"));
afea54
-			return -1;
afea54
+                        report(stderr, GT_("Your OpenSSL version does not support SSLv2.\n"));
afea54
+                        return -1;
afea54
 #endif
afea54
-		} else if(!strcasecmp("ssl3",myproto)) {
afea54
-			_ctx[sock] = SSL_CTX_new(SSLv3_client_method());
afea54
-		} else if(!strcasecmp("tls1",myproto)) {
afea54
-			_ctx[sock] = SSL_CTX_new(TLSv1_client_method());
afea54
-		} else if (!strcasecmp("ssl23",myproto)) {
afea54
-			myproto = NULL;
afea54
-		} else {
afea54
-			fprintf(stderr,GT_("Invalid SSL protocol '%s' specified, using default (SSLv23).\n"), myproto);
afea54
-			myproto = NULL;
afea54
-		}
afea54
-	}
afea54
-	if(!myproto) {
afea54
-		_ctx[sock] = SSL_CTX_new(SSLv23_client_method());
afea54
-	}
afea54
+                        avoid_ssl_versions &= ~SSL_OP_NO_SSLv2;
afea54
+                } else if(!strcasecmp("ssl3",myproto)) {
afea54
+#if HAVE_DECL_SSLV3_CLIENT_METHOD + 0 > 0
afea54
+                        _ctx[sock] = SSL_CTX_new(SSLv3_client_method());
afea54
+#else
afea54
+                        report(stderr, GT_("Your OpenSSL version does not support SSLv3.\n"));
afea54
+                        return -1;
afea54
+#endif
afea54
+                        avoid_ssl_versions &= ~SSL_OP_NO_SSLv3;
afea54
+                } else if(!strcasecmp("ssl3+",myproto)) {
afea54
+                        avoid_ssl_versions &= ~SSL_OP_NO_SSLv3;
afea54
+                        myproto = NULL;
afea54
+                } else if(!strcasecmp("tls1",myproto)) {
afea54
+                        _ctx[sock] = SSL_CTX_new(TLSv1_client_method());
afea54
+                } else if(!strcasecmp("tls1+",myproto)) {
afea54
+                        myproto = NULL;
afea54
+#if defined(TLS1_1_VERSION) && TLS_MAX_VERSION >= TLS1_1_VERSION
afea54
+                } else if(!strcasecmp("tls1.1",myproto)) {
afea54
+                        _ctx[sock] = SSL_CTX_new(TLSv1_1_client_method());
afea54
+                } else if(!strcasecmp("tls1.1+",myproto)) {
afea54
+                        myproto = NULL;
afea54
+                        avoid_ssl_versions |= SSL_OP_NO_TLSv1;
afea54
+#else
afea54
+                } else if(!strcasecmp("tls1.1",myproto) || !strcasecmp("tls1.1+", myproto)) {
afea54
+                        report(stderr, GT_("Your OpenSSL version does not support TLS v1.1.\n"));
afea54
+                        return -1;
afea54
+#endif
afea54
+#if defined(TLS1_2_VERSION) && TLS_MAX_VERSION >= TLS1_2_VERSION
afea54
+                } else if(!strcasecmp("tls1.2",myproto)) {
afea54
+                        _ctx[sock] = SSL_CTX_new(TLSv1_2_client_method());
afea54
+                } else if(!strcasecmp("tls1.2+",myproto)) {
afea54
+                        myproto = NULL;
afea54
+                        avoid_ssl_versions |= SSL_OP_NO_TLSv1;
afea54
+                        avoid_ssl_versions |= SSL_OP_NO_TLSv1_1;
afea54
+#else
afea54
+                } else if(!strcasecmp("tls1.2",myproto) || !strcasecmp("tls1.2+", myproto)) {
afea54
+                        report(stderr, GT_("Your OpenSSL version does not support TLS v1.2.\n"));
afea54
+                        return -1;
afea54
+#endif
afea54
+                } else if (!strcasecmp("ssl23",myproto) || 0 == strcasecmp("auto",myproto)) {
afea54
+                        myproto = NULL;
afea54
+                } else {
afea54
+                        report(stderr,GT_("Invalid SSL protocol '%s' specified, using default autoselect (SSL23).\n"), myproto);
afea54
+                        myproto = NULL;
afea54
+                }
afea54
+        }
afea54
+        // do not combine into an else { } as myproto may be nulled
afea54
+        // above!
afea54
+        if(!myproto) {
afea54
+                // SSLv23 is a misnomer and will in fact use the best
afea54
+                // available protocol, subject to SSL_OP_NO*
afea54
+                // constraints.
afea54
+                _ctx[sock] = SSL_CTX_new(SSLv23_client_method());
afea54
+        }
afea54
 	if(_ctx[sock] == NULL) {
afea54
 		ERR_print_errors_fp(stderr);
afea54
 		return(-1);
afea54
@@ -906,7 +949,7 @@ int SSLOpen(int sock, char *mycert, char
afea54
 		sslopts &= ~ SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
afea54
 	}
afea54
 
afea54
-	SSL_CTX_set_options(_ctx[sock], sslopts);
afea54
+	SSL_CTX_set_options(_ctx[sock], sslopts | avoid_ssl_versions);
afea54
 
afea54
 	if (certck) {
afea54
 		SSL_CTX_set_verify(_ctx[sock], SSL_VERIFY_PEER, SSL_ck_verify_callback);
afea54
@@ -985,6 +1028,24 @@ int SSLOpen(int sock, char *mycert, char
afea54
 		return(-1);
afea54
 	}
afea54
 
afea54
+	if (outlevel >= O_VERBOSE) {
afea54
+	    SSL_CIPHER const *sc;
afea54
+	    int bitsmax, bitsused;
afea54
+
afea54
+	    const char *ver;
afea54
+
afea54
+	    ver = SSL_get_version(_ssl_context[sock]);
afea54
+
afea54
+	    sc = SSL_get_current_cipher(_ssl_context[sock]);
afea54
+	    if (!sc) {
afea54
+		report (stderr, GT_("Cannot obtain current SSL/TLS cipher - no session established?\n"));
afea54
+	    } else {
afea54
+		bitsused = SSL_CIPHER_get_bits(sc, &bitsmax);
afea54
+		report(stdout, GT_("SSL/TLS: using protocol %s, cipher %s, %d/%d secret/processed bits\n"),
afea54
+		    ver, SSL_CIPHER_get_name(sc), bitsused, bitsmax);
afea54
+		}
afea54
+	}
afea54
+
afea54
 	/* Paranoia: was the callback not called as we expected? */
afea54
 	if (!_depth0ck) {
afea54
 		report(stderr, GT_("Certificate/fingerprint verification was somehow skipped!\n"));
afea54
diff -up fetchmail-6.3.24/starttls.c.orig fetchmail-6.3.24/starttls.c
afea54
--- fetchmail-6.3.24/starttls.c.orig	2017-03-07 12:35:18.964038382 +0100
afea54
+++ fetchmail-6.3.24/starttls.c	2017-03-07 12:35:18.964038382 +0100
afea54
@@ -0,0 +1,37 @@
afea54
+/** \file tls.c - collect common TLS functionality
afea54
+ * \author Matthias Andree
afea54
+ * \date 2006
afea54
+ */
afea54
+
afea54
+#include "fetchmail.h"
afea54
+
afea54
+#include <string.h>
afea54
+
afea54
+#ifdef HAVE_STRINGS_H
afea54
+#include <strings.h>
afea54
+#endif
afea54
+
afea54
+/** return true if user allowed opportunistic STARTTLS/STLS */
afea54
+int maybe_starttls(struct query *ctl) {
afea54
+#ifdef SSL_ENABLE
afea54
+         /* opportunistic  or forced TLS */
afea54
+    return (!ctl->sslproto || strlen(ctl->sslproto))
afea54
+	&& !ctl->use_ssl;
afea54
+#else
afea54
+    (void)ctl;
afea54
+    return 0;
afea54
+#endif
afea54
+}
afea54
+
afea54
+/** return true if user requires STARTTLS/STLS, note though that this
afea54
+ * code must always use a logical AND with maybe_tls(). */
afea54
+int must_starttls(struct query *ctl) {
afea54
+#ifdef SSL_ENABLE
afea54
+    return maybe_starttls(ctl)
afea54
+	&& (ctl->sslfingerprint || ctl->sslcertck
afea54
+		|| (ctl->sslproto && !strcasecmp(ctl->sslproto, "tls1")));
afea54
+#else
afea54
+    (void)ctl;
afea54
+    return 0;
afea54
+#endif
afea54
+}
afea54
diff -up fetchmail-6.3.24/tls.c.orig fetchmail-6.3.24/tls.c
afea54
--- fetchmail-6.3.24/tls.c.orig	2012-12-13 22:12:27.000000000 +0100
afea54
+++ fetchmail-6.3.24/tls.c	2017-03-07 12:35:18.964038382 +0100
afea54
@@ -1,35 +0,0 @@
afea54
-/** \file tls.c - collect common TLS functionality 
afea54
- * \author Matthias Andree
afea54
- * \date 2006
afea54
- */
afea54
-
afea54
-#include "fetchmail.h"
afea54
-
afea54
-#ifdef HAVE_STRINGS_H
afea54
-#include <strings.h>
afea54
-#endif
afea54
-
afea54
-/** return true if user allowed TLS */
afea54
-int maybe_tls(struct query *ctl) {
afea54
-#ifdef SSL_ENABLE
afea54
-         /* opportunistic  or forced TLS */
afea54
-    return (!ctl->sslproto || !strcasecmp(ctl->sslproto,"tls1"))
afea54
-	&& !ctl->use_ssl;
afea54
-#else
afea54
-    (void)ctl;
afea54
-    return 0;
afea54
-#endif
afea54
-}
afea54
-
afea54
-/** return true if user requires TLS, note though that this code must
afea54
- * always use a logical AND with maybe_tls(). */
afea54
-int must_tls(struct query *ctl) {
afea54
-#ifdef SSL_ENABLE
afea54
-    return maybe_tls(ctl)
afea54
-	&& (ctl->sslfingerprint || ctl->sslcertck
afea54
-		|| (ctl->sslproto && !strcasecmp(ctl->sslproto, "tls1")));
afea54
-#else
afea54
-    (void)ctl;
afea54
-    return 0;
afea54
-#endif
afea54
-}