Fix delivery $host in client authenticator in verify/callout. Bug 1476
[exim.git] / src / src / verify.c
index 39f546ed6a7ab072020c410cf4ce9c25d86dc26c..b1b9f29a449ce232a7655a750aa57faa1ec9832d 100644 (file)
@@ -373,10 +373,13 @@ if (!addr->transport)
   {
   HDEBUG(D_verify) debug_printf("cannot callout via null transport\n");
   }
+else if (Ustrcmp(addr->transport->driver_name, "smtp") != 0)
+  log_write(0, LOG_MAIN|LOG_PANIC|LOG_CONFIG_FOR, "callout transport '%s': %s is non-smtp",
+    addr->transport->name, addr->transport->driver_name);
 else
   {
   smtp_transport_options_block *ob =
-    (smtp_transport_options_block *)(addr->transport->options_block);
+    (smtp_transport_options_block *)addr->transport->options_block;
 
   /* The information wasn't available in the cache, so we have to do a real
   callout and save the result in the cache for next time, unless no_cache is set,
@@ -521,9 +524,6 @@ else
       else active_hostname = s;
       }
 
-    deliver_host = deliver_host_address = NULL;
-    deliver_domain = save_deliver_domain;
-
     /* Wait for initial response, and send HELO. The smtp_write_command()
     function leaves its command in big_buffer. This is used in error responses.
     Initialize it in case the connection is rejected. */
@@ -633,16 +633,12 @@ else
        /* STARTTLS accepted or ssl-on-connect: try to negotiate a TLS session. */
       else
         {
-        int rc = tls_client_start(inblock.sock, host, addr,
-        ob->tls_certificate, ob->tls_privatekey,
-        ob->tls_sni,
-        ob->tls_verify_certificates, ob->tls_crl,
-        ob->tls_require_ciphers,
-#ifdef EXPERIMENTAL_OCSP
-        ob->hosts_require_ocsp,
-#endif
-        ob->tls_dh_min_bits, callout,
-         ob->tls_verify_hosts, ob->tls_try_verify_hosts);
+       int oldtimeout = ob->command_timeout;
+       int rc;
+
+       ob->command_timeout = callout;
+        rc = tls_client_start(inblock.sock, host, addr, ob);
+       ob->command_timeout = oldtimeout;
 
         /* TLS negotiation failed; give an error.  Try in clear on a new connection,
            if the options permit it for this host. */
@@ -721,7 +717,6 @@ else
     ;
     /* Clear down of the TLS, SMTP and TCP layers on error is handled below.  */
 
-
     /* Failure to accept HELO is cached; this blocks the whole domain for all
     senders. I/O errors and defer responses are not cached. */
 
@@ -759,6 +754,9 @@ else
       smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
         '2', callout);
 
+    deliver_host = deliver_host_address = NULL;
+    deliver_domain = save_deliver_domain;
+
     /* If the host does not accept MAIL FROM:<>, arrange to cache this
     information, but again, don't record anything for an I/O error or a defer. Do
     not cache rejections of MAIL when a non-empty sender has been used, because
@@ -1573,13 +1571,7 @@ if (address[0] == 0) return OK;
 they're used in the context of a transport used by verification. Reset them
 at exit from this routine. */
 
-modify_variable(US"tls_bits",                 &tls_out.bits);
-modify_variable(US"tls_certificate_verified", &tls_out.certificate_verified);
-modify_variable(US"tls_cipher",               &tls_out.cipher);
-modify_variable(US"tls_peerdn",               &tls_out.peerdn);
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
-modify_variable(US"tls_sni",                  &tls_out.sni);
-#endif
+tls_modify_variables(&tls_out);
 
 /* Save a copy of the sender address for re-instating if we change it to <>
 while verifying a sender address (a nice bit of self-reference there). */
@@ -1752,8 +1744,20 @@ while (addr_new != NULL)
                   string_is_ip_address(host->name, NULL) != 0)
                 (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE);
               else
+               {
+               uschar * d_request = NULL, * d_require = NULL;
+               if (Ustrcmp(addr->transport->driver_name, "smtp") == 0)
+                 {
+                 smtp_transport_options_block * ob =
+                     (smtp_transport_options_block *)
+                       addr->transport->options_block;
+                 d_request = ob->dnssec_request_domains;
+                 d_require = ob->dnssec_require_domains;
+                 }
+
                 (void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
-                  &canonical_name, NULL);
+                 d_request, d_require, &canonical_name, NULL);
+               }
               }
             }
           }
@@ -2038,14 +2042,7 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
 the -bv or -bt case). */
 
 out:
-
-modify_variable(US"tls_bits",                 &tls_in.bits);
-modify_variable(US"tls_certificate_verified", &tls_in.certificate_verified);
-modify_variable(US"tls_cipher",               &tls_in.cipher);
-modify_variable(US"tls_peerdn",               &tls_in.peerdn);
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
-modify_variable(US"tls_sni",                  &tls_in.sni);
-#endif
+tls_modify_variables(&tls_in);
 
 return yield;
 }
@@ -3556,7 +3553,7 @@ revadd[0] = 0;
 
 /* In case this is the first time the DNS resolver is being used. */
 
-dns_init(FALSE, FALSE);
+dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */
 
 /* Loop through all the domains supplied, until something matches */