More regular logging use of H=<name> [<ip>]
[exim.git] / src / src / tls-openssl.c
index 5056e618876ef19186fe34bb567ebbd85f31be21..43ea8a0d2ec31a42b550b538ea8d574fa461a6af 100644 (file)
@@ -167,27 +167,28 @@ Returns:    OK/DEFER/FAIL
 static int
 tls_error(uschar *prefix, host_item *host, uschar *msg)
 {
-if (msg == NULL)
+if (!msg)
   {
   ERR_error_string(ERR_get_error(), ssl_errstring);
   msg = (uschar *)ssl_errstring;
   }
 
-if (host == NULL)
+if (host)
+  {
+  log_write(0, LOG_MAIN, "H=%s [%s] TLS error on connection (%s): %s",
+    host->name, host->address, prefix, msg);
+  return FAIL;
+  }
+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",
     conn_info, prefix, msg);
   return DEFER;
   }
-else
-  {
-  log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
-    host->name, host->address, prefix, msg);
-  return FAIL;
-  }
 }
 
 
@@ -1376,9 +1377,23 @@ if (expcerts != NULL && *expcerts != '\0')
           !SSL_CTX_load_verify_locations(sctx, CS file, CS dir))
       return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
 
+    /* Load the list of CAs for which we will accept certs, for sending
+    to the client.  This is only for the one-file tls_verify_certificates
+    variant.
+    If a list isn't loaded into the server, but
+    some verify locations are set, the server end appears to make
+    a wildcard reqest for client certs.
+    Meanwhile, the client library as deafult behaviour *ignores* the list
+    we send over the wire - see man SSL_CTX_set_client_cert_cb.
+    Because of this, and that the dir variant is likely only used for
+    the public-CA bundle (not for a private CA), not worth fixing.
+    */
     if (file != NULL)
       {
-      SSL_CTX_set_client_CA_list(sctx, SSL_load_client_CA_file(CS file));
+      STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file);
+DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
+                                 sk_X509_NAME_num(names));
+      SSL_CTX_set_client_CA_list(sctx, names);
       }
     }
 
@@ -1697,22 +1712,23 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
   uint8_t usage, selector, mtype;
   const char * mdname;
 
-  found++;
   usage = *p++;
+
+  /* Only DANE-TA(2) and DANE-EE(3) are supported */
+  if (usage != 2 && usage != 3) continue;
+
   selector = *p++;
   mtype = *p++;
 
   switch (mtype)
     {
-    default:
-      log_write(0, LOG_MAIN,
-               "DANE error: TLSA record w/bad mtype 0x%x", mtype);
-      return FAIL;
-    case 0:    mdname = NULL; break;
-    case 1:    mdname = "sha256"; break;
-    case 2:    mdname = "sha512"; break;
+    default: continue; /* Only match-types 0, 1, 2 are supported */
+    case 0:  mdname = NULL; break;
+    case 1:  mdname = "sha256"; break;
+    case 2:  mdname = "sha512"; break;
     }
 
+  found++;
   switch (DANESSL_add_tlsa(ssl, usage, selector, mdname, p, rr->size - 3))
     {
     default:
@@ -1727,7 +1743,7 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
 if (found)
   return OK;
 
-log_write(0, LOG_MAIN, "DANE error: No TLSA records");
+log_write(0, LOG_MAIN, "DANE error: No usable TLSA records");
 return FAIL;
 }
 #endif /*EXPERIMENTAL_DANE*/
@@ -1779,28 +1795,29 @@ tls_out.tlsa_usage = 0;
 
 #ifndef DISABLE_OCSP
   {
+# ifdef EXPERIMENTAL_DANE
+  if (  tlsa_dnsa
+     && ob->hosts_request_ocsp[0] == '*'
+     && ob->hosts_request_ocsp[1] == '\0'
+     )
+    {
+    /* Unchanged from default.  Use a safer one under DANE */
+    request_ocsp = TRUE;
+    ob->hosts_request_ocsp = US"${if or { {= {0}{$tls_out_tlsa_usage}} "
+                                     "   {= {4}{$tls_out_tlsa_usage}} } "
+                                " {*}{}}";
+    }
+# endif
+
   if ((require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
     NULL, host->name, host->address, NULL) == OK))
     request_ocsp = TRUE;
   else
-    {
 # ifdef EXPERIMENTAL_DANE
-    if (  tlsa_dnsa
-       && ob->hosts_request_ocsp[0] == '*'
-       && ob->hosts_request_ocsp[1] == '\0'
-       )
-      {
-      /* Unchanged from default.  Use a safer one under DANE */
-      request_ocsp = TRUE;
-      ob->hosts_request_ocsp = US"${if or { {= {0}{$tls_out_tlsa_usage}} "
-                                       "   {= {4}{$tls_out_tlsa_usage}} } "
-                                  " {*}{}}";
-      }
-    else
+    if (!request_ocsp)
 # endif
       request_ocsp = verify_check_this_host(&ob->hosts_request_ocsp,
          NULL, host->name, host->address, NULL) == OK;
-    }
   }
 #endif
 
@@ -1895,8 +1912,8 @@ does OCSP stapling we will get the callback (set in tls_init()) */
 if (request_ocsp)
   {
   const uschar * s;
-  if (  (s = ob->hosts_require_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage")
-     || (s = ob->hosts_request_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage")
+  if (  ((s = ob->hosts_require_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage"))
+     || ((s = ob->hosts_request_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage"))
      )
     {  /* Re-eval now $tls_out_tlsa_usage is populated.  If
        this means we avoid the OCSP request, we wasted the setup