[exim-cvs] Basic DANE entry points

Page principale
Supprimer ce message
Répondre à ce message
Auteur: Exim Git Commits Mailing List
Date:  
À: exim-cvs
Sujet: [exim-cvs] Basic DANE entry points
Gitweb: http://git.exim.org/exim.git/commitdiff/043b12481513cec52c31717c8ad5248d2b344ad2
Commit:     043b12481513cec52c31717c8ad5248d2b344ad2
Parent:     946ecbe0c046adc421dd897b34ed5b68229bba22
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Fri Aug 1 18:16:53 2014 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Fri Aug 1 19:06:49 2014 +0100


    Basic DANE entry points
---
 doc/doc-txt/experimental-spec.txt |   13 ++++
 src/src/EDITME                    |    3 +
 src/src/dane-openssl.c            |    5 ++
 src/src/dane.c                    |   31 ++++-----
 src/src/exim.c                    |    3 +
 src/src/tls-openssl.c             |  133 ++++++++++++++++++++++++++++---------
 6 files changed, 140 insertions(+), 48 deletions(-)


diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 6657f63..1a78635 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -1130,6 +1130,7 @@ in a router. Exim will then send the success DSN himself if requested as if
the next hop does not support DSN.
Adding it to a redirect router makes no difference.

+
Certificate name checking
--------------------------------------------------------------
The X509 certificates used for TLS are supposed be verified
@@ -1148,6 +1149,18 @@ a single wildcard being the initial component of a 3-or-more
component FQDN).


+DANE
+------------------------------------------------------------
+If dane is in use the following transport options are ignored:
+ tls_verify_hosts
+ tls_try_verify_hosts
+ tls_verify_certificates
+ tls_crl
+ tls_verify_cert_hostnames
+ hosts_require_ocsp
+ hosts_request_ocsp
+
+

--------------------------------------------------------------
End of file
diff --git a/src/src/EDITME b/src/src/EDITME
index d576fd7..01c4ebc 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -494,6 +494,9 @@ EXIM_MONITOR=eximon.bin
# Uncomment the following line to add DSN support
# EXPERIMENTAL_DSN=yes

+# Uncomment the following line to add DANE support
+# EXPERIMENTAL_DANE=yes
+
 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
 ###############################################################################
diff --git a/src/src/dane-openssl.c b/src/src/dane-openssl.c
index c8099f6..407e680 100644
--- a/src/src/dane-openssl.c
+++ b/src/src/dane-openssl.c
@@ -1471,6 +1471,11 @@ dane_idx = SSL_get_ex_new_index(0, 0, 0, 0, 0);
 Call this once.  Probably early in startup will do; may need
 to be after SSL library init.


+=> put after call to tls_init() for now
+
+Return
+  1    Success
+  0    Fail
 */


 int
diff --git a/src/src/dane.c b/src/src/dane.c
index 54fd00c..20dfe5b 100644
--- a/src/src/dane.c
+++ b/src/src/dane.c
@@ -2,15 +2,14 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/


-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2012, 2014 */
/* See the file NOTICE for conditions of use and distribution. */

-/* This module provides TLS (aka SSL) support for Exim. The code for OpenSSL is
-based on a patch that was originally contributed by Steve Haslam. It was
-adapted from stunnel, a GPL program by Michal Trojnara. The code for GNU TLS is
-based on a patch contributed by Nikos Mavroyanopoulos. Because these packages
-are so very different, the functions for each are kept in separate files. The
-relevant file is #included as required, after any any common functions.
+/* This module provides DANE (RFC6659) support for Exim. See also
+the draft RFC for DANE-over-SMTP, "SMTP security via opportunistic DANE TLS"
+(V. Dukhovni, W. Hardaker) - version 10, dated May 25, 2014.
+
+The code for DANE support with Openssl was provided by V.Dukhovni.

No cryptographic code is included in Exim. All this module does is to call
functions from the OpenSSL or GNU TLS libraries. */
@@ -30,15 +29,15 @@ static void dummy(int x) { dummy(x-1); }
#else

/* Enabling DANE without enabling TLS cannot work. Abort the compilation. */
-#ifndef SUPPORT_TLS
-#error DANE support requires that TLS support must be enabled. Abort build.
-#endif
-
-#ifdef USE_GNUTLS
-#include "dane-gnu.c"
-#else
-#include "dane-openssl.c"
-#endif
+# ifndef SUPPORT_TLS
+# error DANE support requires that TLS support must be enabled. Abort build.
+# endif
+
+# ifdef USE_GNUTLS
+# include "dane-gnu.c"
+# else
+# include "dane-openssl.c"
+# endif


#endif /* EXPERIMENTAL_DANE */
diff --git a/src/src/exim.c b/src/src/exim.c
index 517b543..8a9de72 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -820,6 +820,9 @@ fprintf(f, "Support for:");
#ifdef EXPERIMENTAL_BRIGHTMAIL
fprintf(f, " Experimental_Brightmail");
#endif
+#ifdef EXPERIMENTAL_DANE
+ fprintf(f, " Experimental_DANE");
+#endif
#ifdef EXPERIMENTAL_DCC
fprintf(f, " Experimental_DCC");
#endif
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index eeff64f..b96dbbf 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1534,6 +1534,50 @@ return OK;



+static int
+tls_client_basic_ctx_init(SSL_CTX * ctx,
+    host_item * host, smtp_transport_options_block * ob
+#ifdef EXPERIMENTAL_CERTNAMES
+    , tls_ext_ctx_cb * cbinfo
+#endif
+              )
+{
+int rc;
+/* stick to the old behaviour for compatibility if tls_verify_certificates is 
+   set but both tls_verify_hosts and tls_try_verify_hosts is not set. Check only
+   the specified host patterns if one of them is defined */
+
+if ((!ob->tls_verify_hosts && !ob->tls_try_verify_hosts) ||
+    (verify_check_host(&ob->tls_verify_hosts) == OK))
+  {
+  if ((rc = setup_certs(ctx, ob->tls_verify_certificates,
+    ob->tls_crl, host, FALSE, verify_callback_client)) != OK)
+    return rc;
+  client_verify_optional = FALSE;
+
+#ifdef EXPERIMENTAL_CERTNAMES
+  if (ob->tls_verify_cert_hostnames)
+    {
+    if (!expand_check(ob->tls_verify_cert_hostnames,
+              US"tls_verify_cert_hostnames",
+              &cbinfo->verify_cert_hostnames))
+      return FAIL;
+    if (cbinfo->verify_cert_hostnames)
+      DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
+              cbinfo->verify_cert_hostnames);
+    }
+#endif
+  }
+else if (verify_check_host(&ob->tls_try_verify_hosts) == OK)
+  {
+  if ((rc = setup_certs(ctx, ob->tls_verify_certificates,
+    ob->tls_crl, host, TRUE, verify_callback_client)) != OK)
+    return rc;
+  client_verify_optional = TRUE;
+  }
+
+return OK;
+}


 /*************************************************
 *    Start a TLS session in a client             *
@@ -1562,12 +1606,30 @@ uschar *expciphers;
 X509* server_cert;
 int rc;
 static uschar cipherbuf[256];
+
+#ifndef DISABLE_OCSP
+BOOL require_ocsp = FALSE;
+BOOL request_ocsp = FALSE;
+#endif
+#ifdef EXPERIMENTAL_DANE
+BOOL dane_in_use;
+#endif
+
+#ifdef EXPERIMENTAL_DANE
+/*XXX TBD: test for transport options, and for TLSA records */
+dane_in_use = FALSE;
+
+if (!dane_in_use)
+#endif
+
 #ifndef DISABLE_OCSP
-BOOL require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
-  NULL, host->name, host->address, NULL) == OK;
-BOOL request_ocsp = require_ocsp ? TRUE
-  : verify_check_this_host(&ob->hosts_request_ocsp,
-      NULL, host->name, host->address, NULL) == OK;
+  {
+  require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
+    NULL, host->name, host->address, NULL) == OK;
+  request_ocsp = require_ocsp ? TRUE
+    : verify_check_this_host(&ob->hosts_request_ocsp,
+    NULL, host->name, host->address, NULL) == OK;
+  }
 #endif


 rc = tls_init(&client_ctx, host, NULL,
@@ -1598,38 +1660,24 @@ if (expciphers != NULL)
     return tls_error(US"SSL_CTX_set_cipher_list", host, NULL);
   }


-/* stick to the old behaviour for compatibility if tls_verify_certificates is 
-   set but both tls_verify_hosts and tls_try_verify_hosts is not set. Check only
-   the specified host patterns if one of them is defined */
-
-if ((!ob->tls_verify_hosts && !ob->tls_try_verify_hosts) ||
-    (verify_check_host(&ob->tls_verify_hosts) == OK))
+#ifdef EXPERIMENTAL_DANE
+if (dane_in_use)
   {
-  if ((rc = setup_certs(client_ctx, ob->tls_verify_certificates,
-    ob->tls_crl, host, FALSE, verify_callback_client)) != OK)
-    return rc;
-  client_verify_optional = FALSE;
+  if (!DANESSL_library_init())
+    return tls_error(US"library init", host, US"DANE library error");
+  if (DANESSL_CTX_init(client_ctx) <= 0)
+    return tls_error(US"context init", host, US"DANE library error");
+  }
+else


+#endif
+
+  if ((rc = tls_client_basic_ctx_init(client_ctx, host, ob
 #ifdef EXPERIMENTAL_CERTNAMES
-  if (ob->tls_verify_cert_hostnames)
-    {
-    if (!expand_check(ob->tls_verify_cert_hostnames,
-              US"tls_verify_cert_hostnames",
-              &client_static_cbinfo->verify_cert_hostnames))
-      return FAIL;
-    if (client_static_cbinfo->verify_cert_hostnames)
-      DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
-              client_static_cbinfo->verify_cert_hostnames);
-    }
+                , client_static_cbinfo
 #endif
-  }
-else if (verify_check_host(&ob->tls_try_verify_hosts) == OK)
-  {
-  if ((rc = setup_certs(client_ctx, ob->tls_verify_certificates,
-    ob->tls_crl, host, TRUE, verify_callback_client)) != OK)
+                )) != OK)
     return rc;
-  client_verify_optional = TRUE;
-  }


if ((client_ssl = SSL_new(client_ctx)) == NULL)
return tls_error(US"SSL_new", host, NULL);
@@ -1671,6 +1719,23 @@ if (request_ocsp)
}
#endif

+#ifdef EXPERIMENTAL_DANE
+if (dane_in_use)
+  {
+  if (DANESSL_init(client_ssl, NULL, NULL /*??? hostnames*/) != 1)
+    return tls_error(US"hostnames load", host, US"DANE library error");
+
+  /*
+  foreach TLSA record
+    
+    DANESSL_add_tlsa(client_ssl, uint8_t usage, uint8_t selector,
+    const char *mdname,
+        unsigned const char *data, size_t dlen)
+  */
+  }
+#endif
+
+
 /* There doesn't seem to be a built-in timeout on connection. */


DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
@@ -1679,6 +1744,10 @@ alarm(ob->command_timeout);
rc = SSL_connect(client_ssl);
alarm(0);

+#ifdef EXPERIMENTAL_DANE
+DANESSL_cleanup(client_ssl);    /*XXX earliest possible callpoint. Too early? */
+#endif
+
 if (rc <= 0)
   return tls_error(US"SSL_connect", host, sigalrm_seen ? US"timed out" : NULL);