UTF8: MSA downconversions
[exim.git] / src / src / verify.c
index e39b55db89b129beeb6caeb89bc6a1772eb1f4b5..28013fa35c152da357f17b643392f653b8c8b03d 100644 (file)
@@ -173,6 +173,9 @@ dbdata_callout_cache new_domain_record;
 dbdata_callout_cache_address new_address_record;
 host_item *host;
 time_t callout_start_time;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+BOOL utf8_offered = FALSE;
+#endif
 
 new_domain_record.result = ccache_unknown;
 new_domain_record.postmaster_result = ccache_unknown;
@@ -921,22 +924,35 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       }
 
 #ifdef EXPERIMENTAL_INTERNATIONAL
-    else if (  addr->p.utf8
+    else if (  addr->prop.utf8_msg
+           && !addr->prop.utf8_downcvt
            && !(  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
-           )   )
+               && (  (utf8_offered = pcre_exec(regex_UTF8, NULL,
+                           CS responsebuffer, Ustrlen(responsebuffer),
+                           0, PCRE_EOPT, NULL, 0) >= 0)
+                  || addr->prop.utf8_downcvt_maybe
+           )   )  )
       {
       HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
       errno = ERRNO_UTF8_FWD;
       setflag(addr, af_verify_nsfail);
       done = FALSE;
       }
+    else if (  addr->prop.utf8_msg
+           && (addr->prop.utf8_downcvt || !utf8_offered)
+           && (from_address = string_address_utf8_to_alabel(from_address,
+                                     &addr->message), addr->message)
+           )
+      {
+      errno = ERRNO_EXPANDFAIL;
+      setflag(addr, af_verify_nsfail);
+      done = FALSE;
+      }
 #endif
 
     /* If we haven't authenticated, but are required to, give up. */
@@ -958,7 +974,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     /* Send the MAIL command */
         (smtp_write_command(&outblock, FALSE,
 #ifdef EXPERIMENTAL_INTERNATIONAL
-         addr->p.utf8
+         addr->prop.utf8_msg
          ? "MAIL FROM:<%s>%s SMTPUTF8\r\n"
          :
 #endif
@@ -1049,7 +1065,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 
             smtp_write_command(&outblock, FALSE,
 #ifdef EXPERIMENTAL_INTERNATIONAL
-             addr->p.utf8
+             addr->prop.utf8_msg
              ? "MAIL FROM:<%s> SMTPUTF8\r\n"
              :
 #endif
@@ -1662,7 +1678,7 @@ if (addr != vaddr)
   vaddr->user_message = addr->user_message;
   vaddr->basic_errno = addr->basic_errno;
   vaddr->more_errno = addr->more_errno;
-  vaddr->p.address_data = addr->p.address_data;
+  vaddr->prop.address_data = addr->prop.address_data;
   copyflag(vaddr, addr, af_pass_message);
   }
 return yield;
@@ -1923,8 +1939,8 @@ while (addr_new != NULL)
 
   /* Just in case some router parameter refers to it. */
 
-  return_path = (addr->p.errors_address != NULL)?
-    addr->p.errors_address : sender_address;
+  return_path = (addr->prop.errors_address != NULL)?
+    addr->prop.errors_address : sender_address;
 
   /* Split the address into domain and local part, handling the %-hack if
   necessary, and then route it. While routing a sender address, set
@@ -2217,7 +2233,7 @@ while (addr_new != NULL)
       /* If we have carried on to verify a child address, we want the value
       of $address_data to be that of the child */
 
-      vaddr->p.address_data = addr->p.address_data;
+      vaddr->prop.address_data = addr->prop.address_data;
       yield = OK;
       goto out;
       }
@@ -2249,8 +2265,8 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
 
     fprintf(f, "%s", CS addr->address);
 #ifdef EXPERIMENTAL_SRS
-    if(addr->p.srs_sender)
-      fprintf(f, "    [srs = %s]", addr->p.srs_sender);
+    if(addr->prop.srs_sender)
+      fprintf(f, "    [srs = %s]", addr->prop.srs_sender);
 #endif
 
     /* If the address is a duplicate, show something about it. */