<<< Date Index >>>     <<< Thread Index >>>

[PATCH] support for SSL/TLS compression



# HG changeset patch
# User Michael.Elkins@xxxxxxxxxx
# Date 1281724591 25200
# Branch HEAD
# Node ID a0d6b775f42a1f4f43b416a7137cb3da6f1f7214
# Parent  6572e8bcd723a34d9457650fe272ff9633033ccf
add support for SSL/TLS-layer compression

diff --git a/init.h b/init.h
--- a/init.h
+++ b/init.h
@@ -2915,6 +2915,15 @@
   ** The file containing a client certificate and its associated private
   ** key.
   */
+  { "ssl_compress", DT_BOOL, R_NONE, OPTSSLCOMPRESS, 0 },
+  /*
+  ** .pp
+  ** If this variable is \fIset\fP, Mutt will enable the use of compression
+  ** for SSL/TLS connections if the server supports it.
+  ** .pp
+  ** \fBNote:\fP When Mutt is compiled with OpenSSL, it is not possible to
+  ** disable compression without restaring Mutt.
+  */
   { "ssl_force_tls",         DT_BOOL, R_NONE, OPTSSLFORCETLS, 0 },
   /*
    ** .pp
diff --git a/mutt.h b/mutt.h
--- a/mutt.h
+++ b/mutt.h
@@ -379,6 +379,7 @@
   OPTSSLFORCETLS,
   OPTSSLVERIFYDATES,
   OPTSSLVERIFYHOST,
+  OPTSSLCOMPRESS,
 #endif /* defined(USE_SSL) */
   OPTIMPLICITAUTOVIEW,
   OPTINCLUDEONLYFIRST,
diff --git a/mutt_ssl.c b/mutt_ssl.c
--- a/mutt_ssl.c
+++ b/mutt_ssl.c
@@ -194,6 +194,20 @@
    * itself might clobber the last SSL error. */
   SSL_load_error_strings();
   SSL_library_init();
+
+  /* according to RFC 3749, DEFLATE is 1 */
+  if (option (OPTSSLCOMPRESS))
+  {
+    dprint (1, (debugfile, "enabling SSL compression by user request\n"));
+
+    if (SSL_COMP_add_compression_method (1 , COMP_zlib ()))
+    {
+      unsigned long err = ERR_get_error ();
+      dprint (1, (debugfile, "SSL_COMP_add_compression_method() failed: %s (code 
%lu)\n",
+           ERR_error_string (err, NULL), err));
+    }
+  }
+
   init_complete = 1;
   return 0;
 }
@@ -379,6 +393,11 @@
     SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl));
   mutt_sleep (0);
+ dprint (1, (debugfile, "SSL compression method: %s\n",
+       SSL_COMP_get_name (SSL_get_current_compression (ssldata->ssl))));
+  dprint (1, (debugfile, "SSL expansion method: %s\n",
+       SSL_COMP_get_name (SSL_get_current_expansion (ssldata->ssl))));
+
   return 0;
 }
@@ -1061,3 +1080,11 @@ return snprintf(buf, size, "%s", account->pass);
 }
+
+/* returns non-zero if the SSL connection is compressed, or zero if not 
compressed. */
+int mutt_ssl_is_compressed (CONNECTION *conn)
+{
+  sslsockdata* ssldata = conn->data;
+  return (SSL_get_current_compression (ssldata->ssl) != NULL &&
+         (SSL_get_current_expansion (ssldata->ssl) != NULL));
+}
diff --git a/mutt_ssl.h b/mutt_ssl.h
--- a/mutt_ssl.h
+++ b/mutt_ssl.h
@@ -24,6 +24,9 @@
 #if defined(USE_SSL)
 int mutt_ssl_starttls (CONNECTION* conn);
 int mutt_ssl_socket_setup (CONNECTION *conn);
+
+/* returns non-zero if the SSL connection is compressed, or zero if not 
compressed. */
+int mutt_ssl_is_compressed (CONNECTION *conn);
 #endif
#endif /* _MUTT_SSL_H_ */
diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c
--- a/mutt_ssl_gnutls.c
+++ b/mutt_ssl_gnutls.c
@@ -323,6 +323,23 @@
gnutls_credentials_set (data->state, GNUTLS_CRD_CERTIFICATE, data->xcred); + if (option (OPTSSLCOMPRESS))
+  {
+    /*gnutls_compression_method_t*/ int compression_methods[] = {
+      GNUTLS_COMP_DEFLATE,
+      GNUTLS_COMP_NULL,
+      0
+    };
+    int rc;
+
+    /* enable TLS-level compression */
+    dprint (1, (debugfile, "enabling SSL compression by user request\n"));
+    if ((rc = gnutls_compression_set_priority (data->state, 
compression_methods) != GNUTLS_E_SUCCESS))
+    {
+      dprint (1, (debugfile, "error enabling SSL compression (code %d)\n", 
rc));
+    }
+  }
+
   err = gnutls_handshake(data->state);
while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED)
@@ -361,6 +378,8 @@
     mutt_sleep (0);
   }
+ dprint (1, (debugfile, "SSL compression method: %s\n", NONULL (gnutls_compression_get_name (gnutls_compression_get (data->state)))));
+
   return 0;
fail: