Add tls_verify_hosts and tls_try_verify_hosts to smtp transport
authorWolfgang Breyha <wbreyha@gmx.net>
Wed, 26 Feb 2014 20:07:46 +0000 (20:07 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 26 Feb 2014 20:07:46 +0000 (20:07 +0000)
Patch version 2

src/src/functions.h
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/transports/smtp.h
src/src/verify.c

index 9d933fea77b37e09092ac3a0d58d3fab6ea4f9be..32bd0bc079902b55919514318a324da5e81daeea 100644 (file)
@@ -30,7 +30,7 @@ extern int     tls_client_start(int, host_item *, address_item *,
 # ifdef EXPERIMENTAL_OCSP
                  uschar *,
 # endif
-                 int, int);
+                 int, int, uschar *, uschar *);
 extern void    tls_close(BOOL, BOOL);
 extern int     tls_feof(void);
 extern int     tls_ferror(void);
index 4f1169aa415a6ed37efba907a10901894dc8261c..280744ec02b2142ba4c47c08e513b9fa3cf51129 100644 (file)
@@ -1563,6 +1563,8 @@ Arguments:
   require_ciphers   list of allowed ciphers or NULL
   dh_min_bits       minimum number of bits acceptable in server's DH prime
   timeout           startup timeout
+  verify_hosts     mandatory client verification 
+  try_verify_hosts optional client verification
 
 Returns:            OK/DEFER/FAIL (because using common functions),
                     but for a client, DEFER and FAIL have the same meaning
@@ -1577,7 +1579,8 @@ tls_client_start(int fd, host_item *host,
 #ifdef EXPERIMENTAL_OCSP
     uschar *require_ocsp ARG_UNUSED,
 #endif
-    int dh_min_bits, int timeout)
+    int dh_min_bits, int timeout,
+    uschar *verify_hosts, uschar *try_verify_hosts)
 {
 int rc;
 const char *error;
index 2b8d798c9a92e32e6c28ade08f7a8ce75a7515f0..a9adb613480364723ccadf7fe6c169f27b4086af 100644 (file)
@@ -1504,6 +1504,8 @@ Argument:
   dh_min_bits      minimum number of bits acceptable in server's DH prime
                    (unused in OpenSSL)
   timeout          startup timeout
+  verify_hosts     mandatory client verification 
+  try_verify_hosts optional client verification
 
 Returns:           OK on success
                    FAIL otherwise - note that tls_error() will not give DEFER
@@ -1518,7 +1520,8 @@ tls_client_start(int fd, host_item *host, address_item *addr,
 #ifdef EXPERIMENTAL_OCSP
   uschar *hosts_require_ocsp,
 #endif
-  int dh_min_bits ARG_UNUSED, int timeout)
+  int dh_min_bits ARG_UNUSED, int timeout,
+  uschar *verify_hosts, uschar *try_verify_hosts)
 {
 static uschar txt[256];
 uschar *expciphers;
@@ -1556,8 +1559,22 @@ if (expciphers != NULL)
     return tls_error(US"SSL_CTX_set_cipher_list", host, NULL);
   }
 
-rc = setup_certs(client_ctx, verify_certs, crl, host, FALSE, verify_callback_client);
-if (rc != OK) return 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 (((verify_hosts == NULL) && (try_verify_hosts == NULL)) ||
+    (verify_check_host(&verify_hosts) == OK))
+  {
+  rc = setup_certs(client_ctx, verify_certs, crl, host, FALSE, verify_callback_client);
+  if (rc != OK) return rc;
+  client_verify_optional = FALSE;
+  }
+else if (verify_check_host(&try_verify_hosts) == OK)
+  {
+  rc = setup_certs(client_ctx, verify_certs, crl, host, TRUE, verify_callback_client);
+  if (rc != OK) return rc;
+  client_verify_optional = TRUE;
+  }
 
 if ((client_ssl = SSL_new(client_ctx)) == NULL) return tls_error(US"SSL_new", host, NULL);
 SSL_set_session_id_context(client_ssl, sid_ctx, Ustrlen(sid_ctx));
index a77e472d666d28669ef427ef95b316090ad1b14f..938844799f731d50016a4ff504e6f362f02db208 100644 (file)
@@ -153,8 +153,12 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, tls_sni) },
   { "tls_tempfail_tryclear", opt_bool,
       (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
+  { "tls_try_verify_hosts", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) },
   { "tls_verify_certificates", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) }
+      (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
+  { "tls_verify_hosts",     opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, tls_verify_hosts) }
 #endif
 #ifdef EXPERIMENTAL_TPDA
  ,{ "tpda_host_defer_action", opt_stringptr,
@@ -227,7 +231,9 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* tls_verify_certificates */
   EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
                        /* tls_dh_min_bits */
-  TRUE                 /* tls_tempfail_tryclear */
+  TRUE,                /* tls_tempfail_tryclear */
+  NULL,                /* tls_verify_hosts */
+  NULL                 /* tls_try_verify_hosts */
 #endif
 #ifndef DISABLE_DKIM
  ,NULL,                /* dkim_canon */
@@ -1446,7 +1452,9 @@ if (tls_offered && !suppress_tls &&
       ob->hosts_require_ocsp,
 #endif
       ob->tls_dh_min_bits,
-      ob->command_timeout);
+      ob->command_timeout,
+      ob->tls_verify_hosts,
+      ob->tls_try_verify_hosts);
 
     /* TLS negotiation failed; give an error. From outside, this function may
     be called again to try in clear on a new connection, if the options permit
index 6c22e4b96ed3321c05a4eae29d0da3261184dc5a..fc4e014c1ae201c0a3e901d707f54b8172d6d66e 100644 (file)
@@ -64,6 +64,8 @@ typedef struct {
   uschar *tls_verify_certificates;
   int     tls_dh_min_bits;
   BOOL    tls_tempfail_tryclear;
+  uschar *tls_verify_hosts;
+  uschar *tls_try_verify_hosts;
   #endif
   #ifndef DISABLE_DKIM
   uschar *dkim_domain;
index 711b3af5a93bca4a8a661d44c955629e88c1bc2e..c83748a12f5c7f067d0e2d6ce68c85d1a7062501 100644 (file)
@@ -641,7 +641,8 @@ else
 #ifdef EXPERIMENTAL_OCSP
         ob->hosts_require_ocsp,
 #endif
-        ob->tls_dh_min_bits,         callout);
+        ob->tls_dh_min_bits, callout,
+         ob->tls_verify_hosts, ob->tls_try_verify_hosts);
 
         /* TLS negotiation failed; give an error.  Try in clear on a new connection,
            if the options permit it for this host. */