Attached is a revised patch for ticket #3515.  Currently mutt calls the
deprecated gnutls_protocol_set_priority.  This patch add autoconf checks
(as requested by Brendan at
http://dev.mutt.org/trac/ticket/3515#comment:1)

-Kevin
# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1408758698 25200
#      Fri Aug 22 18:51:38 2014 -0700
# Node ID 48f5e2a518095333ec06debb2307fa35f6f192e5
# Parent  8f62001989cc9f564236e54b318ecca05f551af2
Fix deprecated gnutls_protocol_set_priority.  (closes #3515)

This patch is based off of the patch at
http://dev.mutt.org/trac/attachment/ticket/3515/624058-gnutls-deprecated-set-priority.patch

The mutt source has changed since then, with more TLS options being
added.  This patch therefore uses a slightly different strategy for generating 
the
priority string.

The patch also adds autoconf support, as requested by brendan at
http://dev.mutt.org/trac/ticket/3515#comment:1

diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -702,16 +702,19 @@
     fi
     saved_LIBS="$LIBS"
 
     AC_CHECK_LIB(gnutls, gnutls_check_version,
       [dnl GNUTLS found
       AC_CHECK_DECLS([GNUTLS_VERIFY_DISABLE_TIME_CHECKS], [], [],
                     [[#include <gnutls/x509.h>]])
 
+      LIBS="$LIBS -lgnutls"
+      AC_CHECK_FUNCS(gnutls_priority_set_direct)
+
       LIBS="$saved_LIBS"
       MUTTLIBS="$MUTTLIBS -lgnutls"
 
       AC_DEFINE(USE_SSL, 1, [ Define if you want support for SSL. ])
       AC_DEFINE(USE_SSL_GNUTLS, 1, [ Define if you want support for SSL via 
GNUTLS. ])
 
       MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS mutt_ssl_gnutls.o"
       need_ssl=yes],
diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c
--- a/mutt_ssl_gnutls.c
+++ b/mutt_ssl_gnutls.c
@@ -233,29 +233,103 @@
   mutt_account_getuser (&conn->account);
 
 err_dn:
   FREE (&dn);
 err_crt:
   gnutls_x509_crt_deinit (clientcrt);
 }
 
+#if HAVE_GNUTLS_PRIORITY_SET_DIRECT
+static int tls_set_priority(tlssockdata *data)
+{
+  size_t nproto = 4;
+  char priority[SHORT_STRING];
+  int err;
+
+  priority[0] = 0;
+  safe_strcat (priority, sizeof (priority), "NORMAL");
+
+  if (! option(OPTTLSV1_2))
+  {
+    nproto--;
+    safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.2");
+  }
+  if (! option(OPTTLSV1_1))
+  {
+    nproto--;
+    safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.1");
+  }
+  if (! option(OPTTLSV1))
+  {
+    nproto--;
+    safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.0");
+  }
+  if (! option(OPTSSLV3))
+  {
+    nproto--;
+    safe_strcat (priority, sizeof (priority), ":-VERS-SSL3.0");
+  }
+
+  if (nproto == 0)
+  {
+    mutt_error (_("All available protocols for TLS/SSL connection disabled"));
+    return -1;
+  }
+
+  if ((err = gnutls_priority_set_direct (data->state, priority, NULL)) < 0)
+  {
+    mutt_error ("gnutls_priority_set_direct(%s): %s", priority, 
gnutls_strerror(err));
+    mutt_sleep (2);
+    return -1;
+  }
+
+  return 0;
+}
+#else
 /* This array needs to be large enough to hold all the possible values support
  * by Mutt.  The initialized values are just placeholders--the array gets
  * overwrriten in tls_negotiate() depending on the $ssl_use_* options.
  */
 static int protocol_priority[] = {GNUTLS_TLS1_2, GNUTLS_TLS1_1, GNUTLS_TLS1, 
GNUTLS_SSL3, 0};
 
+static int tls_set_priority(tlssockdata *data)
+{
+  size_t nproto = 0; /* number of tls/ssl protocols */
+
+  if (option(OPTTLSV1_2))
+    protocol_priority[nproto++] = GNUTLS_TLS1_2;
+  if (option(OPTTLSV1_1))
+    protocol_priority[nproto++] = GNUTLS_TLS1_1;
+  if (option(OPTTLSV1))
+    protocol_priority[nproto++] = GNUTLS_TLS1;
+  if (option(OPTSSLV3))
+    protocol_priority[nproto++] = GNUTLS_SSL3;
+  protocol_priority[nproto] = 0;
+
+  if (nproto == 0)
+  {
+    mutt_error (_("All available protocols for TLS/SSL connection disabled"));
+    return -1;
+  }
+
+  /* We use default priorities (see gnutls documentation),
+     except for protocol version */
+  gnutls_set_default_priority (data->state);
+  gnutls_protocol_set_priority (data->state, protocol_priority);
+  return 0;
+}
+#endif
+
 /* tls_negotiate: After TLS state has been initialized, attempt to negotiate
  *   TLS over the wire, including certificate checks. */
 static int tls_negotiate (CONNECTION * conn)
 {
   tlssockdata *data;
   int err;
-  size_t nproto = 0; /* number of tls/ssl protocols */
 
   data = (tlssockdata *) safe_calloc (1, sizeof (tlssockdata));
   conn->sockdata = data;
   err = gnutls_certificate_allocate_credentials (&data->xcred);
   if (err < 0)
   {
     FREE(&conn->sockdata);
     mutt_error ("gnutls_certificate_allocate_credentials: %s", 
gnutls_strerror(err));
@@ -291,41 +365,19 @@
     mutt_error ("gnutls_handshake: %s", gnutls_strerror(err));
     mutt_sleep (2);
     goto fail;
   }
 
   /* set socket */
   gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)conn->fd);
 
-  if (option(OPTTLSV1_2))
-    protocol_priority[nproto++] = GNUTLS_TLS1_2;
-  if (option(OPTTLSV1_1))
-    protocol_priority[nproto++] = GNUTLS_TLS1_1;
-  if (option(OPTTLSV1))
-    protocol_priority[nproto++] = GNUTLS_TLS1;
-  if (option(OPTSSLV3))
-    protocol_priority[nproto++] = GNUTLS_SSL3;
-  protocol_priority[nproto] = 0;
-
-  /* disable TLS/SSL protocols as needed */
-  if (nproto == 0)
-  {
-    mutt_error (_("All available protocols for TLS/SSL connection disabled"));
+  if (tls_set_priority(data) < 0) {
     goto fail;
   }
-  /*
-  else
-    use the list set above
-  */
-
-  /* We use default priorities (see gnutls documentation),
-     except for protocol version */
-  gnutls_set_default_priority (data->state);
-  gnutls_protocol_set_priority (data->state, protocol_priority);
 
   if (SslDHPrimeBits > 0)
   {
     gnutls_dh_set_prime_bits (data->state, SslDHPrimeBits);
   }
 
 /*
   gnutls_set_cred (data->state, GNUTLS_ANON, NULL);

Attachment: signature.asc
Description: PGP signature

Reply via email to