Package: fetchmail
Tags: patch

Hi,

The attached patch improves fethcmail SSL/TLS support.  It seems
to have some misunderstandings of openssl / SSL / TLS.

First, STARTTLS should work with both SSL and TLS, not just from
TLS 1.0.  The TLS in STARTTLS does not mean it's TLS only, TLS is
just a different name for SSL.

It also still seems to think only TLS 1.0 is supported while there
are more recent versions, and it encourages SSL3 because SSL2 is
broken.

I've also changed the way in which opportunistic TLS works a
little.  It seems to have only done this with TLS1 for the above
stated reasons which were wrong.

This patch results in the following changes with a server support
STARTTLS:
        | --ssl         | no option     | sslproto ssl23| sslproto tls1
Old:    | TLS 1.2       | TLS1.0        | not working   | TLS1.0
New:    | TLS 1.2       | TLS1.2        | TLS1.2        | TLS1.0

The "sslproto ssl23" case just send logout, I assume because
maybe_tls returns false.

This started by making the call to SSLv3_client_method() optional
in case openssl doesn't support it.


Kurt

Index: fetchmail-6.3.26/configure.ac
===================================================================
--- fetchmail-6.3.26.orig/configure.ac
+++ fetchmail-6.3.26/configure.ac
@@ -801,11 +801,6 @@ else
   AC_MSG_WARN(Consider re-running configure --with-ssl.)
 fi
 
