Fix cert-try-verify when denied by event action
[exim.git] / src / src / tls-openssl.c
index 25d523274fd1b39b8f08fc42e25f86403d3d35c8..fe1b208ac5b2e4d708b913e2f466e11733ad0450 100644 (file)
@@ -294,8 +294,11 @@ verify_callback(int state, X509_STORE_CTX *x509ctx,
 {
 X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
 int depth = X509_STORE_CTX_get_error_depth(x509ctx);
-uschar * ev;
 static uschar txt[256];
+#ifdef EXPERIMENTAL_EVENT
+uschar * ev;
+uschar * yield;
+#endif
 
 X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
 
@@ -305,7 +308,6 @@ if (state == 0)
     depth,
     X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509ctx)),
     txt);
-  tlsp->certificate_verified = FALSE;
   *calledp = TRUE;
   if (!*optionalp)
     {
@@ -335,13 +337,15 @@ else if (depth != 0)
   if (ev)
     {
     tlsp->peercert = X509_dup(cert);
-    if (event_raise(ev, US"tls:cert", string_sprintf("%d", depth)) == DEFER)
+    if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth))))
       {
       log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
-                             "depth=%d cert=%s", depth, txt);
-      tlsp->certificate_verified = FALSE;
+                             "depth=%d cert=%s: %s", depth, txt, yield);
       *calledp = TRUE;
-      return 0;                            /* reject */
+      if (!*optionalp)
+       return 0;                           /* reject */
+      DEBUG(D_tls) debug_printf("Event-action verify failure overridden "
+       "(host in tls_try_verify_hosts)\n");
       }
     X509_free(tlsp->peercert);
     tlsp->peercert = NULL;
@@ -386,7 +390,11 @@ else
       {
       log_write(0, LOG_MAIN,
        "SSL verify error: certificate name mismatch: \"%s\"\n", txt);
-      return 0;                                /* reject */
+      *calledp = TRUE;
+      if (!*optionalp)
+       return 0;                           /* reject */
+      DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
+       "tls_try_verify_hosts)\n");
       }
     }
 # else
@@ -394,7 +402,11 @@ else
       {
       log_write(0, LOG_MAIN,
        "SSL verify error: certificate name mismatch: \"%s\"\n", txt);
-      return 0;                                /* reject */
+      *calledp = TRUE;
+      if (!*optionalp)
+       return 0;                           /* reject */
+      DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
+       "tls_try_verify_hosts)\n");
       }
 # endif
 #endif /*EXPERIMENTAL_CERTNAMES*/
@@ -402,13 +414,15 @@ else
 #ifdef EXPERIMENTAL_EVENT
   ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
   if (ev)
-    if (event_raise(ev, US"tls:cert", US"0") == DEFER)
+    if ((yield = event_raise(ev, US"tls:cert", US"0")))
       {
       log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
-                             "depth=0 cert=%s", txt);
-      tlsp->certificate_verified = FALSE;
+                             "depth=0 cert=%s: %s", txt, yield);
       *calledp = TRUE;
-      return 0;                            /* reject */
+      if (!*optionalp)
+       return 0;                           /* reject */
+      DEBUG(D_tls) debug_printf("Event-action verify failure overridden "
+       "(host in tls_try_verify_hosts)\n");
       }
 #endif
 
@@ -446,6 +460,7 @@ X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
 static uschar txt[256];
 #ifdef EXPERIMENTAL_EVENT
 int depth = X509_STORE_CTX_get_error_depth(x509ctx);
+uschar * yield;
 #endif
 
 X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
@@ -457,11 +472,11 @@ tls_out.peercert = X509_dup(cert);
 #ifdef EXPERIMENTAL_EVENT
   if (client_static_cbinfo->event_action)
     {
-    if (event_raise(client_static_cbinfo->event_action,
-                   US"tls:cert", string_sprintf("%d", depth)) == DEFER)
+    if ((yield = event_raise(client_static_cbinfo->event_action,
+                   US"tls:cert", string_sprintf("%d", depth))))
       {
       log_write(0, LOG_MAIN, "DANE verify denied by event-action: "
-                             "depth=%d cert=%s", depth, txt);
+                             "depth=%d cert=%s: %s", depth, txt, yield);
       tls_out.certificate_verified = FALSE;
       return 0;                            /* reject */
       }