Make transport name available in verify-callouts. Add verify_mode variable
[exim.git] / src / src / tls-gnu.c
index 3043e3abc925ff07f2ee9b6ed8a069d118c853a9..20e11cae16e77a32181d18e5c8d5cb7ae10bec4f 100644 (file)
@@ -47,9 +47,14 @@ require current GnuTLS, then we'll drop support for the ancient libraries).
 # warning "GnuTLS library version too old; define DISABLE_OCSP in Makefile"
 # define DISABLE_OCSP
 #endif
-#if GNUTLS_VERSION_NUMBER < 0x020a00 && defined(EXPERIMENTAL_TPDA)
-# warning "GnuTLS library version too old; TPDA tls:cert event unsupported"
-# undef EXPERIMENTAL_TPDA
+#if GNUTLS_VERSION_NUMBER < 0x020a00 && defined(EXPERIMENTAL_EVENT)
+# warning "GnuTLS library version too old; tls:cert event unsupported"
+# undef EXPERIMENTAL_EVENT
+#endif
+#if GNUTLS_VERSION_NUMBER >= 0x030306
+# define SUPPORT_CA_DIR
+#else
+# undef  SUPPORT_CA_DIR
 #endif
 
 #ifndef DISABLE_OCSP
@@ -119,7 +124,7 @@ typedef struct exim_gnutls_state {
 #ifdef EXPERIMENTAL_CERTNAMES
   uschar *exp_tls_verify_cert_hostnames;
 #endif
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
   uschar *event_action;
 #endif
 
@@ -140,7 +145,7 @@ static const exim_gnutls_state_st exim_gnutls_state_init = {
 #ifdef EXPERIMENTAL_CERTNAMES
                                             NULL,
 #endif
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
                                             NULL,
 #endif
   NULL,
@@ -268,7 +273,7 @@ tls_error(const uschar *prefix, const char *msg, const host_item *host)
 {
 if (host)
   {
-  log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s%s",
+  log_write(0, LOG_MAIN, "H=%s [%s] TLS error on connection (%s)%s%s",
       host->name, host->address, prefix, msg ? ": " : "", msg ? msg : "");
   return FAIL;
   }
@@ -277,6 +282,7 @@ else
   uschar *conn_info = smtp_get_connection_info();
   if (Ustrncmp(conn_info, US"SMTP ", 5) == 0)
     conn_info += 5;
+  /* I'd like to get separated H= here, but too hard for now */
   log_write(0, LOG_MAIN, "TLS error on %s (%s)%s%s",
       conn_info, prefix, msg ? ": " : "", msg ? msg : "");
   return DEFER;
@@ -884,6 +890,7 @@ if (Ustat(state->exp_tls_verify_certificates, &statbuf) < 0)
   return DEFER;
   }
 
+#ifndef SUPPORT_CA_DIR
 /* The test suite passes in /dev/null; we could check for that path explicitly,
 but who knows if someone has some weird FIFO which always dumps some certs, or
 other weirdness.  The thing we really want to check is that it's not a
@@ -899,6 +906,7 @@ if (S_ISDIR(statbuf.st_mode))
       state->exp_tls_verify_certificates);
   return DEFER;
   }
+#endif
 
 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
         state->exp_tls_verify_certificates, statbuf.st_size);
@@ -910,8 +918,18 @@ if (statbuf.st_size == 0)
   return OK;
   }
 
-cert_count = gnutls_certificate_set_x509_trust_file(state->x509_cred,
+cert_count =
+
+#ifdef SUPPORT_CA_DIR
+  (statbuf.st_mode & S_IFMT) == S_IFDIR
+  ?
+  gnutls_certificate_set_x509_trust_dir(state->x509_cred,
+    CS state->exp_tls_verify_certificates, GNUTLS_X509_FMT_PEM)
+  :
+#endif
+  gnutls_certificate_set_x509_trust_file(state->x509_cred,
     CS state->exp_tls_verify_certificates, GNUTLS_X509_FMT_PEM);
+
 if (cert_count < 0)
   {
   rc = cert_count;
@@ -1524,10 +1542,10 @@ return 0;
 #endif
 
 
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
 /*
 We use this callback to get observability and detail-level control
-for an exim client TLS connection, raising a TPDA tls:cert event
+for an exim client TLS connection, raising a tls:cert event
 for each cert in the chain presented by the server.  Any event
 can deny verification.
 
@@ -1556,7 +1574,7 @@ if (cert_list)
     }
 
   state->tlsp->peercert = crt;
-  if (tpda_raise_event(state->event_action,
+  if (event_raise(state->event_action,
              US"tls:cert", string_sprintf("%d", cert_list_size)) == DEFER)
     {
     log_write(0, LOG_MAIN,
@@ -1867,10 +1885,10 @@ if (request_ocsp)
   }
 #endif
 
-#ifdef EXPERIMENTAL_TPDA
-if (tb->tpda_event_action)
+#ifdef EXPERIMENTAL_EVENT
+if (tb->event_action)
   {
-  state->event_action = tb->tpda_event_action;
+  state->event_action = tb->event_action;
   gnutls_session_set_ptr(state->session, state);
   gnutls_certificate_set_verify_function(state->x509_cred, client_verify_cb);
   }