-case "$LIBS" in *-lssl*)
-	AC_CHECK_DECLS([SSLv2_client_method],,,[#include <openssl/ssl.h>])
-	;;
-esac
-
 ###	use option --with-socks=DIR to point at SOCKS library
 AC_ARG_WITH(socks,
 	[  --with-socks[=DIR]      add built-in SOCKS firewall access],
Index: fetchmail-6.3.26/fetchmail-FAQ.html
===================================================================
--- fetchmail-6.3.26.orig/fetchmail-FAQ.html
+++ fetchmail-6.3.26/fetchmail-FAQ.html
@@ -2232,8 +2232,8 @@ negotiation, add this option:</p>
 
 <pre>sslproto ssl23</pre>
 
-<p>This restricts fetchmail's SSL/TLS protocol choice from the default
-"SSLv2, SSLv3, TLSv1" to the two SSL variants, disabling TLSv1. Note
+<p>This selects fetchmail's default SSL/TLS protocol choice that
+supports all SSL/TLS versions supported by the openssl library. Note
 however that this causes the connection to be unencrypted unless an
 encrypting &quot;plugin&quot; is used or SSL is requested explicitly.</p>
 
Index: fetchmail-6.3.26/fetchmail.man
===================================================================
--- fetchmail-6.3.26.orig/fetchmail.man
+++ fetchmail-6.3.26/fetchmail.man
@@ -413,16 +413,16 @@ from. The folder information is written
 (Keyword: ssl)
 .br
 Causes the connection to the mail server to be encrypted
-via SSL.  Connect to the server using the specified base protocol over a
-connection secured by SSL. This option defeats opportunistic starttls
-negotiation. It is highly recommended to use \-\-sslproto 'SSL3'
-\-\-sslcertck to validate the certificates presented by the server and
-defeat the obsolete SSLv2 negotiation. More information is available in
-the \fIREADME.SSL\fP file that ships with fetchmail.
-.IP
-Note that fetchmail may still try to negotiate SSL through starttls even
-if this option is omitted. You can use the \-\-sslproto option to defeat
-this behavior or tell fetchmail to negotiate a particular SSL protocol.
+via SSL / TLS.  This option makes encryption mandatory and uses a dedicated
+port for SSL / TLS.
+It is highly recommended to use \-\-sslcertck to validate
+the certificates presented by the server. More information is available
+in the \fIREADME.SSL\fP file that ships with fetchmail.
+.IP
+Note that fetchmail may still try to opportunisticly negotiate SSL through
+starttls even if this option is omitted.
+You can use the \-\-sslproto option to defeat this behavior or tell fetchmail to
+negotiate a particular SSL protocol.
 .IP
 If no port is specified, the connection is attempted to the well known
 port of the SSL version of the base protocol.  This is generally a
@@ -473,27 +473,33 @@ Also see \-\-sslcert above.
 .B \-\-sslproto <name>
 (Keyword: sslproto)
 .br
-Forces an SSL/TLS protocol. Possible values are \fB''\fP,
-\&'\fBSSL2\fP' (not supported on all systems),
-\&'\fBSSL23\fP', (use of these two values is discouraged
-and should only be used as a last resort) \&'\fBSSL3\fP', and
-\&'\fBTLS1\fP'.  The default behaviour if this option is unset is: for
-connections without \-\-ssl, use \&'\fBTLS1\fP' so that fetchmail will
-opportunistically try STARTTLS negotiation with TLS1. You can configure
-this option explicitly if the default handshake (TLS1 if \-\-ssl is not
-used) does not work for your server.
-.IP
-Use this option with '\fBTLS1\fP' value to enforce a STARTTLS
-connection. In this mode, it is highly recommended to also use
-\-\-sslcertck (see below).  Note that this will then cause fetchmail
-v6.3.19 to force STARTTLS negotiation even if it is not advertised by
-the server.
-.IP
-To defeat opportunistic TLSv1 negotiation when the server advertises
-STARTTLS or STLS, and use a cleartext connection use \fB''\fP.  This
-option, even if the argument is the empty string, will also suppress the
-diagnostic 'SERVER: opportunistic upgrade to TLS.' message in verbose
-mode. The default is to try appropriate protocols depending on context.
+Forces an SSL/TLS protocol. Possible values are:
+.RS
+.IP \fB''\fP
+Disables to use of SSL / TLS and send things in clear text.  If \-\-ssl is also
+used it will use the default.
+.IP \&'\fBSSL2\fP'
+Uses SSL 2.  This is an insecure protocol.  It's not supported on all systems.
+.IP \&'\fBSSL23\fP'
+This will use the highest version suppored by both client and server and may
+include SSL 2, SSL 3, TLS 1.0, TLS 1.1 and TLS 1.2 if supported.  This is the
+recommended value.
+.IP \&'\fBSSL3\fP'
+Uses SSL 3.  This is an insecure protocol.  It's not supported on all systems.
+.IP \&'\fBTLS1\fP'
+Uses TLS 1.0.
+.RE
+.IP
+When this option is not set and the server indicates supports for STARTTLS
+or STLS fetchmail will opportunistically try to negotiation SSL / TLS with
+the \fBSSL23\fP value.  This can be disabled by using the \fB''\fP value.
+.IP
+When this option is set to something other than \fB''\fP it will make encryption
+mandatory using the selected protocol.  It's recommended to use the \fBSSL23\fP
+value.
+In this mode, it is highly recommended to also use \-\-sslcertck (see below).
+If \-\-ssl isn't used it will try to use STARTTLS / STLS even if the server doesn't
+indicate support for it.
 .TP
 .B \-\-sslcertck
 (Keyword: sslcertck)
@@ -1219,15 +1225,14 @@ connection after negotiating an SSL sess
 SSL cannot be negotiated.  Some services, such as POP3 and IMAP, have
 different well known ports defined for the SSL encrypted services.  The
 encrypted ports will be selected automatically when SSL is enabled and
-no explicit port is specified. The \-\-sslproto 'SSL3' option should be
-used to select the SSLv3 protocol (default if unset: v2 or v3).  Also,
-the \-\-sslcertck command line or sslcertck run control file option
-should be used to force strict certificate checking - see below.
+no explicit port is specified. Also, the \-\-sslcertck command line or
+sslcertck run control file option should be used to force strict certificate
+checking - see below.
 .PP
 If SSL is not configured, fetchmail will usually opportunistically try to use
-STARTTLS. STARTTLS can be enforced by using \-\-sslproto "TLS1". TLS
-connections use the same port as the unencrypted version of the
-protocol and negotiate TLS via special command. The \-\-sslcertck
+STARTTLS. STARTTLS can be enforced by using \-\-sslproto. When using STARTTLS
+it uses the same port as the unencrypted version of the
+protocol and negotiate TLS via a special command. The \-\-sslcertck
 command line or sslcertck run control file option should be used to
 force strict certificate checking - see below.
 .PP
Index: fetchmail-6.3.26/imap.c
===================================================================
--- fetchmail-6.3.26.orig/imap.c
+++ fetchmail-6.3.26/imap.c
@@ -442,12 +442,10 @@ static int imap_getauth(int sock, struct
 	if (strstr(capabilities, "STARTTLS")
 		|| must_tls(ctl)) /* if TLS is mandatory, ignore capabilities */
 	{
-	    /* Use "tls1" rather than ctl->sslproto because tls1 is the only
-	     * protocol that will work with STARTTLS.  Don't need to worry
-	     * whether TLS is mandatory or opportunistic unless SSLOpen() fails
-	     * (see below). */
+	    /* Don't need to worry whether TLS is mandatory or opportunistic
+ 	     * unless SSLOpen() fails (see below). */
 	    if (gen_transact(sock, "STARTTLS") == PS_SUCCESS
-		    && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, "tls1", ctl->sslcertck,
+		    && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, ctl->sslproto, ctl->sslcertck,
 			ctl->sslcertfile, ctl->sslcertpath, ctl->sslfingerprint, commonname,
 			ctl->server.pollname, &ctl->remotename)) != -1)
 	    {
Index: fetchmail-6.3.26/pop3.c
===================================================================
--- fetchmail-6.3.26.orig/pop3.c
+++ fetchmail-6.3.26/pop3.c
@@ -443,12 +443,11 @@ static int pop3_getauth(int sock, struct
 	   if (has_stls
 		   || must_tls(ctl)) /* if TLS is mandatory, ignore capabilities */
 	   {
-	       /* Use "tls1" rather than ctl->sslproto because tls1 is the only
-		* protocol that will work with STARTTLS.  Don't need to worry
-		* whether TLS is mandatory or opportunistic unless SSLOpen() fails
-		* (see below). */
+	       /* 
+		* Don't need to worry whether TLS is mandatory or opportunistic unless
+		* SSLOpen() fails (see below). */
 	       if (gen_transact(sock, "STLS") == PS_SUCCESS
-		       && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, "tls1", ctl->sslcertck,
+		       && (set_timeout(mytimeout), SSLOpen(sock, ctl->sslcert, ctl->sslkey, ctl->sslproto, ctl->sslcertck,
 			   ctl->sslcertfile, ctl->sslcertpath, ctl->sslfingerprint, commonname,
 			   ctl->server.pollname, &ctl->remotename)) != -1)
 	       {
Index: fetchmail-6.3.26/README.SSL
===================================================================
--- fetchmail-6.3.26.orig/README.SSL
+++ fetchmail-6.3.26/README.SSL
@@ -25,22 +25,26 @@ Quickstart
 For use of SSL or TLS with in-band negotiation on the regular service's port, 
 i. e. with STLS or STARTTLS, use these command line options
 
-    --sslproto tls1 --sslcertck
+    --sslproto ssl23 --sslcertck
 
 or these options in the rcfile (after the respective "user"... options)
 
-      sslproto tls1   sslcertck
+      sslproto ssl23   sslcertck
 
 
 For use of SSL or TLS on a separate port, if the whole TCP connection is 
 SSL-encrypted from the very beginning, use these command line options (in the 
 rcfile, omit all leading "--"):
 
-    --ssl --sslproto ssl3 --sslcertck
+    --ssl --sslcertck
 
 or these options in the rcfile (after the respective "user"... options)
 
-      ssl   sslproto ssl3   sslcertck
+      ssl   sslcertck
+
+By default it will do opportunistic encryption if the server announces it with
+STLS or STARTTLS but will not verify the certificate.  Using either --sslproto
+or --ssl will make the use of encryption mandatory.
 
 
 Background and use (long version :-))
Index: fetchmail-6.3.26/socket.c
===================================================================
--- fetchmail-6.3.26.orig/socket.c
+++ fetchmail-6.3.26/socket.c
@@ -907,14 +907,19 @@ int SSLOpen(int sock, char *mycert, char
 	_ssl_context[sock] = NULL;
 	if(myproto) {
 		if(!strcasecmp("ssl2",myproto)) {
-#if HAVE_DECL_SSLV2_CLIENT_METHOD + 0 > 0
+#ifndef OPENSSL_NO_SSL2
 			_ctx[sock] = SSL_CTX_new(SSLv2_client_method());
 #else
 			report(stderr, GT_("Your operating system does not support SSLv2.\n"));
 			return -1;
 #endif
+#ifndef OPENSSL_NO_SSL3
 		} else if(!strcasecmp("ssl3",myproto)) {
 			_ctx[sock] = SSL_CTX_new(SSLv3_client_method());
+#else
+			report(stderr, GT_("Your operating system does not support SSLv3.\n"));
+			return -1;
+#endif
 		} else if(!strcasecmp("tls1",myproto)) {
 			_ctx[sock] = SSL_CTX_new(TLSv1_client_method());
 		} else if (!strcasecmp("ssl23",myproto)) {
Index: fetchmail-6.3.26/tls.c
===================================================================
--- fetchmail-6.3.26.orig/tls.c
+++ fetchmail-6.3.26/tls.c
@@ -9,12 +9,11 @@
 #include <strings.h>
 #endif
 
-/** return true if user allowed TLS */
+/** return true if user allows opportunistic TLS */
 int maybe_tls(struct query *ctl) {
 #ifdef SSL_ENABLE
-         /* opportunistic  or forced TLS */
-    return (!ctl->sslproto || !strcasecmp(ctl->sslproto,"tls1"))
-	&& !ctl->use_ssl;
+    /* opportunistic encryption is disabled with sslproto == "" */
+    return (!ctl->sslproto || strcmp(ctl->sslproto,"")) && !ctl->use_ssl;
 #else
     (void)ctl;
     return 0;
@@ -26,8 +25,7 @@ int maybe_tls(struct query *ctl) {
 int must_tls(struct query *ctl) {
 #ifdef SSL_ENABLE
     return maybe_tls(ctl)
-	&& (ctl->sslfingerprint || ctl->sslcertck
-		|| (ctl->sslproto && !strcasecmp(ctl->sslproto, "tls1")));
+	&& (ctl->sslfingerprint || ctl->sslcertck || ctl->sslproto);
 #else
     (void)ctl;
     return 0;

Reply via email to