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