recipient verify callout
[exim.git] / src / src / verify.c
index d85ef3b4f16d12e4d70cd9ee5119f9e63524b901..e39b55db89b129beeb6caeb89bc6a1772eb1f4b5 100644 (file)
@@ -575,9 +575,10 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     deliver_domain = addr->domain;
     transport_name = addr->transport->name;
 
-    if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
-            US"callout") ||
-        !smtp_get_port(tf->port, addr, &port, US"callout"))
+    if (  !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
+            US"callout")
+       || !smtp_get_port(tf->port, addr, &port, US"callout")
+       )
       log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
         addr->message);
 
@@ -588,35 +589,6 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 
     HDEBUG(D_verify) debug_printf("interface=%s port=%d\n", interface, port);
 
-#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
-      {
-      int rc;
-
-      tls_out.dane_verified = FALSE;
-      tls_out.tlsa_usage = 0;
-
-      dane_required =
-       verify_check_given_host(&ob->hosts_require_dane, host) == OK;
-
-      if (host->dnssec == DS_YES)
-       {
-       if(  dane_required
-         || verify_check_given_host(&ob->hosts_try_dane, host) == OK
-         )
-         if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
-           return rc;
-       }
-      else if (dane_required)
-       {
-       log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
-       return FAIL;
-       }
-
-      if (dane)
-       ob->tls_tempfail_tryclear = FALSE;
-      }
-#endif  /*DANE*/
-
     /* Set up the buffer for reading SMTP response packets. */
 
     inblock.buffer = inbuffer;
@@ -653,6 +625,36 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       continue;
       }
 
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+      {
+      int rc;
+
+      tls_out.dane_verified = FALSE;
+      tls_out.tlsa_usage = 0;
+
+      dane_required =
+       verify_check_given_host(&ob->hosts_require_dane, host) == OK;
+
+      if (host->dnssec == DS_YES)
+       {
+       if(  (  dane_required
+            || verify_check_given_host(&ob->hosts_try_dane, host) == OK
+            )
+         && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK
+         )
+         return rc;
+       }
+      else if (dane_required)
+       {
+       log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
+       return FAIL;
+       }
+
+      if (dane)
+       ob->tls_tempfail_tryclear = FALSE;
+      }
+#endif  /*DANE*/
+
     /* Expand the helo_data string to find the host name to use. */
 
     if (tf->helo_data != NULL)
@@ -918,6 +920,25 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
         }
       }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    else if (  addr->p.utf8
+           && !(  esmtp
+               && (  regex_UTF8
+                  || ( (regex_UTF8 = regex_must_compile(
+                         US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE)),
+                     TRUE
+                  )  )
+               && pcre_exec(regex_UTF8, NULL, CS responsebuffer,
+                   Ustrlen(responsebuffer), 0, PCRE_EOPT, NULL, 0) >= 0
+           )   )
+      {
+      HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
+      errno = ERRNO_UTF8_FWD;
+      setflag(addr, af_verify_nsfail);
+      done = FALSE;
+      }
+#endif
+
     /* If we haven't authenticated, but are required to, give up. */
     /* Try to AUTH */
 
@@ -935,7 +956,13 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       ( (addr->auth_sndr = client_authenticated_sender),
 
     /* Send the MAIL command */
-        (smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>%s\r\n",
+        (smtp_write_command(&outblock, FALSE,
+#ifdef EXPERIMENTAL_INTERNATIONAL
+         addr->p.utf8
+         ? "MAIL FROM:<%s>%s SMTPUTF8\r\n"
+         :
+#endif
+           "MAIL FROM:<%s>%s\r\n",
           from_address, responsebuffer) >= 0)
       )  &&
 
@@ -1020,7 +1047,13 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
             smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
               '2', callout) &&
 
-            smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>\r\n",
+            smtp_write_command(&outblock, FALSE,
+#ifdef EXPERIMENTAL_INTERNATIONAL
+             addr->p.utf8
+             ? "MAIL FROM:<%s> SMTPUTF8\r\n"
+             :
+#endif
+               "MAIL FROM:<%s>\r\n",
               from_address) >= 0 &&
             smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
               '2', callout);
@@ -1144,6 +1177,21 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
         HDEBUG(D_verify) debug_printf("SMTP timeout\n");
         send_quit = FALSE;
         }
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      else if (errno == ERRNO_UTF8_FWD)
+       {
+       extern int acl_where;   /* src/acl.c */
+       errno = 0;
+       addr->message = string_sprintf(
+           "response to \"%s\" from %s [%s] did not include SMTPUTF8",
+            big_buffer, host->name, host->address);
+        addr->user_message = acl_where == ACL_WHERE_RCPT
+         ? US"533 mailbox name not allowed"
+         : US"550 mailbox unavailable";
+       yield = FAIL;
+       done = TRUE;
+       }
+#endif
       else if (errno == 0)
         {
         if (*responsebuffer == 0) Ustrcpy(responsebuffer, US"connection dropped");