Merge branch 'SMTPUTF8_1516'. Bug 1516
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 12 Apr 2015 23:18:54 +0000 (00:18 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 12 Apr 2015 23:18:54 +0000 (00:18 +0100)
This adds limited support for the ESMTP option SMTPUTF8
under the EXPERIMENTAL_INTERNATIONAL compile define

81 files changed:
doc/doc-txt/experimental-spec.txt
src/OS/Makefile-Base
src/scripts/MakeLinks
src/src/EDITME
src/src/acl.c
src/src/config.h.defaults
src/src/deliver.c
src/src/dns.c
src/src/exim.c
src/src/expand.c
src/src/filter.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/macros.h
src/src/parse.c
src/src/queue.c
src/src/rda.c
src/src/readconf.c
src/src/receive.c
src/src/route.c
src/src/routers/accept.c
src/src/routers/dnslookup.c
src/src/routers/ipliteral.c
src/src/routers/iplookup.c
src/src/routers/manualroute.c
src/src/routers/queryprogram.c
src/src/routers/redirect.c
src/src/routers/rf_change_domain.c
src/src/routers/rf_get_errors_address.c
src/src/routers/rf_get_munge_headers.c
src/src/routers/rf_queue_add.c
src/src/sieve.c
src/src/smtp_in.c
src/src/spool_in.c
src/src/spool_out.c
src/src/structs.h
src/src/transport.c
src/src/transports/smtp.c
src/src/utf8.c [new file with mode: 0644]
src/src/verify.c
test/confs/4200 [new file with mode: 0644]
test/confs/4201 [new file with mode: 0644]
test/confs/4211 [new file with mode: 0644]
test/confs/4221 [new file with mode: 0644]
test/dnszones-src/db.test.ex
test/log/4201 [new file with mode: 0644]
test/log/4211 [new file with mode: 0644]
test/log/4221 [new file with mode: 0644]
test/mail/4201.यहलोगहिन्दीक्योंनहींबोलसकतेहैं [new file with mode: 0644]
test/mail/4211.यहलोगहिन्दीक्योंनहींबोलसकतेहैं [new file with mode: 0644]
test/mail/4221.यहलोगहिन्दीक्योंनहींबोलसकतेहैं [new file with mode: 0644]
test/rejectlog/4201 [new file with mode: 0644]
test/rejectlog/4211 [new file with mode: 0644]
test/rejectlog/4221 [new file with mode: 0644]
test/runtest
test/scripts/4200-International/4200 [new file with mode: 0644]
test/scripts/4200-International/4201 [new file with mode: 0644]
test/scripts/4200-International/REQUIRES [new file with mode: 0644]
test/scripts/4210-GnuTLS-International/4211 [new file with mode: 0644]
test/scripts/4210-GnuTLS-International/REQUIRES [new file with mode: 0644]
test/scripts/4220-OpenSSL-International/4221 [new file with mode: 0644]
test/scripts/4220-OpenSSL-International/REQUIRES [new file with mode: 0644]
test/stderr/0275
test/stderr/0278
test/stderr/0361
test/stderr/0386
test/stderr/0402
test/stderr/0403
test/stderr/0404
test/stderr/0408
test/stderr/0487
test/stderr/2600
test/stderr/5004
test/stderr/5005
test/stderr/5006
test/stdout/0405
test/stdout/4200 [new file with mode: 0644]
test/stdout/4201 [new file with mode: 0644]
test/stdout/4211 [new file with mode: 0644]
test/stdout/4221 [new file with mode: 0644]

index e6e066c..819b47f 100644 (file)
@@ -1270,6 +1270,51 @@ in combination with EXPERIMENTAL_EVENT), and a new variable
 $tls_out_tlsa_usage (detailed above).
 
 
+
+SMTPUTF8
+------------------------------------------------------------
+Internationalised mail name handling.
+RFCs 6530, 6533, 5890
+
+Compile with EXPERIMENTAL_INTERNATIONAL and libidn.
+
+New main config option smtputf8_advertise_hosts, default '*',
+a host list.  If this matches the sending host and
+accept_8bitmime is true (the default) then the ESMTP option
+SMTPUTF8 will be advertised.
+
+If the sender specifies the SMTPUTF8 option on a MAIL command
+international handling for the message is enabled and
+the expansion variable $message_smtputf8 will have value TRUE.
+
+The option allow_utf8_domains is set to true for this
+message. All DNS lookups are converted to a-label form
+whatever the setting of allow_utf8_domains.
+
+Both localparts and domain are maintained as the original
+utf8 form internally; any matching or regex use will
+require appropriate care.  Filenames created, eg. by
+the appendfile transport, will have utf8 name.
+
+Helo names sent by the smtp transport will have any utf8
+components expanded to a-label form.
+
+Log lines and Received-by: header lines will aquire a "utf8"
+prefix on the protocol element, eg. utf8esmtp.
+
+New expansion operators:
+       ${utf8_domain_to_alabel:str}
+       ${utf8_domain_from_alabel:str}
+       ${utf8_localpart_to_alabel:str}
+       ${utf8_localpart_from_alabel:str}
+
+Known issues:
+ - Currently LMTP is not supported.
+ - DSN unitext handling is not present
+ - no provision for converting logging from UTF-8
+ - VRFY and EXPN not handled
+ - MSA mode not handled (!)
+
 --------------------------------------------------------------
 End of file
 --------------------------------------------------------------
index 38d7198..63646e2 100644 (file)
@@ -295,7 +295,7 @@ convert4r4: Makefile ../src/convert4r4.src
 
 OBJ_WITH_CONTENT_SCAN = malware.o mime.o regex.o spam.o spool_mbox.o
 OBJ_WITH_OLD_DEMIME = demime.o
-OBJ_EXPERIMENTAL = bmi_spam.o spf.o srs.o dcc.o dmarc.o dane.o
+OBJ_EXPERIMENTAL = bmi_spam.o spf.o srs.o dcc.o dmarc.o dane.o utf8.o
 
 # Targets for final binaries; the main one has a build number which is
 # updated each time. We don't bother with that for the auxiliaries.
@@ -604,6 +604,7 @@ dcc.o:           $(HDRS) dcc.h dcc.c
 dmarc.o:         $(HDRS) dmarc.h dmarc.c
 spf.o:           $(HDRS) spf.h spf.c
 srs.o:           $(HDRS) srs.h srs.c
+utf8.o:                 $(HDRS) utf8.c
 
 # The module containing tables of available lookups, routers, auths, and
 # transports must be rebuilt if any of them are. However, because the makefiles
index f68fd6f..f9cc27c 100755 (executable)
@@ -276,6 +276,7 @@ ln -s ../src/dane.c            dane.c
 ln -s ../src/dane-gnu.c        dane-gnu.c
 ln -s ../src/dane-openssl.c    dane-openssl.c
 ln -s ../src/danessl.h         danessl.h
+ln -s ../src/utf8.c            utf8.c
 
 
 # End of MakeLinks
index d48f268..4260335 100644 (file)
@@ -497,6 +497,11 @@ EXIM_MONITOR=eximon.bin
 # Uncomment the following line to add SOCKS support
 # EXPERIMENTAL_SOCKS=yes
 
+# Uncomment the following to add Internationalisation features. You need to
+# have the IDN library installed.
+EXPERIMENTAL_INTERNATIONAL=yes
+LDFLAGS += -lidn
+
 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
 ###############################################################################
index ea078f6..3f513c3 100644 (file)
@@ -2079,6 +2079,9 @@ else if (verify_sender_address != NULL)
     uschar *save_address_data = deliver_address_data;
 
     sender_vaddr = deliver_make_addr(verify_sender_address, TRUE);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    sender_vaddr->prop.utf8 = message_smtputf8;
+#endif
     if (no_details) setflag(sender_vaddr, af_sverify_told);
     if (verify_sender_address[0] != 0)
       {
@@ -2135,7 +2138,7 @@ else if (verify_sender_address != NULL)
 
   /* Put the sender address_data value into $sender_address_data */
 
-  sender_address_data = sender_vaddr->p.address_data;
+  sender_address_data = sender_vaddr->prop.address_data;
   }
 
 /* A recipient address just gets a straightforward verify; again we must handle
@@ -2165,7 +2168,7 @@ else
   if (testflag((&addr2), af_pass_message)) acl_temp_details = TRUE;
 
   /* Make $address_data visible */
-  deliver_address_data = addr2.p.address_data;
+  deliver_address_data = addr2.prop.address_data;
   }
 
 /* We have a result from the relevant test. Handle defer overrides first. */
@@ -2184,13 +2187,9 @@ sender_verified_failed to the address item that actually failed. */
 if (rc != OK && verify_sender_address != NULL)
   {
   if (rc != DEFER)
-    {
     *log_msgptr = *user_msgptr = US"Sender verify failed";
-    }
   else if (*basic_errno != ERRNO_CALLOUTDEFER)
-    {
     *log_msgptr = *user_msgptr = US"Could not complete sender verify";
-    }
   else
     {
     *log_msgptr = US"Could not complete sender verify callout";
@@ -4382,6 +4381,9 @@ if (where == ACL_WHERE_RCPT)
     *log_msgptr = US"defer in percent_hack_domains check";
     return DEFER;
     }
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  addr->prop.utf8 = message_smtputf8;
+#endif
   deliver_domain = addr->domain;
   deliver_localpart = addr->local_part;
   }
index ac4994a..d31f115 100644 (file)
@@ -171,6 +171,7 @@ it's a default value. */
 #define EXPERIMENTAL_DCC
 #define EXPERIMENTAL_DMARC
 #define EXPERIMENTAL_EVENT
+#define EXPERIMENTAL_INTERNATIONAL
 #define EXPERIMENTAL_PROXY
 #define EXPERIMENTAL_REDIS
 #define EXPERIMENTAL_SOCKS
index 1cdecc6..85a379c 100644 (file)
@@ -149,9 +149,9 @@ else
   }
 
 deliver_recipients = addr;
-deliver_address_data = addr->p.address_data;
-deliver_domain_data = addr->p.domain_data;
-deliver_localpart_data = addr->p.localpart_data;
+deliver_address_data = addr->prop.address_data;
+deliver_domain_data = addr->prop.domain_data;
+deliver_localpart_data = addr->prop.localpart_data;
 
 /* These may be unset for multiple addresses */
 
@@ -825,8 +825,8 @@ if ((log_extra_selector & LX_sender_on_delivery) != 0  ||  msg)
   s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
 
 #ifdef EXPERIMENTAL_SRS
-if(addr->p.srs_sender)
-  s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->p.srs_sender, US">");
+if(addr->prop.srs_sender)
+  s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->prop.srs_sender, US">");
 #endif
 
 /* You might think that the return path must always be set for a successful
@@ -1093,7 +1093,7 @@ if (addr->return_file >= 0 && addr->return_filename != NULL)
     /* Handle returning options, but only if there is an address to return
     the text to. */
 
-    if (sender_address[0] != 0 || addr->p.errors_address != NULL)
+    if (sender_address[0] != 0 || addr->prop.errors_address != NULL)
       {
       if (tb->return_output)
         {
@@ -1310,7 +1310,7 @@ else
 
   if (!testflag(addr, af_ignore_error) &&
       (addr->special_action == SPECIAL_FREEZE ||
-        (sender_address[0] == 0 && addr->p.errors_address == NULL)
+        (sender_address[0] == 0 && addr->prop.errors_address == NULL)
       ))
     {
     frozen_info = (addr->special_action == SPECIAL_FREEZE)? US"" :
@@ -1810,11 +1810,11 @@ transport_instance *tp = addr->transport;
 /* Set up the return path from the errors or sender address. If the transport
 has its own return path setting, expand it and replace the existing value. */
 
-if(addr->p.errors_address != NULL)
-  return_path = addr->p.errors_address;
+if(addr->prop.errors_address != NULL)
+  return_path = addr->prop.errors_address;
 #ifdef EXPERIMENTAL_SRS
-else if(addr->p.srs_sender != NULL)
-  return_path = addr->p.srs_sender;
+else if(addr->prop.srs_sender != NULL)
+  return_path = addr->prop.srs_sender;
 #endif
 else
   return_path = sender_address;
@@ -2426,9 +2426,9 @@ while (addr_local != NULL)
         (addr->flags & (af_pfr|af_file)) == (next->flags & (af_pfr|af_file)) &&
         (!uses_lp  || Ustrcmp(next->local_part, addr->local_part) == 0) &&
         (!uses_dom || Ustrcmp(next->domain, addr->domain) == 0) &&
-        same_strings(next->p.errors_address, addr->p.errors_address) &&
-        same_headers(next->p.extra_headers, addr->p.extra_headers) &&
-        same_strings(next->p.remove_headers, addr->p.remove_headers) &&
+        same_strings(next->prop.errors_address, addr->prop.errors_address) &&
+        same_headers(next->prop.extra_headers, addr->prop.extra_headers) &&
+        same_strings(next->prop.remove_headers, addr->prop.remove_headers) &&
         same_ugid(tp, addr, next) &&
         ((addr->host_list == NULL && next->host_list == NULL) ||
          (addr->host_list != NULL && next->host_list != NULL &&
@@ -3950,13 +3950,13 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
     if (  (multi_domain || Ustrcmp(next->domain, addr->domain) == 0)
        && tp == next->transport
        && same_hosts(next->host_list, addr->host_list)
-       && same_strings(next->p.errors_address, addr->p.errors_address)
-       && same_headers(next->p.extra_headers, addr->p.extra_headers)
+       && same_strings(next->prop.errors_address, addr->prop.errors_address)
+       && same_headers(next->prop.extra_headers, addr->prop.extra_headers)
        && same_ugid(tp, next, addr)
-       && (  next->p.remove_headers == addr->p.remove_headers
-         || (  next->p.remove_headers != NULL
-            && addr->p.remove_headers != NULL
-            && Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0
+       && (  next->prop.remove_headers == addr->prop.remove_headers
+         || (  next->prop.remove_headers
+            && addr->prop.remove_headers
+            && Ustrcmp(next->prop.remove_headers, addr->prop.remove_headers) == 0
          )  )
        && (  !multi_domain
          || (  (
@@ -4000,11 +4000,11 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
   /* Compute the return path, expanding a new one if required. The old one
   must be set first, as it might be referred to in the expansion. */
 
-  if(addr->p.errors_address != NULL)
-    return_path = addr->p.errors_address;
+  if(addr->prop.errors_address != NULL)
+    return_path = addr->prop.errors_address;
 #ifdef EXPERIMENTAL_SRS
-  else if(addr->p.srs_sender != NULL)
-    return_path = addr->p.srs_sender;
+  else if(addr->prop.srs_sender != NULL)
+    return_path = addr->prop.srs_sender;
 #endif
   else
     return_path = sender_address;
@@ -5593,7 +5593,11 @@ if (process_recipients != RECIP_IGNORE)
       {
       recipient_item *r = recipients_list + i;
       address_item *new = deliver_make_addr(r->address, FALSE);
-      new->p.errors_address = r->errors_to;
+      new->prop.errors_address = r->errors_to;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      new->prop.utf8 = message_smtputf8;
+      DEBUG(D_deliver) if (message_smtputf8) debug_printf("utf8\n");
+#endif
 
       if (r->pno >= 0)
         new->onetime_parent = recipients_list[r->pno].address;
@@ -5602,7 +5606,8 @@ if (process_recipients != RECIP_IGNORE)
          to be passed on to other DSN enabled MTAs */
       new->dsn_flags = r->dsn_flags & rf_dsnflags;
       new->dsn_orcpt = r->orcpt;
-      DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s  flags: %d\n", new->dsn_orcpt, new->dsn_flags);
+      DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s  flags: %d\n",
+       new->dsn_orcpt, new->dsn_flags);
 
       switch (process_recipients)
         {
@@ -6189,8 +6194,8 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
 
     /* 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;
 
     /* If a router defers an address, add a retry item. Whether or not to
     use the local part in the key is a property of the router. */
@@ -6260,8 +6265,8 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
 
     if (addr_remote == addr &&
         addr->router->same_domain_copy_routing &&
-        addr->p.extra_headers == NULL &&
-        addr->p.remove_headers == NULL &&
+        addr->prop.extra_headers == NULL &&
+        addr->prop.remove_headers == NULL &&
         old_domain == addr->domain)
       {
       address_item **chain = &addr_route;
@@ -6288,7 +6293,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
         addr2->transport = addr->transport;
         addr2->host_list = addr->host_list;
         addr2->fallback_hosts = addr->fallback_hosts;
-        addr2->p.errors_address = addr->p.errors_address;
+        addr2->prop.errors_address = addr->prop.errors_address;
         copyflag(addr2, addr, af_hide_child | af_local_host_removed);
 
         DEBUG(D_deliver|D_route)
@@ -6660,29 +6665,36 @@ else if (!dont_deliver) retry_update(&addr_defer, &addr_failed, &addr_succeed);
 addr_dsntmp = addr_succeed;
 addr_senddsn = NULL;
 
-while(addr_dsntmp != NULL)
+while(addr_dsntmp)
   {
-  DEBUG(D_deliver)
-    debug_printf("DSN: processing router : %s\n", addr_dsntmp->router->name);
-
-  DEBUG(D_deliver)
-    debug_printf("DSN: processing successful delivery address: %s\n", addr_dsntmp->address);
-
   /* af_ignore_error not honored here. it's not an error */
-
-  DEBUG(D_deliver) debug_printf("DSN: Sender_address: %s\n", sender_address);
-  DEBUG(D_deliver) debug_printf("DSN: orcpt: %s  flags: %d\n", addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags);
-  DEBUG(D_deliver) debug_printf("DSN: envid: %s  ret: %d\n", dsn_envid, dsn_ret);
-  DEBUG(D_deliver) debug_printf("DSN: Final recipient: %s\n", addr_dsntmp->address);
-  DEBUG(D_deliver) debug_printf("DSN: Remote SMTP server supports DSN: %d\n", addr_dsntmp->dsn_aware);
+  DEBUG(D_deliver)
+    {
+    debug_printf("DSN: processing router : %s\n"
+      "DSN: processing successful delivery address: %s\n"
+      "DSN: Sender_address: %s\n"
+      "DSN: orcpt: %s  flags: %d\n"
+      "DSN: envid: %s  ret: %d\n"
+      "DSN: Final recipient: %s\n"
+      "DSN: Remote SMTP server supports DSN: %d\n",
+      addr_dsntmp->router->name,
+      addr_dsntmp->address,
+      sender_address,
+      addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags,
+      dsn_envid, dsn_ret,
+      addr_dsntmp->address,
+      addr_dsntmp->dsn_aware
+      );
+    }
 
   /* send report if next hop not DSN aware or a router flagged "last DSN hop"
      and a report was requested */
-  if (((addr_dsntmp->dsn_aware != dsn_support_yes) ||
-       ((addr_dsntmp->dsn_flags & rf_dsnlasthop) != 0))
-      &&
-      (((addr_dsntmp->dsn_flags & rf_dsnflags) != 0) &&
-        ((addr_dsntmp->dsn_flags & rf_notify_success) != 0)))
+  if (  (  addr_dsntmp->dsn_aware != dsn_support_yes
+       || addr_dsntmp->dsn_flags & rf_dsnlasthop
+        )
+     && addr_dsntmp->dsn_flags & rf_dsnflags
+     && addr_dsntmp->dsn_flags & rf_notify_success
+     )
     {
     /* copy and relink address_item and send report with all of them at once later */
     address_item *addr_next;
@@ -6692,14 +6704,12 @@ while(addr_dsntmp != NULL)
     addr_senddsn->next = addr_next;
     }
   else
-    {
-      DEBUG(D_deliver) debug_printf("DSN: *** NOT SENDING DSN SUCCESS Message ***\n"); 
-    }
+    DEBUG(D_deliver) debug_printf("DSN: not sending DSN success message\n"); 
 
   addr_dsntmp = addr_dsntmp->next;
   }
 
-if (addr_senddsn != NULL)
+if (addr_senddsn)
   {
   pid_t pid;
   int fd;
@@ -6854,10 +6864,10 @@ while (addr_failed != NULL)
   If neither of these cases obtains, something has gone wrong. Log the
   incident, but then ignore the error. */
 
-  if (sender_address[0] == 0 && addr_failed->p.errors_address == NULL)
+  if (sender_address[0] == 0 && addr_failed->prop.errors_address == NULL)
     {
-    if (!testflag(addr_failed, af_retry_timedout) &&
-        !testflag(addr_failed, af_ignore_error))
+    if (  !testflag(addr_failed, af_retry_timedout)
+       && !testflag(addr_failed, af_ignore_error))
       {
       log_write(0, LOG_MAIN|LOG_PANIC, "internal error: bounce message "
         "failure is neither frozen nor ignored (it's been ignored)");
@@ -6870,8 +6880,8 @@ while (addr_failed != NULL)
   mark the recipient done. */
 
   if (  testflag(addr_failed, af_ignore_error)
-     || (  ((addr_failed->dsn_flags & rf_dsnflags) != 0)
-        && ((addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure))
+     || (  addr_failed->dsn_flags & rf_dsnflags
+        && (addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure)
      )
     {
     addr = addr_failed;
@@ -6898,8 +6908,8 @@ while (addr_failed != NULL)
 
   else
     {
-    bounce_recipient = addr_failed->p.errors_address
-      ? addr_failed->p.errors_address : sender_address;
+    bounce_recipient = addr_failed->prop.errors_address
+      ? addr_failed->prop.errors_address : sender_address;
 
     /* Make a subprocess to send a message */
 
@@ -6934,8 +6944,8 @@ while (addr_failed != NULL)
 
       paddr = &addr_failed;
       for (addr = addr_failed; addr != NULL; addr = *paddr)
-        if (Ustrcmp(bounce_recipient, addr->p.errors_address
-             ? addr->p.errors_address : sender_address) == 0)
+        if (Ustrcmp(bounce_recipient, addr->prop.errors_address
+             ? addr->prop.errors_address : sender_address) == 0)
           {                          /* The same - dechain */
           *paddr = addr->next;
           *pmsgchain = addr;
@@ -7136,10 +7146,18 @@ wording. */
         }
 
       /* output machine readable part */
-      fprintf(f, "--%s\n"
-         "Content-type: message/delivery-status\n\n"
-         "Reporting-MTA: dns; %s\n",
-       bound, smtp_active_hostname);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      if (message_smtputf8)
+       fprintf(f, "--%s\n"
+           "Content-type: message/global-delivery-status\n\n"
+           "Reporting-MTA: dns; %s\n",
+         bound, smtp_active_hostname);
+      else
+#endif
+       fprintf(f, "--%s\n"
+           "Content-type: message/delivery-status\n\n"
+           "Reporting-MTA: dns; %s\n",
+         bound, smtp_active_hostname);
 
       if (dsn_envid)
        {
@@ -7214,9 +7232,16 @@ wording. */
             }
           }
   
-      fputs(topt & topt_no_body ? "Content-type: text/rfc822-headers\n\n"
-                               : "Content-type: message/rfc822\n\n",
-           f);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      if (message_smtputf8)
+       fputs(topt & topt_no_body ? "Content-type: message/global-headers\n\n"
+                                 : "Content-type: message/global\n\n",
+             f);
+      else
+#endif
+       fputs(topt & topt_no_body ? "Content-type: text/rfc822-headers\n\n"
+                                 : "Content-type: message/rfc822\n\n",
+             f);
 
       fflush(f);
       transport_filter_argv = NULL;   /* Just in case */
@@ -7431,7 +7456,7 @@ else if (addr_defer != (address_item *)(+1))
         DEBUG(D_deliver) debug_printf("one_time: adding %s in place of %s\n",
           otaddr->address, otaddr->parent->address);
         receive_add_recipient(otaddr->address, t);
-        recipients_list[recipients_count-1].errors_to = otaddr->p.errors_address;
+        recipients_list[recipients_count-1].errors_to = otaddr->prop.errors_address;
         tree_add_nonrecipient(otaddr->parent->address);
         update_spool = TRUE;
         }
@@ -7443,7 +7468,7 @@ else if (addr_defer != (address_item *)(+1))
 
     if (sender_address[0] != 0)
       {
-      if (addr->p.errors_address == NULL)
+      if (addr->prop.errors_address == NULL)
         {
         if (Ustrstr(recipients, sender_address) == NULL)
           recipients = string_sprintf("%s%s%s", recipients,
@@ -7451,9 +7476,9 @@ else if (addr_defer != (address_item *)(+1))
         }
       else
         {
-        if (Ustrstr(recipients, addr->p.errors_address) == NULL)
+        if (Ustrstr(recipients, addr->prop.errors_address) == NULL)
           recipients = string_sprintf("%s%s%s", recipients,
-            (recipients[0] == 0)? "" : ",", addr->p.errors_address);
+            (recipients[0] == 0)? "" : ",", addr->prop.errors_address);
         }
       }
     }
@@ -7857,6 +7882,11 @@ if (!regex_PRDR) regex_PRDR =
   regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE);
 #endif
 
+#ifdef SUPPORT_TLS
+if (!regex_UTF8) regex_UTF8 =
+  regex_must_compile(US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE);
+#endif
+
 if (!regex_DSN) regex_DSN  =
   regex_must_compile(US"\\n250[\\s\\-]DSN(\\s|\\n|$)", FALSE, TRUE);
 
index a2f4309..6f75386 100644 (file)
@@ -576,6 +576,23 @@ if (previous != NULL)
   return previous->data.val;
   }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+/* Convert all names to a-label form before doing lookup */
+  {
+  uschar * alabel;
+  uschar * errstr = NULL;
+  if ((alabel = string_domain_utf8_to_alabel(name, &errstr)), errstr)
+    {
+    DEBUG(D_dns)
+      debug_printf("DNS name '%s' utf8 conversion to alabel failed: %s\n", name,
+        errstr);
+    host_find_failed_syntax = TRUE;
+    return DNS_NOMATCH;
+    }
+  name = alabel;
+  }
+#endif
+
 /* If configured, check the hygene of the name passed to lookup. Otherwise,
 although DNS lookups may give REFUSED at the lower level, some resolvers
 turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
index 54725ef..cae2964 100644 (file)
@@ -856,6 +856,9 @@ fprintf(f, "Support for:");
 #ifdef EXPERIMENTAL_SOCKS
   fprintf(f, " Experimental_SOCKS");
 #endif
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  fprintf(f, " Experimental_International");
+#endif
 fprintf(f, "\n");
 
 fprintf(f, "Lookups (built-in):");
@@ -1019,6 +1022,9 @@ DEBUG(D_any) do {
 #ifdef SUPPORT_TLS
   tls_version_report(f);
 #endif
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  utf8_version_report(f);
+#endif
 
   for (authi = auths_available; *authi->driver_name != '\0'; ++authi) {
     if (authi->version_report) {
@@ -2516,7 +2522,7 @@ for (i = 1; i < argc; i++)
 
     case 'f':
       {
-      int start, end;
+      int dummy_start, dummy_end;
       uschar *errmess;
       if (*argrest == 0)
         {
@@ -2524,9 +2530,7 @@ for (i = 1; i < argc; i++)
           { badarg = TRUE; break; }
         }
       if (*argrest == 0)
-        {
         sender_address = string_sprintf("");  /* Ensure writeable memory */
-        }
       else
         {
         uschar *temp = argrest + Ustrlen(argrest) - 1;
@@ -2534,8 +2538,15 @@ for (i = 1; i < argc; i++)
         if (temp >= argrest && *temp == '.') f_end_dot = TRUE;
         allow_domain_literals = TRUE;
         strip_trailing_dot = TRUE;
-        sender_address = parse_extract_address(argrest, &errmess, &start, &end,
-          &sender_address_domain, TRUE);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       allow_utf8_domains = TRUE;
+#endif
+        sender_address = parse_extract_address(argrest, &errmess,
+          &dummy_start, &dummy_end, &sender_address_domain, TRUE);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       message_smtputf8 =  string_is_utf8(sender_address);
+       allow_utf8_domains = FALSE;
+#endif
         allow_domain_literals = FALSE;
         strip_trailing_dot = FALSE;
         if (sender_address == NULL)
@@ -3702,6 +3713,10 @@ is equivalent to the ability to modify a setuid binary!
 This needs to happen before we read the main configuration. */
 init_lookup_list();
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+if (running_in_test_harness) smtputf8_advertise_hosts = NULL;
+#endif
+
 /* Read the main runtime configuration data; this gives up if there
 is a failure. It leaves the configuration file open so that the subsequent
 configuration data for delivery can be read if needed. */
@@ -5351,7 +5366,6 @@ while (more)
 
         if (recipients_max > 0 && ++rcount > recipients_max &&
             !extract_recipients)
-          {
           if (error_handling == ERRORS_STDERR)
             {
             fprintf(stderr, "exim: too many recipients\n");
@@ -5363,11 +5377,22 @@ while (more)
               moan_to_sender(ERRMESS_TOOMANYRECIP, NULL, NULL, stdin, TRUE)?
                 errors_sender_rc : EXIT_FAILURE;
             }
-          }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       {
+       BOOL b = allow_utf8_domains;
+       allow_utf8_domains = TRUE;
+#endif
         recipient =
           parse_extract_address(s, &errmess, &start, &end, &domain, FALSE);
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       if (string_is_utf8(recipient))
+         message_smtputf8 = TRUE;
+       else
+         allow_utf8_domains = b;
+       }
+#endif
         if (domain == 0 && !allow_unqualified_recipient)
           {
           recipient = NULL;
@@ -5467,9 +5492,7 @@ while (more)
       return_path = string_copy(sender_address);
       }
     else
-      {
       printf("Return-path = %s\n", (return_path[0] == 0)? US"<>" : return_path);
-      }
     printf("Sender      = %s\n", (sender_address[0] == 0)? US"<>" : sender_address);
 
     receive_add_recipient(
index 8a7a27e..ad97f6f 100644 (file)
@@ -168,7 +168,14 @@ static uschar *op_table_underscore[] = {
   US"quote_local_part",
   US"reverse_ip",
   US"time_eval",
-  US"time_interval"};
+  US"time_interval"
+#ifdef EXPERIMENTAL_INTERNATIONAL
+ ,US"utf8_domain_from_alabel",
+  US"utf8_domain_to_alabel",
+  US"utf8_localpart_from_alabel",
+  US"utf8_localpart_to_alabel"
+#endif
+  };
 
 enum {
   EOP_FROM_UTF8,
@@ -176,7 +183,14 @@ enum {
   EOP_QUOTE_LOCAL_PART,
   EOP_REVERSE_IP,
   EOP_TIME_EVAL,
-  EOP_TIME_INTERVAL };
+  EOP_TIME_INTERVAL
+#ifdef EXPERIMENTAL_INTERNATIONAL
+ ,EOP_UTF8_DOMAIN_FROM_ALABEL,
+  EOP_UTF8_DOMAIN_TO_ALABEL,
+  EOP_UTF8_LOCALPART_FROM_ALABEL,
+  EOP_UTF8_LOCALPART_TO_ALABEL
+#endif
+  };
 
 static uschar *op_table_main[] = {
   US"address",
@@ -549,6 +563,9 @@ static var_entry var_table[] = {
   { "message_id",          vtype_stringptr,   &message_id },
   { "message_linecount",   vtype_int,         &message_linecount },
   { "message_size",        vtype_int,         &message_size },
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  { "message_smtputf8",    vtype_bool,        &message_smtputf8 },
+#endif
 #ifdef WITH_CONTENT_SCAN
   { "mime_anomaly_level",  vtype_int,         &mime_anomaly_level },
   { "mime_anomaly_text",   vtype_stringptr,   &mime_anomaly_text },
@@ -6552,16 +6569,13 @@ while (*s != 0)
          if (bytes_left)
            {
            if ((c & 0xc0) != 0x80)
-             {
                    /* wrong continuation byte; invalidate all bytes */
              complete = 1; /* error */
-             }
            else
              {
              codepoint = (codepoint << 6) | (c & 0x3f);
              seq_buff[index++] = c;
              if (--bytes_left == 0)            /* codepoint complete */
-               {
                if(codepoint > 0x10FFFF)        /* is it too large? */
                  complete = -1;        /* error (RFC3629 limit) */
                else
@@ -6569,7 +6583,6 @@ while (*s != 0)
                  yield = string_cat(yield, &size, &ptr, seq_buff, seq_len);
                  index = 0;
                  }
-               }
              }
            }
          else  /* no bytes left: new sequence */
@@ -6612,13 +6625,75 @@ while (*s != 0)
            yield = string_cat(yield, &size, &ptr, UTF8_REPLACEMENT_CHAR, 1);
            }
          if ((complete == 1) && ((c & 0x80) == 0))
-           { /* ASCII character follows incomplete sequence */
+                       /* ASCII character follows incomplete sequence */
              yield = string_cat(yield, &size, &ptr, &c, 1);
-           }
          }
         continue;
         }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      case EOP_UTF8_DOMAIN_TO_ALABEL:
+       {
+        uschar * error = NULL;
+       uschar * s = string_domain_utf8_to_alabel(sub, &error);
+       if (error)
+         {
+         expand_string_message = string_sprintf(
+           "error converting utf8 (%s) to alabel: %s",
+           string_printing(sub), error);
+         goto EXPAND_FAILED;
+         }
+       yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+        continue;
+       }
+
+      case EOP_UTF8_DOMAIN_FROM_ALABEL:
+       {
+        uschar * error = NULL;
+       uschar * s = string_domain_alabel_to_utf8(sub, &error);
+       if (error)
+         {
+         expand_string_message = string_sprintf(
+           "error converting alabel (%s) to utf8: %s",
+           string_printing(sub), error);
+         goto EXPAND_FAILED;
+         }
+       yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+        continue;
+       }
+
+      case EOP_UTF8_LOCALPART_TO_ALABEL:
+       {
+        uschar * error = NULL;
+       uschar * s = string_localpart_utf8_to_alabel(sub, &error);
+       if (error)
+         {
+         expand_string_message = string_sprintf(
+           "error converting utf8 (%s) to alabel: %s",
+           string_printing(sub), error);
+         goto EXPAND_FAILED;
+         }
+       yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+       DEBUG(D_expand) debug_printf("yield: '%s'\n", yield);
+        continue;
+       }
+
+      case EOP_UTF8_LOCALPART_FROM_ALABEL:
+       {
+        uschar * error = NULL;
+       uschar * s = string_localpart_alabel_to_utf8(sub, &error);
+       if (error)
+         {
+         expand_string_message = string_sprintf(
+           "error converting alabel (%s) to utf8: %s",
+           string_printing(sub), error);
+         goto EXPAND_FAILED;
+         }
+       yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+        continue;
+       }
+#endif /* EXPERIMENTAL_INTERNATIONAL */
+
       /* escape turns all non-printing characters into escape sequences. */
 
       case EOP_ESCAPE:
index 9ee7acb..a28e5f9 100644 (file)
@@ -1821,7 +1821,7 @@ while (commands != NULL)
       set in a system filter and to the local address in user filters. */
 
       addr = deliver_make_addr(expargs[0], TRUE);  /* TRUE => copy s */
-      addr->p.errors_address = (s == NULL)?
+      addr->prop.errors_address = (s == NULL)?
         s : string_copy(s);                        /* Default is NULL */
       if (commands->noerror) setflag(addr, af_ignore_error);
       addr->next = *generated;
index 7195afa..d1ada38 100644 (file)
@@ -412,12 +412,23 @@ extern BOOL    string_format(uschar *, int, const char *, ...) ALMOST_PRINTF(3,4
 extern uschar *string_format_size(int, uschar *);
 extern int     string_interpret_escape(const uschar **);
 extern int     string_is_ip_address(const uschar *, int *);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+extern BOOL    string_is_utf8(const uschar *);
+#endif
 extern uschar *string_log_address(address_item *, BOOL, BOOL);
 extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
 extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3);
 extern const uschar *string_printing2(const uschar *, BOOL);
 extern uschar *string_split_message(uschar *);
 extern uschar *string_unprinting(uschar *);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+extern uschar *string_address_alabel_to_utf8(const uschar *, uschar **);
+extern uschar *string_address_utf8_to_alabel(uschar *, uschar **, int *);
+extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
+extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
+extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
+extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
+#endif
 extern BOOL    string_vformat(uschar *, int, const char *, va_list);
 extern int     strcmpic(const uschar *, const uschar *);
 extern int     strncmpic(const uschar *, const uschar *, int);
index b68ed7e..2bf4d0a 100644 (file)
@@ -175,6 +175,10 @@ BOOL    prdr_requested         = FALSE;
 const pcre *regex_PRDR         = NULL;
 #endif
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+const pcre *regex_UTF8         = NULL;
+#endif
+
 /* Input-reading functions for messages, so we can use special ones for
 incoming TCP/IP. The defaults use stdin. We never need these for any
 stand-alone tests. */
@@ -384,6 +388,9 @@ address_item address_defaults = {
 #ifdef EXPERIMENTAL_SRS
     NULL,               /* srs_sender */
 #endif
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    FALSE,             /* utf8 */
+#endif
   }
 };
 
@@ -906,6 +913,9 @@ int     message_linecount      = 0;
 BOOL    message_logs           = TRUE;
 int     message_size           = 0;
 uschar *message_size_limit     = US"50M";
+#ifdef EXPERIMENTAL_INTERNATIONAL
+BOOL    message_smtputf8       = FALSE;
+#endif
 uschar  message_subdir[2]      = { 0, 0 };
 uschar *message_reference      = NULL;
 
@@ -1270,6 +1280,9 @@ int     smtp_rlr_limit         = 0;
 int     smtp_rlr_threshold     = INT_MAX;
 BOOL    smtp_use_pipelining    = FALSE;
 BOOL    smtp_use_size          = FALSE;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+uschar *smtputf8_advertise_hosts = US"*";      /* overridden under test-harness */
+#endif
 
 #ifdef WITH_CONTENT_SCAN
 uschar *spamd_address          = US"127.0.0.1 783";
index 5c00220..7cbf7bf 100644 (file)
@@ -570,6 +570,10 @@ extern int     message_linecount;      /* As it says */
 extern BOOL    message_logs;           /* TRUE to write message logs */
 extern int     message_size;           /* Size of message */
 extern uschar *message_size_limit;     /* As it says */
+#ifdef EXPERIMENTAL_INTERNATIONAL
+extern BOOL    message_smtputf8;       /* Internationalized mail handling */
+const extern pcre *regex_UTF8;         /* For recognizing SMTPUTF8 settings */
+#endif
 extern uschar  message_subdir[];       /* Subdirectory for messages */
 extern uschar *message_reference;      /* Reference for error messages */
 
@@ -822,6 +826,9 @@ extern int     smtp_rlr_limit;         /* Max delay */
 extern int     smtp_rlr_threshold;     /* Threshold for RCPT rate limit */
 extern BOOL    smtp_use_pipelining;    /* Global for passed connections */
 extern BOOL    smtp_use_size;          /* Global for passed connections */
+#ifdef EXPERIMENTAL_INTERNATIONAL
+extern uschar *smtputf8_advertise_hosts; /* ingress control */
+#endif
 
 #ifdef WITH_CONTENT_SCAN
 extern uschar *spamd_address;          /* address for the spamassassin daemon */
index 0f893e8..a8ab4f7 100644 (file)
@@ -503,7 +503,11 @@ to conflict with system errno values. */
 #define ERRNO_MAIL4XX        (-45)   /* MAIL gave 4xx error */
 #define ERRNO_DATA4XX        (-46)   /* DATA gave 4xx error */
 #define ERRNO_PROXYFAIL      (-47)   /* Negotiation failed for proxy configured host */
-#define ERRNO_AUTHPROB       (-48)   /* Autheticator "other" failure */
+#define ERRNO_AUTHPROB       (-48)   /* Authenticator "other" failure */
+
+#ifdef EXPERIMENTAL_INTERNATIONAL
+# define ERRNO_UTF8_FWD      (-49)   /* target not supporting SMTPUTF8 */
+#endif
 
 /* These must be last, so all retry deferments can easily be identified */
 
index ff814e7..9e57365 100644 (file)
@@ -550,9 +550,7 @@ read_addr_spec(uschar *s, uschar *t, int term, uschar **errorptr,
 {
 s = read_local_part(s, t, errorptr, FALSE);
 if (*errorptr == NULL)
-  {
   if (*s != term)
-    {
     if (*s != '@')
       *errorptr = string_sprintf("\"@\" or \".\" expected after \"%s\"", t);
     else
@@ -562,8 +560,6 @@ if (*errorptr == NULL)
       *domainptr = t;
       s = read_domain(s, t, errorptr);
       }
-    }
-  }
 return s;
 }
 
@@ -817,7 +813,7 @@ if (*end - *start > ADDRESS_MAXLENGTH)
   return NULL;
   }
 
-return (uschar *)yield;
+return yield;
 
 /* Use goto (via the macro FAILED) to get to here from a variety of places.
 We might have an empty address in a group - the caller can choose to ignore
index ca6c47f..5f7781c 100644 (file)
@@ -1274,6 +1274,9 @@ switch(action)
       {
       if (action == MSG_ADD_RECIPIENT)
         {
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
         receive_add_recipient(recipient, -1);
         log_write(0, LOG_MAIN, "recipient <%s> added by %s",
           recipient, username);
@@ -1297,6 +1300,9 @@ switch(action)
         }
       else  /* MSG_EDIT_SENDER */
         {
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
         sender_address = recipient;
         log_write(0, LOG_MAIN, "sender address changed to <%s> by %s",
           recipient, username);
index 99c5513..3359275 100644 (file)
@@ -723,7 +723,7 @@ if ((pid = fork()) == 0)
            != sizeof(addr->mode)
          || write(fd, &(addr->flags), sizeof(addr->flags))
            != sizeof(addr->flags)
-         || rda_write_string(fd, addr->p.errors_address) != 0
+         || rda_write_string(fd, addr->prop.errors_address) != 0
         )
        goto bad;
 
@@ -892,7 +892,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
 
     if (read(fd, &(addr->mode), sizeof(addr->mode)) != sizeof(addr->mode) ||
         read(fd, &(addr->flags), sizeof(addr->flags)) != sizeof(addr->flags) ||
-        !rda_read_string(fd, &(addr->p.errors_address))) goto DISASTER;
+        !rda_read_string(fd, &(addr->prop.errors_address))) goto DISASTER;
 
     /* Next comes a possible setting for $thisaddress and any numerical
     variables for pipe expansion, terminated by a NULL string. The maximum
index e2d3c51..67241cb 100644 (file)
@@ -398,6 +398,9 @@ static optionlist optionlist_config[] = {
   { "smtp_receive_timeout",     opt_func,        &fn_smtp_receive_timeout },
   { "smtp_reserve_hosts",       opt_stringptr,   &smtp_reserve_hosts },
   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  { "smtputf8_advertise_hosts", opt_stringptr,   &smtputf8_advertise_hosts },
+#endif
 #ifdef WITH_CONTENT_SCAN
   { "spamd_address",            opt_stringptr,   &spamd_address },
 #endif
index 0b35463..7c56f47 100644 (file)
@@ -2303,9 +2303,23 @@ if (extract_recip)
         pp = recipient = store_get(ss - s + 1);
         for (p = s; p < ss; p++) if (*p != '\n') *pp++ = *p;
         *pp = 0;
+
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       {
+       BOOL b = allow_utf8_domains;
+       allow_utf8_domains = TRUE;
+#endif
         recipient = parse_extract_address(recipient, &errmess, &start, &end,
           &domain, FALSE);
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       if (string_is_utf8(recipient))
+         message_smtputf8 = TRUE;
+       else
+         allow_utf8_domains = b;
+       }
+#endif
+
         /* Keep a list of all the bad addresses so we can send a single
         error message at the end. However, an empty address is not an error;
         just ignore it. This can come from an empty group list like
index 764f0a1..ec18880 100644 (file)
@@ -1342,8 +1342,8 @@ from the original address' parent, if present, otherwise unset. */
 
 *parent = *addr;
 parent->child_count = 2;
-parent->p.errors_address =
-  (addr->parent == NULL)? NULL : addr->parent->p.errors_address;
+parent->prop.errors_address =
+  (addr->parent == NULL)? NULL : addr->parent->prop.errors_address;
 
 /* The routed address gets a new parent. */
 
@@ -1354,12 +1354,12 @@ was set from the original parent (or to NULL) - see above. We do NOT want to
 take the errors address from the unseen router. */
 
 new->parent = parent;
-new->p.errors_address = parent->p.errors_address;
+new->prop.errors_address = parent->prop.errors_address;
 
 /* Copy the propagated flags and address_data from the original. */
 
 copyflag(new, addr, af_propagate);
-new->p.address_data = addr->p.address_data;
+new->prop.address_data = addr->prop.address_data;
 new->dsn_flags = addr->dsn_flags;
 new->dsn_orcpt = addr->dsn_orcpt;
 
@@ -1645,7 +1645,7 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router;
         goto ROUTE_EXIT;
         }
       }
-    addr->p.address_data = deliver_address_data;
+    addr->prop.address_data = deliver_address_data;
     }
 
   /* We are finally cleared for take-off with this router. Clear the the flag
@@ -1891,8 +1891,8 @@ DEBUG(D_route)
   debug_printf("  transport: %s\n", (addr->transport == NULL)?
     US"<none>" : addr->transport->name);
 
-  if (addr->p.errors_address != NULL)
-    debug_printf("  errors to %s\n", addr->p.errors_address);
+  if (addr->prop.errors_address != NULL)
+    debug_printf("  errors to %s\n", addr->prop.errors_address);
 
   for (h = addr->host_list; h != NULL; h = h->next)
     {
index 8049eaf..ef2a285 100644 (file)
@@ -118,9 +118,9 @@ if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
   addr, rblock->name, NULL)) return DEFER;
 
 addr->transport = rblock->transport;
-addr->p.errors_address = errors_to;
-addr->p.extra_headers = extra_headers;
-addr->p.remove_headers = remove_headers;
+addr->prop.errors_address = errors_to;
+addr->prop.extra_headers = extra_headers;
+addr->prop.remove_headers = remove_headers;
 
 return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)? OK : DEFER;
 }
index 8ef4e0d..650e56d 100644 (file)
@@ -421,13 +421,13 @@ else if (ob->check_secondary_mx && !testflag(addr, af_local_host_removed))
 
 /* Set up the errors address, if any. */
 
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
 if (rc != OK) return rc;
 
 /* Set up the additional and removeable headers for this address. */
 
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
-  &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+  &addr->prop.remove_headers);
 if (rc != OK) return rc;
 
 /* Get store in which to preserve the original host item, chained on
index e9c1865..f9a8c0c 100644 (file)
@@ -165,13 +165,13 @@ addr->host_list = h;
 
 /* Set up the errors address, if any. */
 
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
 if (rc != OK) return rc;
 
 /* Set up the additional and removeable headers for this address. */
 
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
-  &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+  &addr->prop.remove_headers);
 if (rc != OK) return rc;
 
 /* Fill in the transport, queue the address for local or remote delivery, and
index d48cfb9..33329f8 100644 (file)
@@ -377,7 +377,7 @@ new_addr = deliver_make_addr(reroute, TRUE);
 new_addr->parent = addr;
 
 copyflag(new_addr, addr, af_propagate);
-new_addr->p = addr->p;
+new_addr->prop = addr->prop;
 
 if (addr->child_count == SHRT_MAX)
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
@@ -389,11 +389,11 @@ new_addr->next = *addr_new;
 /* Set up the errors address, if any, and the additional and removeable headers
 for this new address. */
 
-rc = rf_get_errors_address(addr, rblock, verify, &(new_addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &new_addr->prop.errors_address);
 if (rc != OK) return rc;
 
-rc = rf_get_munge_headers(addr, rblock, &(new_addr->p.extra_headers),
-  &(new_addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &new_addr->prop.extra_headers,
+  &new_addr->prop.remove_headers);
 if (rc != OK) return rc;
 
 return OK;
index 7cbe5db..add55de 100644 (file)
@@ -358,13 +358,13 @@ while (*options != 0)
 
 /* Set up the errors address, if any. */
 
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
 if (rc != OK) return rc;
 
 /* Set up the additional and removeable headers for this address. */
 
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
-  &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+  &addr->prop.remove_headers);
 if (rc != OK) return rc;
 
 /* If an individual transport is not set, get the transport for this router, if
index bf0f4c4..71f4915 100644 (file)
@@ -114,7 +114,7 @@ while (generated != NULL)
 
   next->parent = addr;
   orflag(next, addr, af_propagate);
-  next->p = *addr_prop;
+  next->prop = *addr_prop;
   next->start_router = rblock->redirect_router;
 
   next->next = *addr_new;
@@ -216,11 +216,11 @@ errors address and extra header stuff. */
 
 addr_prop.address_data = deliver_address_data;
 
-rc = rf_get_errors_address(addr, rblock, verify, &(addr_prop.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr_prop.errors_address);
 if (rc != OK) return rc;
 
-rc = rf_get_munge_headers(addr, rblock, &(addr_prop.extra_headers),
-  &(addr_prop.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr_prop.extra_headers,
+  &addr_prop.remove_headers);
 if (rc != OK) return rc;
 
 /* Get the fixed or expanded uid under which the command is to run
@@ -526,7 +526,7 @@ lookup_value = NULL;
 
 /* Put the errors address, extra headers, and address_data into this address */
 
-addr->p = addr_prop;
+addr->prop = addr_prop;
 
 /* Queue the address for local or remote delivery. */
 
index 0189d23..8f1c2c3 100644 (file)
@@ -277,11 +277,11 @@ sort_errors_and_headers(router_instance *rblock, address_item *addr,
   int verify, address_item_propagated *addr_prop)
 {
 int frc = rf_get_errors_address(addr, rblock, verify,
-  &(addr_prop->errors_address));
+  &addr_prop->errors_address);
 if (frc != OK) return frc;
-addr->p.errors_address = addr_prop->errors_address;
-return rf_get_munge_headers(addr, rblock, &(addr_prop->extra_headers),
-  &(addr_prop->remove_headers));
+addr->prop.errors_address = addr_prop->errors_address;
+return rf_get_munge_headers(addr, rblock, &addr_prop->extra_headers,
+  &addr_prop->remove_headers);
 }
 
 
@@ -329,7 +329,7 @@ while (generated != NULL)
   {
   address_item *parent;
   address_item *next = generated;
-  uschar *errors_address = next->p.errors_address;
+  uschar *errors_address = next->prop.errors_address;
 
   generated = next->next;
   next->parent = addr;
@@ -378,8 +378,8 @@ while (generated != NULL)
   If so, we must take care to re-instate it when we copy in the propagated
   data so that it overrides any errors_to setting on the router. */
 
-  next->p = *addr_prop;
-  if (errors_address != NULL) next->p.errors_address = errors_address;
+  next->prop = *addr_prop;
+  if (errors_address != NULL) next->prop.errors_address = errors_address;
 
   /* For pipes, files, and autoreplies, record this router as handling them,
   because they don't go through the routing process again. Then set up uid,
@@ -451,13 +451,18 @@ while (generated != NULL)
       }
     }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    next->prop.utf8 = string_is_utf8(next->address)
+      || (sender_address && string_is_utf8(sender_address));
+#endif
+
   DEBUG(D_route)
     {
     debug_printf("%s router generated %s\n  %serrors_to=%s transport=%s\n",
       rblock->name,
       next->address,
       testflag(next, af_pfr)? "pipe, file, or autoreply\n  " : "",
-      next->p.errors_address,
+      next->prop.errors_address,
       (next->transport == NULL)? US"NULL" : next->transport->name);
 
     if (testflag(next, af_uid_set))
@@ -470,6 +475,10 @@ while (generated != NULL)
     else
       debug_printf("gid=unset ");
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    if (next->prop.utf8) debug_printf("utf8 ");
+#endif
+
     debug_printf("home=%s\n", next->home_dir);
     }
   }
@@ -891,7 +900,7 @@ else
   data that propagates. */
 
   copyflag(next, addr, af_propagate);
-  next->p = addr_prop;
+  next->prop = addr_prop;
 
   DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
     rblock->name,
index e891b84..049e6ab 100644 (file)
@@ -52,7 +52,7 @@ domain cache. Then copy over the propagating fields from the parent. Then set
 up the new fields. */
 
 *addr = address_defaults;
-addr->p = parent->p;
+addr->prop = parent->prop;
 
 addr->address = address;
 addr->unique = string_copy(address);
index a0ea9f2..f520594 100644 (file)
@@ -38,7 +38,7 @@ rf_get_errors_address(address_item *addr, router_instance *rblock,
 {
 uschar *s;
 
-*errors_to = addr->p.errors_address;
+*errors_to = addr->prop.errors_address;
 if (rblock->errors_to == NULL) return OK;
 
 s = expand_string(rblock->errors_to);
index a6c039e..d4af84f 100644 (file)
@@ -32,7 +32,7 @@ rf_get_munge_headers(address_item *addr, router_instance *rblock,
   header_line **extra_headers, uschar **remove_headers)
 {
 /* Default is to retain existing headers */
-*extra_headers = addr->p.extra_headers;
+*extra_headers = addr->prop.extra_headers;
 
 if (rblock->extra_headers)
   {
@@ -82,7 +82,7 @@ if (rblock->extra_headers)
   }
 
 /* Default is to retain existing removes */
-*remove_headers = addr->p.remove_headers;
+*remove_headers = addr->prop.remove_headers;
 
 /* Expand items from colon-sep list separately, then build new list */
 if (rblock->remove_headers)
index 06cdb6c..273780f 100644 (file)
@@ -36,8 +36,8 @@ BOOL
 rf_queue_add(address_item *addr, address_item **paddr_local,
   address_item **paddr_remote, router_instance *rblock, struct passwd *pw)
 {
-addr->p.domain_data = deliver_domain_data;         /* Save these values for */
-addr->p.localpart_data = deliver_localpart_data;   /* use in the transport */
+addr->prop.domain_data = deliver_domain_data;         /* Save these values for */
+addr->prop.localpart_data = deliver_localpart_data;   /* use in the transport */
 
 /* Handle a local transport */
 
@@ -95,9 +95,9 @@ DEBUG(D_route)
   debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n"
     "  errors_to=%s\n",
     (addr->transport == NULL)? US"<unset>" : addr->transport->name,
-    addr->local_part, addr->domain, addr->p.errors_address);
-  debug_printf("  domain_data=%s localpart_data=%s\n", addr->p.domain_data,
-    addr->p.localpart_data);
+    addr->local_part, addr->domain, addr->prop.errors_address);
+  debug_printf("  domain_data=%s localpart_data=%s\n", addr->prop.domain_data,
+    addr->prop.localpart_data);
   }
 
 return TRUE;
index 262367e..7653993 100644 (file)
@@ -1072,7 +1072,7 @@ if (file)
   setflag(new_addr, af_pfr|af_file);
   new_addr->mode = 0;
   }
-new_addr->p.errors_address = NULL;
+new_addr->prop.errors_address = NULL;
 new_addr->next = *generated;
 *generated = new_addr;
 }
index 9b7c59d..9fa2ae6 100644 (file)
@@ -133,6 +133,9 @@ static BOOL rcpt_smtp_response_same;
 static BOOL rcpt_in_progress;
 static int  nonmail_command_count;
 static BOOL smtp_exit_function_called = 0;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+static BOOL smtputf8_advertised;
+#endif
 static int  synprot_error_count;
 static int  unknown_command_count;
 static int  sync_cmd_limit;
@@ -158,6 +161,8 @@ QUIT is also "falsely" labelled as a mail command so that it doesn't up the
 count of non-mail commands and possibly provoke an error. */
 
 static smtp_cmd_list cmd_list[] = {
+  /* name         len                     cmd     has_arg is_mail_cmd */
+
   { "rset",       sizeof("rset")-1,       RSET_CMD, FALSE, FALSE },  /* First */
   { "helo",       sizeof("helo")-1,       HELO_CMD, TRUE,  FALSE },
   { "ehlo",       sizeof("ehlo")-1,       EHLO_CMD, TRUE,  FALSE },
@@ -197,7 +202,7 @@ static uschar *smtp_names[] =
   US"HELP", US"MAIL", US"NOOP", US"QUIT", US"RCPT", US"RSET", US"STARTTLS",
   US"VRFY" };
 
-static uschar *protocols[] = {
+static uschar *protocols_local[] = {
   US"local-smtp",        /* HELO */
   US"local-smtps",       /* The rare case EHLO->STARTTLS->HELO */
   US"local-esmtp",       /* EHLO */
@@ -205,12 +210,19 @@ static uschar *protocols[] = {
   US"local-esmtpa",      /* EHLO->AUTH */
   US"local-esmtpsa"      /* EHLO->STARTTLS->EHLO->AUTH */
   };
+static uschar *protocols[] = {
+  US"smtp",              /* HELO */
+  US"smtps",             /* The rare case EHLO->STARTTLS->HELO */
+  US"esmtp",             /* EHLO */
+  US"esmtps",            /* EHLO->STARTTLS->EHLO */
+  US"esmtpa",            /* EHLO->AUTH */
+  US"esmtpsa"            /* EHLO->STARTTLS->EHLO->AUTH */
+  };
 
 #define pnormal  0
 #define pextend  2
 #define pcrpted  1  /* added to pextend or pnormal */
 #define pauthed  2  /* added to pextend */
-#define pnlocal  6  /* offset to remove "local" */
 
 /* Sanity check and validate optional args to MAIL FROM: envelope */
 enum {
@@ -219,6 +231,9 @@ enum {
   ENV_MAIL_OPT_PRDR,
 #endif
   ENV_MAIL_OPT_RET, ENV_MAIL_OPT_ENVID,
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  ENV_MAIL_OPT_UTF8,
+#endif
   ENV_MAIL_OPT_NULL
   };
 typedef struct {
@@ -236,6 +251,9 @@ static env_mail_type_t env_mail_type_list[] = {
 #endif
     { US"RET",    ENV_MAIL_OPT_RET,    TRUE },
     { US"ENVID",  ENV_MAIL_OPT_ENVID,  TRUE },
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    { US"SMTPUTF8",ENV_MAIL_OPT_UTF8,  FALSE },                /* rfc6531 */
+#endif
     { US"NULL",   ENV_MAIL_OPT_NULL,   FALSE }
   };
 
@@ -1494,6 +1512,8 @@ sender_verified_list = NULL;        /* No senders verified */
 memset(sender_address_cache, 0, sizeof(sender_address_cache));
 memset(sender_domain_cache, 0, sizeof(sender_domain_cache));
 
+prdr_requested = FALSE;
+
 /* Reset the DSN flags */
 dsn_ret = 0;
 dsn_envid = NULL;
@@ -1514,6 +1534,9 @@ spf_received = NULL;
 spf_result = NULL;
 spf_smtp_comment = NULL;
 #endif
+#ifdef EXPERIMENTAL_INTERNATIONAL
+message_smtputf8 = FALSE;
+#endif
 body_linecount = body_zerocount = 0;
 
 sender_rate = sender_rate_limit = sender_rate_period = NULL;
@@ -1848,6 +1871,9 @@ tls_in.ocsp = OCSP_NOT_REQ;
 tls_advertised = FALSE;
 #endif
 dsn_advertised = FALSE;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+smtputf8_advertised = FALSE;
+#endif
 
 /* Reset ACL connection variables */
 
@@ -1875,7 +1901,7 @@ reset later if any of EHLO/AUTH/STARTTLS are received. */
 
 else
   received_protocol =
-    protocols[pnormal] + ((sender_host_address != NULL)? pnlocal : 0);
+    (sender_host_address ? protocols : protocols_local) [pnormal];
 
 /* Set up the buffer for inputting using direct read() calls, and arrange to
 call the local functions instead of the standard C ones. */
@@ -3295,9 +3321,10 @@ while (done <= 0)
         sender_host_authenticated = au->name;
         authentication_failed = FALSE;
         authenticated_fail_id = NULL;   /* Impossible to already be set? */
+
         received_protocol =
-          protocols[pextend + pauthed + ((tls_in.active >= 0)? pcrpted:0)] +
-            ((sender_host_address != NULL)? pnlocal : 0);
+         (sender_host_address ? protocols : protocols_local)
+           [pextend + pauthed + (tls_in.active >= 0 ? pcrpted:0)];
         s = ss = US"235 Authentication succeeded";
         authenticated_by = au;
         break;
@@ -3493,10 +3520,13 @@ while (done <= 0)
 
     auth_advertised = FALSE;
     pipelining_advertised = FALSE;
-    #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
     tls_advertised = FALSE;
-    #endif
+#endif
     dsn_advertised = FALSE;
+#ifdef EXPERIMENTAL_INTERNATIONAL
+    smtputf8_advertised = FALSE;
+#endif
 
     smtp_code = US"250 ";        /* Default response code plus space*/
     if (user_msg == NULL)
@@ -3667,7 +3697,7 @@ while (done <= 0)
       tls_advertise_hosts. We must *not* advertise if we are already in a
       secure connection. */
 
-      #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
       if (tls_in.active < 0 &&
           verify_check_host(&tls_advertise_hosts) != FAIL)
         {
@@ -3675,16 +3705,26 @@ while (done <= 0)
         s = string_cat(s, &size, &ptr, US"-STARTTLS\r\n", 11);
         tls_advertised = TRUE;
         }
-      #endif
+#endif
 
-      #ifndef DISABLE_PRDR
+#ifndef DISABLE_PRDR
       /* Per Recipient Data Response, draft by Eric A. Hall extending RFC */
       if (prdr_enable)
         {
         s = string_cat(s, &size, &ptr, smtp_code, 3);
         s = string_cat(s, &size, &ptr, US"-PRDR\r\n", 7);
        }
-      #endif
+#endif
+
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      if (  accept_8bitmime
+         && verify_check_host(&smtputf8_advertise_hosts) != FAIL)
+       {
+        s = string_cat(s, &size, &ptr, smtp_code, 3);
+        s = string_cat(s, &size, &ptr, US"-SMTPUTF8\r\n", 11);
+        smtputf8_advertised = TRUE;
+       }
+#endif
 
       /* Finish off the multiline reply with one that is always available. */
 
@@ -3697,9 +3737,9 @@ while (done <= 0)
 
     s[ptr] = 0;
 
-    #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
     if (tls_in.active >= 0) (void)tls_write(TRUE, s, ptr); else
-    #endif
+#endif
 
       {
       int i = fwrite(s, 1, ptr, smtp_out); i = i; /* compiler quietening */
@@ -3714,16 +3754,13 @@ while (done <= 0)
     helo_seen = TRUE;
 
     /* Reset the protocol and the state, abandoning any previous message. */
-
-    received_protocol = (esmtp?
-      protocols[pextend +
-        ((sender_host_authenticated != NULL)? pauthed : 0) +
-        ((tls_in.active >= 0)? pcrpted : 0)]
-      :
-      protocols[pnormal + ((tls_in.active >= 0)? pcrpted : 0)])
-      +
-      ((sender_host_address != NULL)? pnlocal : 0);
-
+    received_protocol =
+      (sender_host_address ? protocols : protocols_local)
+       [ (esmtp
+         ? pextend + (sender_host_authenticated ? pauthed : 0)
+         : pnormal)
+       + (tls_in.active >= 0 ? pcrpted : 0)
+       ];
     smtp_reset(reset_point);
     toomany = FALSE;
     break;   /* HELO/EHLO */
@@ -3796,10 +3833,8 @@ while (done <= 0)
            (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list);
            mail_args++
           )
-        {
         if (strcmpic(name, mail_args->name) == 0)
           break;
-        }
       if (mail_args->need_value && strcmpic(value, US"") == 0)
         break;
 
@@ -3827,16 +3862,17 @@ while (done <= 0)
         and "7BIT" as body types, but take no action. */
         case ENV_MAIL_OPT_BODY:
           if (accept_8bitmime) {
-            if (strcmpic(value, US"8BITMIME") == 0) {
+            if (strcmpic(value, US"8BITMIME") == 0)
               body_8bitmime = 8;
-            } else if (strcmpic(value, US"7BIT") == 0) {
+            else if (strcmpic(value, US"7BIT") == 0)
               body_8bitmime = 7;
-            } else {
+            else
+             {
               body_8bitmime = 0;
               done = synprot_error(L_smtp_syntax_error, 501, NULL,
                 US"invalid data for BODY");
               goto COMMAND_LOOP;
-            }
+              }
             DEBUG(D_receive) debug_printf("8BITMIME: %d\n", body_8bitmime);
            break;
           }
@@ -3848,35 +3884,43 @@ while (done <= 0)
         is included only if configured in at build time. */
 
         case ENV_MAIL_OPT_RET:
-          if (dsn_advertised) {
+          if (dsn_advertised)
+           {
             /* Check if RET has already been set */
-            if (dsn_ret > 0) {
+            if (dsn_ret > 0)
+             {
               synprot_error(L_smtp_syntax_error, 501, NULL,
                 US"RET can be specified once only");
               goto COMMAND_LOOP;
-            }
-            dsn_ret = (strcmpic(value, US"HDRS") == 0)? dsn_ret_hdrs :
-                    (strcmpic(value, US"FULL") == 0)? dsn_ret_full : 0;
+             }
+            dsn_ret = strcmpic(value, US"HDRS") == 0
+             ? dsn_ret_hdrs
+             : strcmpic(value, US"FULL") == 0
+             ? dsn_ret_full
+             : 0;
             DEBUG(D_receive) debug_printf("DSN_RET: %d\n", dsn_ret);
             /* Check for invalid invalid value, and exit with error */
-            if (dsn_ret == 0) {
+            if (dsn_ret == 0)
+             {
               synprot_error(L_smtp_syntax_error, 501, NULL,
                 US"Value for RET is invalid");
               goto COMMAND_LOOP;
-            }
-          }
+             }
+           }
           break;
         case ENV_MAIL_OPT_ENVID:
-          if (dsn_advertised) {
+          if (dsn_advertised)
+           {
             /* Check if the dsn envid has been already set */
-            if (dsn_envid != NULL) {
+            if (dsn_envid != NULL)
+             {
               synprot_error(L_smtp_syntax_error, 501, NULL,
                 US"ENVID can be specified once only");
               goto COMMAND_LOOP;
-            }
+             }
             dsn_envid = string_copy(value);
             DEBUG(D_receive) debug_printf("DSN_ENVID: %s\n", dsn_envid);
-          }
+           }
           break;
 
         /* Handle the AUTH extension. If the value given is not "<>" and either
@@ -3916,34 +3960,34 @@ while (done <= 0)
             switch (rc)
               {
               case OK:
-              if (authenticated_by == NULL ||
-                  authenticated_by->mail_auth_condition == NULL ||
-                  expand_check_condition(authenticated_by->mail_auth_condition,
-                      authenticated_by->name, US"authenticator"))
-                break;     /* Accept the AUTH */
-  
-              ignore_msg = US"server_mail_auth_condition failed";
-              if (authenticated_id != NULL)
-                ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
-                  ignore_msg, authenticated_id);
+               if (authenticated_by == NULL ||
+                   authenticated_by->mail_auth_condition == NULL ||
+                   expand_check_condition(authenticated_by->mail_auth_condition,
+                       authenticated_by->name, US"authenticator"))
+                 break;     /* Accept the AUTH */
+    
+               ignore_msg = US"server_mail_auth_condition failed";
+               if (authenticated_id != NULL)
+                 ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
+                   ignore_msg, authenticated_id);
   
               /* Fall through */
   
               case FAIL:
-              authenticated_sender = NULL;
-              log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
-                value, host_and_ident(TRUE), ignore_msg);
-              break;
+               authenticated_sender = NULL;
+               log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
+                 value, host_and_ident(TRUE), ignore_msg);
+               break;
   
               /* Should only get DEFER or ERROR here. Put back terminator
               overrides for error message */
   
               default:
-              value[-1] = '=';
-              name[-1] = ' ';
-              (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
-                log_msg);
-              goto COMMAND_LOOP;
+               value[-1] = '=';
+               name[-1] = ' ';
+               (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
+                 log_msg);
+               goto COMMAND_LOOP;
               }
             }
             break;
@@ -3955,6 +3999,16 @@ while (done <= 0)
           break;
 #endif
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+        case ENV_MAIL_OPT_UTF8:
+         if (smtputf8_advertised)
+           {
+           DEBUG(D_receive) debug_printf("smtputf8 requested\n");
+           message_smtputf8 = allow_utf8_domains = TRUE;
+           received_protocol = string_sprintf("utf8%s", received_protocol);
+           }
+         break;
+#endif
         /* Unknown option. Stick back the terminator characters and break
         the loop.  Do the name-terminator second as extract_option sets
        value==name when it found no equal-sign.
@@ -3987,9 +4041,10 @@ while (done <= 0)
     /* Now extract the address, first applying any SMTP-time rewriting. The
     TRUE flag allows "<>" as a sender address. */
 
-    raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
-      rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
-        global_rewrite_rules) : smtp_cmd_data;
+    raw_sender = rewrite_existflags & rewrite_smtp
+      ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
+                   global_rewrite_rules)
+      : smtp_cmd_data;
 
     /* rfc821_domains = TRUE; << no longer needed */
     raw_sender =
@@ -4354,16 +4409,12 @@ while (done <= 0)
       receive_add_recipient(recipient, -1);
  
       /* Set the dsn flags in the recipients_list */
-      if (orcpt != NULL)
-        recipients_list[recipients_count-1].orcpt = orcpt;
-      else
-        recipients_list[recipients_count-1].orcpt = NULL;
+      recipients_list[recipients_count-1].orcpt = orcpt;
+      recipients_list[recipients_count-1].dsn_flags = flags;
 
-      if (flags != 0)
-        recipients_list[recipients_count-1].dsn_flags = flags;
-      else
-        recipients_list[recipients_count-1].dsn_flags = 0;
-      DEBUG(D_receive) debug_printf("DSN: orcpt: %s  flags: %d\n", recipients_list[recipients_count-1].orcpt, recipients_list[recipients_count-1].dsn_flags);
+      DEBUG(D_receive) debug_printf("DSN: orcpt: %s  flags: %d\n",
+       recipients_list[recipients_count-1].orcpt,
+       recipients_list[recipients_count-1].dsn_flags);
       }
 
     /* The recipient was discarded */
@@ -4624,13 +4675,13 @@ while (done <= 0)
         set_process_info("handling incoming TLS connection from %s",
           host_and_ident(FALSE));
         }
-      received_protocol = (esmtp?
-        protocols[pextend + pcrpted +
-          ((sender_host_authenticated != NULL)? pauthed : 0)]
-        :
-        protocols[pnormal + pcrpted])
-        +
-        ((sender_host_address != NULL)? pnlocal : 0);
+      received_protocol =
+       (sender_host_address ? protocols : protocols_local)
+         [ (esmtp
+           ? pextend + (sender_host_authenticated ? pauthed : 0)
+           : pnormal)
+         + (tls_in.active >= 0 ? pcrpted : 0)
+         ];
 
       sender_host_authenticated = NULL;
       authenticated_id = NULL;
index 79970cb..742f4b5 100644 (file)
@@ -299,6 +299,10 @@ tls_in.ocsp = OCSP_NOT_REQ;
 spam_score_int = NULL;
 #endif
 
+#if defined(EXPERIMENTAL_INTERNATIONAL) && !defined(COMPILE_UTILITY)
+message_smtputf8 = FALSE;
+#endif
+
 dsn_ret = 0;
 dsn_envid = NULL;
 
@@ -569,6 +573,10 @@ for (;;)
     else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
       spam_score_int = string_copy(big_buffer + 16);
 #endif
+#if defined(EXPERIMENTAL_INTERNATIONAL) && !defined(COMPILE_UTILITY)
+    else if (Ustrncmp(p, "mtputf8", 7) == 0)
+      message_smtputf8 = TRUE;
+#endif
     break;
 
 #ifdef SUPPORT_TLS
index fc56057..6d22bff 100644 (file)
@@ -245,6 +245,10 @@ if (tls_in.ourcert)
 if (tls_in.ocsp)        fprintf(f, "-tls_ocsp %d\n",   tls_in.ocsp);
 #endif
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+if (message_smtputf8)    fprintf(f, "-smtputf8\n");
+#endif
+
 /* Write the dsn flags to the spool header file */
 DEBUG(D_deliver) debug_printf("DSN: Write SPOOL :-dsn_envid %s\n", dsn_envid);
 if (dsn_envid != NULL) fprintf(f, "-dsn_envid %s\n", dsn_envid);
index 6ec52e1..99d65cf 100644 (file)
@@ -459,6 +459,9 @@ typedef struct address_item_propagated {
   #ifdef EXPERIMENTAL_SRS
   uschar *srs_sender;             /* Change return path when delivering */
   #endif
+  #ifdef EXPERIMENTAL_INTERNATIONAL
+  BOOL    utf8;                          /* requires SMTPUTF8 processing */
+  #endif
 } address_item_propagated;
 
 /* Bits for the flags field below */
@@ -581,7 +584,7 @@ typedef struct address_item {
                                   /* (  also  */
                                   /* ( contains verify rc in sender verify cache */
   short int transport_return;     /* result of delivery attempt */
-  address_item_propagated p;      /* fields that are propagated to children */
+  address_item_propagated prop;   /* fields that are propagated to children */
 } address_item;
 
 /* The table of header names consists of items of this type */
index c768736..78d9d51 100644 (file)
@@ -628,7 +628,7 @@ that means they were rewritten, or are a record of envelope rewriting, or
 were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
 match any entries therein.  It is a colon-sep list; expand the items
 separately and squash any empty ones.
-Then check addr->p.remove_headers too, provided that addr is not NULL. */
+Then check addr->prop.remove_headers too, provided that addr is not NULL. */
 
 for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
   {
@@ -637,7 +637,7 @@ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
 
   BOOL include_header = TRUE;
 
-  for (i = 0; i < 2; i++)    /* For remove_headers && addr->p.remove_headers */
+  for (i = 0; i < 2; i++)    /* For remove_headers && addr->prop.remove_headers */
     {
     if (list)
       {
@@ -661,7 +661,7 @@ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
        }
       if (s != NULL) { include_header = FALSE; break; }
       }
-    if (addr != NULL) list = addr->p.remove_headers;
+    if (addr != NULL) list = addr->prop.remove_headers;
     }
 
   /* If this header is to be output, try to rewrite it if there are rewriting
@@ -709,7 +709,7 @@ Headers added to an address by a router are guaranteed to end with a newline.
 if (addr)
   {
   int i;
-  header_line *hprev = addr->p.extra_headers;
+  header_line *hprev = addr->prop.extra_headers;
   header_line *hnext;
   for (i = 0; i < 2; i++)
     {
@@ -914,7 +914,7 @@ if ((options & topt_no_headers) == 0)
   /* Then the message's headers. Don't write any that are flagged as "old";
   that means they were rewritten, or are a record of envelope rewriting, or
   were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
-  match any entries therein. Then check addr->p.remove_headers too, provided that
+  match any entries therein. Then check addr->prop.remove_headers too, provided that
   addr is not NULL. */
   if (!transport_headers_send(addr, fd, add_headers, remove_headers, &write_chunk,
        use_crlf, rewrite_rules, rewrite_existflags))
index b0fe177..65bb1de 100644 (file)
@@ -570,6 +570,16 @@ if (*errno_value == ERRNO_WRITEINCOMPLETE)
   return FALSE;
   }
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+/* Handle lack of advertised SMTPUTF8, for international message */
+if (*errno_value == ERRNO_UTF8_FWD)
+  {
+  *message = US string_sprintf("utf8 support required but not offered for forwarding");
+  DEBUG(D_deliver|D_transport) debug_printf("%s\n", *message);
+  return TRUE;
+  }
+#endif
+
 /* Handle error responses from the remote mailer. */
 
 if (buffer[0] != 0)
@@ -1355,6 +1365,9 @@ BOOL pass_message = FALSE;
 BOOL prdr_offered = FALSE;
 BOOL prdr_active;
 #endif
+#ifdef EXPERIMENTAL_INTERNATIONAL
+BOOL utf8_offered = FALSE;
+#endif
 BOOL dsn_all_lasthop = TRUE;
 #if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
 BOOL dane = FALSE;
@@ -1473,6 +1486,19 @@ if (continue_hostname == NULL)
   delayed till here so that $sending_interface and $sending_port are set. */
 
   helo_data = expand_string(ob->helo_data);
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  if (helo_data)
+    {
+    uschar * errstr = NULL;
+    if ((helo_data = string_domain_utf8_to_alabel(helo_data, &errstr)), errstr)
+      {
+      errstr = string_sprintf("failed to expand helo_data: %s", errstr);
+      set_errno(addrlist, ERRNO_EXPANDFAIL, errstr, DEFER, FALSE, NULL);
+      yield = DEFER;
+      goto SEND_QUIT;
+      }
+    }
+#endif
 
   /* The first thing is to wait for an initial OK response. The dreaded "goto"
   is nevertheless a reasonably clean way of programming this kind of logic,
@@ -1614,6 +1640,13 @@ goto SEND_QUIT;
   if (prdr_offered)
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
 #endif
+
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  utf8_offered = esmtp
+    && addrlist->prop.utf8
+    && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
+                 PCRE_EOPT, NULL, 0) >= 0;
+#endif
   }
 
 /* For continuing deliveries down the same channel, the socket is the standard
@@ -1821,16 +1854,24 @@ if (continue_hostname == NULL
 #ifndef DISABLE_PRDR
   prdr_offered = esmtp
     && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0
+                 PCRE_EOPT, NULL, 0) >= 0
     && verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
 
   if (prdr_offered)
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
 #endif
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+  utf8_offered = esmtp
+    && addrlist->prop.utf8
+    && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
+                 PCRE_EOPT, NULL, 0) >= 0;
+#endif
+
   /* Note if the server supports DSN */
-  smtp_use_dsn = esmtp && pcre_exec(regex_DSN, NULL, CS buffer, (int)Ustrlen(CS buffer), 0,
-       PCRE_EOPT, NULL, 0) >= 0;
+  smtp_use_dsn = esmtp
+    && pcre_exec(regex_DSN, NULL, CS buffer, Ustrlen(CS buffer), 0,
+                 PCRE_EOPT, NULL, 0) >= 0;
   DEBUG(D_transport) debug_printf("use_dsn=%d\n", smtp_use_dsn);
 
   /* Note if the response to EHLO specifies support for the AUTH extension.
@@ -1853,6 +1894,15 @@ message-specific. */
 
 setting_up = FALSE;
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+/* If this is an international message we need the host to speak SMTPUTF8 */
+if (addrlist->prop.utf8 && !utf8_offered)
+  {
+  errno = ERRNO_UTF8_FWD;
+  goto RESPONSE_FAILED;
+  }
+#endif
+
 /* If there is a filter command specified for this transport, we can now
 set it up. This cannot be done until the identify of the host is known. */
 
@@ -1929,18 +1979,25 @@ if (prdr_offered)
   }
 #endif
 
+#ifdef EXPERIMENTAL_INTERNATIONAL
+if (addrlist->prop.utf8)
+  sprintf(CS p, " SMTPUTF8"), p += 9;
+#endif
+
 /* check if all addresses have lasthop flag */
 /* do not send RET and ENVID if true */
-dsn_all_lasthop = TRUE;
-for (addr = first_addr;
+for (dsn_all_lasthop = TRUE, addr = first_addr;
      address_count < max_rcpt && addr != NULL;
      addr = addr->next)
   if ((addr->dsn_flags & rf_dsnlasthop) != 1)
+    {
     dsn_all_lasthop = FALSE;
+    break;
+    }
 
 /* Add any DSN flags to the mail command */
 
-if ((smtp_use_dsn) && (dsn_all_lasthop == FALSE))
+if (smtp_use_dsn && !dsn_all_lasthop)
   {
   if (dsn_ret == dsn_ret_hdrs)
     {
@@ -1981,27 +2038,27 @@ buffer. */
 pending_MAIL = TRUE;     /* The block starts with MAIL */
 
 rc = smtp_write_command(&outblock, smtp_use_pipelining,
-       "MAIL FROM:<%s>%s\r\n", return_path, buffer);
+       "MAIL FROM:<%s>%s\r\n", return_path, buffer);
 mail_command = string_copy(big_buffer);  /* Save for later error message */
 
 switch(rc)
   {
   case -1:                /* Transmission error */
-  goto SEND_FAILED;
+    goto SEND_FAILED;
 
   case +1:                /* Block was sent */
-  if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
+    if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
        ob->command_timeout))
-    {
-    if (errno == 0 && buffer[0] == '4')
       {
-      errno = ERRNO_MAIL4XX;
-      addrlist->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
+      if (errno == 0 && buffer[0] == '4')
+       {
+       errno = ERRNO_MAIL4XX;
+       addrlist->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
+       }
+      goto RESPONSE_FAILED;
       }
-    goto RESPONSE_FAILED;
-    }
-  pending_MAIL = FALSE;
-  break;
+    pending_MAIL = FALSE;
+    break;
   }
 
 /* Pass over all the relevant recipient addresses for this host, which are the
@@ -2490,24 +2547,29 @@ if (!ok)
 
     switch(save_errno)
       {
+#ifdef EXPERIMENTAL_INTERNATIONAL
+      case ERRNO_UTF8_FWD:
+        code = '5';
+      /*FALLTHROUGH*/
+#endif
       case 0:
       case ERRNO_MAIL4XX:
       case ERRNO_DATA4XX:
-      message_error = TRUE;
-      break;
+       message_error = TRUE;
+       break;
 
       case ETIMEDOUT:
-      message_error = Ustrncmp(smtp_command,"MAIL",4) == 0 ||
-                      Ustrncmp(smtp_command,"end ",4) == 0;
-      break;
+       message_error = Ustrncmp(smtp_command,"MAIL",4) == 0 ||
+                       Ustrncmp(smtp_command,"end ",4) == 0;
+       break;
 
       case ERRNO_SMTPCLOSED:
-      message_error = Ustrncmp(smtp_command,"end ",4) == 0;
-      break;
+       message_error = Ustrncmp(smtp_command,"end ",4) == 0;
+       break;
 
       default:
-      message_error = FALSE;
-      break;
+       message_error = FALSE;
+       break;
       }
 
     /* Handle the cases that are treated as message errors. These are:
@@ -2515,6 +2577,7 @@ if (!ok)
       (a) negative response or timeout after MAIL
       (b) negative response after DATA
       (c) negative response or timeout or dropped connection after "."
+      (d) utf8 support required and not offered
 
     It won't be a negative response or timeout after RCPT, as that is dealt
     with separately above. The action in all cases is to set an appropriate
diff --git a/src/src/utf8.c b/src/src/utf8.c
new file mode 100644 (file)
index 0000000..6bc0c2e
--- /dev/null
@@ -0,0 +1,152 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+
+#include "exim.h"
+
+#ifdef EXPERIMENTAL_INTERNATIONAL
+
+#include <idna.h>
+#include <punycode.h>
+#include <stringprep.h>
+
+BOOL
+string_is_utf8(const uschar * s)
+{
+uschar c;
+while ((c = *s++)) if (c & 0x80) return TRUE;
+return FALSE;
+}
+
+/**************************************************/
+/* Domain conversions */
+
+uschar *
+string_domain_utf8_to_alabel(const uschar * utf8, uschar ** err)
+{
+uschar * s1;
+uschar * s;
+int rc;
+
+s = US stringprep_utf8_nfkc_normalize(CCS utf8, -1);
+if (  (rc = idna_to_ascii_8z(CCS s, CSS &s1, IDNA_ALLOW_UNASSIGNED))
+   != IDNA_SUCCESS)
+  {
+  free(s);
+  if (err) *err = US idna_strerror(rc);
+  return NULL;
+  }
+free(s);
+s = string_copy(s1);
+free(s1);
+return s;
+}
+
+
+
+uschar *
+string_domain_alabel_to_utf8(const uschar * alabel, uschar ** err)
+{
+uschar * s1;
+uschar * s;
+int rc;
+
+if (  (rc = idna_to_unicode_8z8z(CCS alabel, CSS &s1, IDNA_USE_STD3_ASCII_RULES))
+   != IDNA_SUCCESS)
+  {
+  if (err) *err = US idna_strerror(rc);
+  return NULL;
+  }
+s = string_copy(s1);
+free(s1);
+return s;
+}
+
+/**************************************************/
+/* localpart conversions */
+
+
+uschar *
+string_localpart_utf8_to_alabel(const uschar * utf8, uschar ** err)
+{
+size_t ucs4_len;
+punycode_uint * p = (punycode_uint *) stringprep_utf8_to_ucs4(CCS utf8, -1, &ucs4_len);
+size_t p_len = ucs4_len*4;     /* this multiplier is pure guesswork */
+uschar * res = store_get(p_len+5);
+int rc;
+
+res[0] = 'x'; res[1] = 'n'; res[2] = res[3] = '-';
+
+if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, res+4)) != PUNYCODE_SUCCESS)
+  {
+  DEBUG(D_expand) debug_printf("l_u2a: bad '%s'\n", punycode_strerror(rc));
+  free(p);
+  if (err) *err = US punycode_strerror(rc);
+  return NULL;
+  }
+p_len += 4;
+free(p);
+res[p_len] = '\0';
+return res;
+}
+
+
+uschar *
+string_localpart_alabel_to_utf8(const uschar * alabel, uschar ** err)
+{
+size_t p_len = strlen(alabel);
+punycode_uint * p;
+uschar * s;
+uschar * res;
+int rc;
+
+if (alabel[0] != 'x' || alabel[1] != 'n' || alabel[2] != '-' || alabel[3] != '-')
+  {
+  if (err) *err = US"bad alabel prefix";
+  return NULL;
+  }
+
+p_len -= 4;
+p = (punycode_uint *) store_get((p_len+1) * sizeof(*p));
+
+if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUCCESS)
+  {
+  if (err) *err = US punycode_strerror(rc);
+  return NULL;
+  }
+
+s = stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len);
+res = string_copyn(s, p_len);
+free(s);
+return res;
+}
+
+
+/*************************************************
+*         Report the library versions.           *
+*************************************************/
+
+/* See a description in tls-openssl.c for an explanation of why this exists.
+
+Arguments:   a FILE* to print the results to
+Returns:     nothing
+*/
+
+void
+utf8_version_report(FILE *f)
+{
+fprintf(f, "Library version: IDN: Compile: %s\n"
+           "                      Runtime: %s\n",
+       STRINGPREP_VERSION,
+       stringprep_check_version(NULL));
+}
+
+#endif /* whole file */
+
+/* vi: aw ai sw=2
+*/
+/* End of utf8.c */
index 678ee63..4e9b563 100644 (file)
@@ -920,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->prop.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 */
 
@@ -937,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->prop.utf8
+         ? "MAIL FROM:<%s>%s SMTPUTF8\r\n"
+         :
+#endif
+           "MAIL FROM:<%s>%s\r\n",
           from_address, responsebuffer) >= 0)
       )  &&
 
@@ -1022,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->prop.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);
@@ -1146,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");
@@ -1616,7 +1662,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;
@@ -1877,8 +1923,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
@@ -2171,7 +2217,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;
       }
@@ -2203,8 +2249,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. */
diff --git a/test/confs/4200 b/test/confs/4200
new file mode 100644 (file)
index 0000000..bce8e55
--- /dev/null
@@ -0,0 +1,12 @@
+# Exim test configuration 4200
+
+exim_path = EXIM_PATH
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+# ----- ACL -----
+
+# End
diff --git a/test/confs/4201 b/test/confs/4201
new file mode 100644 (file)
index 0000000..b34c7c1
--- /dev/null
@@ -0,0 +1,120 @@
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+smtputf8_advertise_hosts = OPTION
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+  accept hosts = :
+  accept domains = +local_domains
+        local_parts = ^user.*\$
+  deny   message = relay not permitted
+
+.else
+
+sub:
+.ifdef CONTROL
+  require CONTROL
+.endif
+  accept
+
+check_recipient:
+  accept domains = *
+        acl = sub
+
+non_smtp:
+  accept senders = :
+        control = queue_only
+  accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+  driver = redirect
+  domains = ! +local_domains
+  data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+  driver = redirect
+  condition = ${if eq {} {$sender_address}}
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+localuser:
+  driver = redirect
+  data = :blackhole:
+
+.else
+
+bounces:
+  driver = redirect
+  domains = *.local
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+rmt:
+  driver = manualroute
+  domains = +local_domains
+  route_data = <;[127.0.0.1]:PORT_D
+  transport = rmt_smtp
+  self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+  driver = appendfile
+  user = CALLER
+  delivery_date_add
+  envelope_to_add
+  file = DIR/test-mail/$local_part
+  headers_add = "X-body-linecount: $body_linecount\n\
+                 X-message-linecount: $message_linecount\n\
+                 X-received-count: $received_count"
+  return_path_add
+
+rmt_smtp:
+  driver = smtp
+
+# End
diff --git a/test/confs/4211 b/test/confs/4211
new file mode 100644 (file)
index 0000000..085fecc
--- /dev/null
@@ -0,0 +1,126 @@
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey =  ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_advertise_hosts = *
+
+smtputf8_advertise_hosts = OPTION
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+  accept hosts = :
+  accept domains = +local_domains
+        local_parts = ^user.*\$
+  deny   message = relay not permitted
+
+.else
+
+sub:
+.ifdef CONTROL
+  require CONTROL
+.endif
+  accept
+
+check_recipient:
+  accept domains = *
+        acl = sub
+
+non_smtp:
+  accept senders = :
+        control = queue_only
+  accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+  driver = redirect
+  domains = ! +local_domains
+  data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+  driver = redirect
+  condition = ${if eq {} {$sender_address}}
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+localuser:
+  driver = redirect
+  data = :blackhole:
+
+.else
+
+bounces:
+  driver = redirect
+  domains = *.local
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+rmt:
+  driver = manualroute
+  domains = +local_domains
+  route_data = <;[127.0.0.1]:PORT_D
+  transport = rmt_smtp
+  self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+  driver = appendfile
+  user = CALLER
+  delivery_date_add
+  envelope_to_add
+  file = DIR/test-mail/$local_part
+  headers_add = "X-body-linecount: $body_linecount\n\
+                 X-message-linecount: $message_linecount\n\
+                 X-received-count: $received_count"
+  return_path_add
+
+rmt_smtp:
+  driver = smtp
+  hosts_require_tls = *
+  tls_try_verify_hosts = :
+
+# End
diff --git a/test/confs/4221 b/test/confs/4221
new file mode 100644 (file)
index 0000000..085fecc
--- /dev/null
@@ -0,0 +1,126 @@
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey =  ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_advertise_hosts = *
+
+smtputf8_advertise_hosts = OPTION
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+  accept hosts = :
+  accept domains = +local_domains
+        local_parts = ^user.*\$
+  deny   message = relay not permitted
+
+.else
+
+sub:
+.ifdef CONTROL
+  require CONTROL
+.endif
+  accept
+
+check_recipient:
+  accept domains = *
+        acl = sub
+
+non_smtp:
+  accept senders = :
+        control = queue_only
+  accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+  driver = redirect
+  domains = ! +local_domains
+  data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+  driver = redirect
+  condition = ${if eq {} {$sender_address}}
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+localuser:
+  driver = redirect
+  data = :blackhole:
+
+.else
+
+bounces:
+  driver = redirect
+  domains = *.local
+  data = DIR/test-mail/$local_part
+  file_transport = local_delivery
+
+rmt:
+  driver = manualroute
+  domains = +local_domains
+  route_data = <;[127.0.0.1]:PORT_D
+  transport = rmt_smtp
+  self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+  driver = appendfile
+  user = CALLER
+  delivery_date_add
+  envelope_to_add
+  file = DIR/test-mail/$local_part
+  headers_add = "X-body-linecount: $body_linecount\n\
+                 X-message-linecount: $message_linecount\n\
+                 X-received-count: $received_count"
+  return_path_add
+
+rmt_smtp:
+  driver = smtp
+  hosts_require_tls = *
+  tls_try_verify_hosts = :
+
+# End
index fec2a0d..ebf9a40 100644 (file)
@@ -38,9 +38,9 @@ dontqualify  A       V4NET.255.255.254
 
 UpperCase    A       127.0.0.1
 
-; A host with UTF-8 characters in its name
+; A host with UTF-8 characters used for its lookup ( π.test.ex )
 
-mx.π        A       V4NET.255.255.255
+mx.xn--1xa   A       V4NET.255.255.255
 
 ; A non-standard name for localhost
 
@@ -358,9 +358,9 @@ mxt97        MX  1  ten-1.test.ex.
 
 mxt1c        MX  1  dontqualify.
 
-; MX with UTF-8 characters in its name
+; MX with UTF-8 characters used for its lookup ( π.test.ex )
 
-π           MX  0  mx.π.test.ex.
+xn--1xa      MX  0  mx.xn--1xa.test.ex.
 
 ; -------- Testing SRV records --------
 
diff --git a/test/log/4201 b/test/log/4201
new file mode 100644 (file)
index 0000000..82f19c8
--- /dev/null
@@ -0,0 +1,95 @@
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= someone@some.domain H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com U=CALLER P=utf8local-esmtp S=sss for usery@test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmaZ-0005vi-00@the.local.host.name for usery@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => usery@test.ex F=<他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <usery@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= user.dontcare@test1.com U=CALLER P=local S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= user.dontcare@test1.com H=localhost (the.local.host.name) [127.0.0.1] P=esmtp S=sss id=E10HmbB-0005vi-00@the.local.host.name for userx@test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 => userx@test.ex F=<user.dontcare@test1.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= user.dontcare@test1.com U=CALLER P=local S=sss for user.他们为什么不说中文@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= user.dontcare@test1.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbD-0005vi-00@the.local.host.name for user.他们为什么不说中文@test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 => user.他们为什么不说中文@test.ex F=<user.dontcare@test1.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= 他们为什么不说中文@test1.com U=CALLER P=local S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= 他们为什么不说中文@test1.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbF-0005vi-00@the.local.host.name for userx@test.ex
+1999-03-02 09:44:33 10HmbF-0005vi-00 => userx@test.ex F=<他们为什么不说中文@test1.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <user.他们为什么不说中文@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local U=CALLER P=utf8local-esmtp S=sss for userz@test.ex
+1999-03-02 09:44:33 10HmbH-0005vi-00 ** userz@test.ex F=<यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1]: utf8 support required but not offered for forwarding
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= <> R=10HmbH-0005vi-00 U=EXIMUSER P=local S=sss for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+1999-03-02 09:44:33 10HmbI-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qfl
+1999-03-02 09:44:33 10HmbI-0005vi-00 => TESTSUITE/test-mail/यहलोगहिन्दीक्योंनहींबोलसकतेहैं <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> F=<> R=bounces T=local_delivery
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qfl
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userQ@test.ex
+1999-03-02 09:44:33 10HmbK-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbJ-0005vi-00@the.local.host.name for userQ@test.ex
+1999-03-02 09:44:33 10HmbJ-0005vi-00 => userq@test.ex <userQ@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbK-0005vi-00"
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbL-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userR@test.ex
+1999-03-02 09:44:33 10HmbM-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbL-0005vi-00@the.local.host.name for userR@test.ex
+1999-03-02 09:44:33 10HmbL-0005vi-00 => userr@test.ex <userR@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbM-0005vi-00"
+1999-03-02 09:44:33 10HmbL-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbK-0005vi-00 => :blackhole: <userQ@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbK-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbM-0005vi-00 => :blackhole: <userR@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbN-0005vi-00 <= userU@test.ex U=CALLER P=utf8local-esmtp S=sss for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbO-0005vi-00 <= userU@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbN-0005vi-00@the.local.host.name for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbN-0005vi-00 => user.γλυκύρριζα@test.ex F=<userU@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbO-0005vi-00"
+1999-03-02 09:44:33 10HmbN-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbO-0005vi-00 => :blackhole: <user.γλυκύρριζα@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbO-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbP-0005vi-00 <= userV.වැල්_මී@test.ex U=CALLER P=utf8local-esmtp S=sss for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbQ-0005vi-00 <= userV.වැල්_මී@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbP-0005vi-00@the.local.host.name for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbP-0005vi-00 => user.அதிமதுரம்@test.ex F=<userV.වැල්_මී@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbQ-0005vi-00"
+1999-03-02 09:44:33 10HmbP-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbR-0005vi-00 <= userW@test.ex U=CALLER P=utf8local-esmtp S=sss for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbS-0005vi-00 <= userW@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtp S=sss id=E10HmbR-0005vi-00@the.local.host.name for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbR-0005vi-00 => user.ഇരട്ടിമധുരം@test.ex F=<userW@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbS-0005vi-00"
+1999-03-02 09:44:33 10HmbR-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbQ-0005vi-00 => :blackhole: <user.அதிமதுரம்@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbQ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbS-0005vi-00 => :blackhole: <user.ഇരട്ടിമധുരം@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbS-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
diff --git a/test/log/4211 b/test/log/4211
new file mode 100644 (file)
index 0000000..3453375
--- /dev/null
@@ -0,0 +1,74 @@
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= someone@some.domain H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com U=CALLER P=utf8local-esmtp S=sss for usery@test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmaZ-0005vi-00@the.local.host.name for usery@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => usery@test.ex F=<他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <usery@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local U=CALLER P=utf8local-esmtp S=sss for userz@test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** userz@test.ex F=<यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no: utf8 support required but not offered for forwarding
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+1999-03-02 09:44:33 10HmbC-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qfl
+1999-03-02 09:44:33 10HmbC-0005vi-00 => TESTSUITE/test-mail/यहलोगहिन्दीक्योंनहींबोलसकतेहैं <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> F=<> R=bounces T=local_delivery
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qfl
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userQ@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbD-0005vi-00@the.local.host.name for userQ@test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 => userq@test.ex <userQ@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userR@test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbF-0005vi-00@the.local.host.name for userR@test.ex
+1999-03-02 09:44:33 10HmbF-0005vi-00 => userr@test.ex <userR@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <userQ@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <userR@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= userU@test.ex U=CALLER P=utf8local-esmtp S=sss for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= userU@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbH-0005vi-00@the.local.host.name for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbH-0005vi-00 => user.γλυκύρριζα@test.ex F=<userU@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbI-0005vi-00"
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbI-0005vi-00 => :blackhole: <user.γλυκύρριζα@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= userV.වැල්_මී@test.ex U=CALLER P=utf8local-esmtp S=sss for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbK-0005vi-00 <= userV.වැල්_මී@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbJ-0005vi-00@the.local.host.name for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbJ-0005vi-00 => user.அதிமதுரம்@test.ex F=<userV.වැල්_මී@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbK-0005vi-00"
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbL-0005vi-00 <= userW@test.ex U=CALLER P=utf8local-esmtp S=sss for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbM-0005vi-00 <= userW@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbL-0005vi-00@the.local.host.name for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbL-0005vi-00 => user.ഇരട്ടിമധുരം@test.ex F=<userW@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmbM-0005vi-00"
+1999-03-02 09:44:33 10HmbL-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbK-0005vi-00 => :blackhole: <user.அதிமதுரம்@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbK-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbM-0005vi-00 => :blackhole: <user.ഇരട്ടിമധുരം@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
diff --git a/test/log/4221 b/test/log/4221
new file mode 100644 (file)
index 0000000..ddbbe8c
--- /dev/null
@@ -0,0 +1,74 @@
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= someone@some.domain H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com H=(client) [127.0.0.1] P=utf8esmtp S=sss for userx@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com U=CALLER P=utf8local-esmtp S=sss for usery@test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= 他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaZ-0005vi-00@the.local.host.name for usery@test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => usery@test.ex F=<他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <userx@test.ex> R=localuser
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <usery@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local U=CALLER P=utf8local-esmtp S=sss for userz@test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** userz@test.ex F=<यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no: utf8 support required but not offered for forwarding
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+1999-03-02 09:44:33 10HmbC-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qfl
+1999-03-02 09:44:33 10HmbC-0005vi-00 => TESTSUITE/test-mail/यहलोगहिन्दीक्योंनहींबोलसकतेहैं <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> F=<> R=bounces T=local_delivery
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qfl
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userQ@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbD-0005vi-00@the.local.host.name for userQ@test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 => userq@test.ex <userQ@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com U=CALLER P=utf8local-esmtp S=sss for userR@test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= 세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbF-0005vi-00@the.local.host.name for userR@test.ex
+1999-03-02 09:44:33 10HmbF-0005vi-00 => userr@test.ex <userR@test.ex> F=<세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <userQ@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <userR@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= userU@test.ex U=CALLER P=utf8local-esmtp S=sss for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= userU@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbH-0005vi-00@the.local.host.name for user.γλυκύρριζα@test.ex
+1999-03-02 09:44:33 10HmbH-0005vi-00 => user.γλυκύρριζα@test.ex F=<userU@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbI-0005vi-00"
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbI-0005vi-00 => :blackhole: <user.γλυκύρριζα@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= userV.වැල්_මී@test.ex U=CALLER P=utf8local-esmtp S=sss for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbK-0005vi-00 <= userV.වැල්_මී@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbJ-0005vi-00@the.local.host.name for user.அதிமதுரம்@test.ex
+1999-03-02 09:44:33 10HmbJ-0005vi-00 => user.அதிமதுரம்@test.ex F=<userV.වැල්_මී@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbK-0005vi-00"
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 10HmbL-0005vi-00 <= userW@test.ex U=CALLER P=utf8local-esmtp S=sss for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbM-0005vi-00 <= userW@test.ex H=localhost (the.local.host.name) [127.0.0.1] P=utf8esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbL-0005vi-00@the.local.host.name for user.ഇരട്ടിമധുരം@test.ex
+1999-03-02 09:44:33 10HmbL-0005vi-00 => user.ഇരട്ടിമധുരം@test.ex F=<userW@test.ex> R=rmt T=rmt_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbM-0005vi-00"
+1999-03-02 09:44:33 10HmbL-0005vi-00 Completed
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqff
+1999-03-02 09:44:33 10HmbK-0005vi-00 => :blackhole: <user.அதிமதுரம்@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbK-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbM-0005vi-00 => :blackhole: <user.ഇരട്ടിമധുരം@test.ex> R=localuser
+1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qqff
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
diff --git a/test/mail/4201.यहलोगहिन्दीक्योंनहींबोलसकतेहैं b/test/mail/4201.यहलोगहिन्दीक्योंनहींबोलसकतेहैं
new file mode 100644 (file)
index 0000000..2582388
--- /dev/null
@@ -0,0 +1,59 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Return-path: <>
+Envelope-to: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Delivery-date: Tue, 2 Mar 1999 09:44:33 +0000
+Received: from EXIMUSER by the.local.host.name with local (Exim x.yz)
+       id 10HmbI-0005vi-00
+       for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local; Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: userz@test.ex
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@the.local.host.name>
+To: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmbI-0005vi-00@the.local.host.name>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-body-linecount: 38
+X-message-linecount: 50
+X-received-count: 1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+  userz@test.ex
+  host 127.0.0.1 [127.0.0.1]
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global-delivery-status
+
+Reporting-MTA: dns; the.local.host.name
+
+Action: failed
+Final-Recipient: rfc822;userz@test.ex
+Status: 5.0.0
+Remote-MTA: dns; 127.0.0.1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global
+
+Return-path: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>
+Received: from CALLER (helo=client.ffail)
+       by the.local.host.name with utf8local-esmtp (Exim x.yz)
+       (envelope-from <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>)
+       id 10HmbH-0005vi-00
+       for userz@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Subject: test
+Message-Id: <E10HmbH-0005vi-00@the.local.host.name>
+From: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+body
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM--
+
diff --git a/test/mail/4211.यहलोगहिन्दीक्योंनहींबोलसकतेहैं b/test/mail/4211.यहलोगहिन्दीक्योंनहींबोलसकतेहैं
new file mode 100644 (file)
index 0000000..cb22035
--- /dev/null
@@ -0,0 +1,59 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Return-path: <>
+Envelope-to: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Delivery-date: Tue, 2 Mar 1999 09:44:33 +0000
+Received: from EXIMUSER by the.local.host.name with local (Exim x.yz)
+       id 10HmbC-0005vi-00
+       for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local; Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: userz@test.ex
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@the.local.host.name>
+To: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmbC-0005vi-00@the.local.host.name>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-body-linecount: 38
+X-message-linecount: 50
+X-received-count: 1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+  userz@test.ex
+  host 127.0.0.1 [127.0.0.1]
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global-delivery-status
+
+Reporting-MTA: dns; the.local.host.name
+
+Action: failed
+Final-Recipient: rfc822;userz@test.ex
+Status: 5.0.0
+Remote-MTA: dns; 127.0.0.1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global
+
+Return-path: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>
+Received: from CALLER (helo=client.ffail)
+       by the.local.host.name with utf8local-esmtp (Exim x.yz)
+       (envelope-from <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>)
+       id 10HmbB-0005vi-00
+       for userz@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Subject: test
+Message-Id: <E10HmbB-0005vi-00@the.local.host.name>
+From: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+body
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM--
+
diff --git a/test/mail/4221.यहलोगहिन्दीक्योंनहींबोलसकतेहैं b/test/mail/4221.यहलोगहिन्दीक्योंनहींबोलसकतेहैं
new file mode 100644 (file)
index 0000000..cb22035
--- /dev/null
@@ -0,0 +1,59 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Return-path: <>
+Envelope-to: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Delivery-date: Tue, 2 Mar 1999 09:44:33 +0000
+Received: from EXIMUSER by the.local.host.name with local (Exim x.yz)
+       id 10HmbC-0005vi-00
+       for यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local; Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: userz@test.ex
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@the.local.host.name>
+To: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmbC-0005vi-00@the.local.host.name>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-body-linecount: 38
+X-message-linecount: 50
+X-received-count: 1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+  userz@test.ex
+  host 127.0.0.1 [127.0.0.1]
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global-delivery-status
+
+Reporting-MTA: dns; the.local.host.name
+
+Action: failed
+Final-Recipient: rfc822;userz@test.ex
+Status: 5.0.0
+Remote-MTA: dns; 127.0.0.1
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/global
+
+Return-path: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>
+Received: from CALLER (helo=client.ffail)
+       by the.local.host.name with utf8local-esmtp (Exim x.yz)
+       (envelope-from <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local>)
+       id 10HmbB-0005vi-00
+       for userz@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Subject: test
+Message-Id: <E10HmbB-0005vi-00@the.local.host.name>
+From: यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+body
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM--
+
diff --git a/test/rejectlog/4201 b/test/rejectlog/4201
new file mode 100644 (file)
index 0000000..a8ced2c
--- /dev/null
@@ -0,0 +1,8 @@
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
diff --git a/test/rejectlog/4211 b/test/rejectlog/4211
new file mode 100644 (file)
index 0000000..90d7d73
--- /dev/null
@@ -0,0 +1,8 @@
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
diff --git a/test/rejectlog/4221 b/test/rejectlog/4221
new file mode 100644 (file)
index 0000000..067e530
--- /dev/null
@@ -0,0 +1,8 @@
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER F=<CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> rejected RCPT <userS@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> rejected RCPT <userT@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 H=localhost (the.local.host.name) [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no F=<> rejected RCPT <the.local.host.name-dddddddd-testing@test.ex>: relay not permitted
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userA@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userA@test.ex> rejected RCPT <user.यष्टिमधु@test.ex>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userB.જેઠીમધ@test.ex>: response to "EHLO the.local.host.name" from 127.0.0.1 [127.0.0.1] did not include SMTPUTF8
+1999-03-02 09:44:33 U=CALLER F=<userB.જેઠીમધ@test.ex> rejected RCPT <user.ქართული@test.ex>: Sender verify failed
index 2baf2ca..4a44278 100755 (executable)
@@ -413,6 +413,7 @@ RESET_AFTER_EXTRA_LINE_READ:
 
   # Random local part in callout cache testing
   s/myhost.test.ex-\d+-testing/myhost.test.ex-dddddddd-testing/;
+  s/the.local.host.name-\d+-testing/the.local.host.name-dddddddd-testing/;
 
   # File descriptor numbers may vary
   s/^writing data block fd=\d+/writing data block fd=dddd/;
@@ -844,7 +845,6 @@ RESET_AFTER_EXTRA_LINE_READ:
     next if /^SSL info: unknown state/;
     next if /^SSL info: SSLv2\/v3 write client hello A/;
     next if /^SSL info: SSLv3 read server key exchange A/;
-
     }
 
   # ======== stderr ========
@@ -1011,6 +1011,9 @@ RESET_AFTER_EXTRA_LINE_READ:
 
     next if /in\shosts_require_dane\?\sno\s\(option\sunset\)/x;
 
+    # Experimental_International
+    next if / in smtputf8_advertise_hosts\? no \(option unset\)/;
+
       # Skip some lines that Exim puts out at the start of debugging output
       # because they will be different in different binaries.
 
@@ -1027,6 +1030,8 @@ RESET_AFTER_EXTRA_LINE_READ:
                 /^Fixed never_users:/ ||
                 /^Size of off_t:/
                 );
+
+
       }
 
     next;
diff --git a/test/scripts/4200-International/4200 b/test/scripts/4200-International/4200
new file mode 100644 (file)
index 0000000..48918b7
--- /dev/null
@@ -0,0 +1,96 @@
+# Internationalised mail: expansions
+#
+# Sample strings taken from RFC3942
+
+exim -be
+
+utf-8 localpart to a-label:
+
+${utf8_localpart_to_alabel:\xD9\x84}
+xn--ghb
+
+${utf8_localpart_to_alabel:\xD9\x84\xD9\x8A\xD9\x87\xD9\x85\xD8\xA7\xD8\xA8\xD8\xAA\xD9\x83\xD9\x84\
+\xD9\x85\xD9\x88\xD8\xB4\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x8A\xD8\x9F}
+xn--egbpdaj6bu4bxfgehfvwxn
+
+a-label localpart to utf-8:
+
+${utf8_localpart_from_alabel:xn--ghb}
+${utf8_localpart_from_alabel:xn--egbpdaj6bu4bxfgehfvwxn}
+
+utf-8 domain to a-label:
+
+${utf8_domain_to_alabel:bogus.\xD9\x84.com}
+bogus.xn--ghb.com
+
+${utf8_domain_to_alabel:arabic.\xD9\x84\xD9\x8A\xD9\x87\xD9\x85\xD8\xA7\xD8\xA8\xD8\xAA\xD9\x83\xD9\x84\
+\xD9\x85\xD9\x88\xD8\xB4\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x8A\xD8\x9F.com}
+arabic.xn--egbpdaj6bu4bxfgehfvwxn.com
+
+${utf8_domain_to_alabel:simpl.chinese.\xE4\xBB\x96\xE4\xBB\xAC\xE4\xB8\xBA\xE4\xBB\x80\
+\xE4\xB9\x88\xE4\xB8\x8D\xE8\xAF\xB4\xE4\xB8\xAD\xE6\x96\x87.com}
+simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com
+
+${utf8_domain_to_alabel:trad.chinese.\xE4\xBB\x96\xE5\x80\x91\xE7\x88\xB2\xE4\xBB\x80\
+\xE9\xBA\xBD\xE4\xB8\x8D\xE8\xAA\xAA\xE4\xB8\xAD\xE6\x96\x87.com}
+trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com
+
+${utf8_domain_to_alabel:czech.\x50\x72\x6F\xC4\x8D\x70\x72\x6F\x73\x74\xC4\x9B\x6E\x65\
+\x6D\x6C\x75\x76\xC3\xAD\xC4\x8D\x65\x73\x6B\x79.com}
+czech.xn--Proprostnemluvesky-uyb24dma41a.com
+
+${utf8_domain_to_alabel:hebrew.\xD7\x9C\xD7\x9E\xD7\x94\xD7\x94\xD7\x9D\xD7\xA4\xD7\xA9\
+\xD7\x95\xD7\x98\xD7\x9C\xD7\x90\xD7\x9E\xD7\x93\xD7\x91\xD7\xA8\xD7\x99\xD7\x9D\xD7\xA2\
+\xD7\x91\xD7\xA8\xD7\x99\xD7\xAA.com}
+hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com
+
+${utf8_domain_to_alabel:hindi.\xE0\xA4\xAF\xE0\xA4\xB9\xE0\xA4\xB2\xE0\xA5\x8B\xE0\xA4\x97\
+\xE0\xA4\xB9\xE0\xA4\xBF\xE0\xA4\xA8\xE0\xA5\x8D\xE0\xA4\xA6\xE0\xA5\x80\xE0\xA4\x95\xE0\xA5\x8D\
+\xE0\xA4\xAF\xE0\xA5\x8B\xE0\xA4\x82\xE0\xA4\xA8\xE0\xA4\xB9\xE0\xA5\x80\xE0\xA4\x82\xE0\xA4\xAC\
+\xE0\xA5\x8B\xE0\xA4\xB2\xE0\xA4\xB8\xE0\xA4\x95\xE0\xA4\xA4\xE0\xA5\x87\xE0\xA4\xB9\xE0\xA5\x88\
+\xE0\xA4\x82.com}
+hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com
+
+${utf8_domain_to_alabel:japanese.\xE3\x81\xAA\xE3\x81\x9C\xE3\x81\xBF\xE3\x82\x93\xE3\x81\xAA\
+\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE3\x82\x92\xE8\xA9\xB1\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\
+\xE3\x82\x8C\xE3\x81\xAA\xE3\x81\x84\xE3\x81\xAE\xE3\x81\x8B.com}
+japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com
+
+# the a-label for the phrase in korean is too long for a domain label (63 byte limit)
+korean: ${utf8_localpart_to_alabel:\xEC\x84\xB8\xEA\xB3\x84\xEC\x9D\x98\xEB\xAA\xA8\xEB\x93\xA0\
+\xEC\x82\xAC\xEB\x9E\x8C\xEB\x93\xA4\xEC\x9D\xB4\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4\xEB\xA5\xBC\
+\xEC\x9D\xB4\xED\x95\xB4\xED\x95\x9C\xEB\x8B\xA4\xEB\xA9\xB4\xEC\x96\xBC\xEB\xA7\x88\xEB\x82\x98\
+\xEC\xA2\x8B\xEC\x9D\x84\xEA\xB9\x8C}
+korean: xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c
+
+${utf8_domain_to_alabel:russian.\xD0\xBF\xD0\xBE\xD1\x87\xD0\xB5\xD0\xBC\xD1\x83\xD0\xB6\
+\xD0\xB5\xD0\xBE\xD0\xBD\xD0\xB8\xD0\xBD\xD0\xB5\xD0\xB3\xD0\xBE\xD0\xB2\xD0\xBE\xD1\x80\
+\xD1\x8F\xD1\x82\xD0\xBF\xD0\xBE\xD1\x80\xD1\x83\xD1\x81\xD1\x81\xD0\xBA\xD0\xB8.com}
+russian.xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l.com
+
+${utf8_domain_to_alabel:spanish.\x50\x6F\x72\x71\x75\xC3\xA9\x6E\x6F\x70\x75\x65\x64\x65\
+\x6E\x73\x69\x6D\x70\x6C\x65\x6D\x65\x6E\x74\x65\x68\x61\x62\x6C\x61\x72\x65\x6E\x45\x73\
+\x70\x61\xC3\xB1\x6F\x6C.com}
+spanish.xn--PorqunopuedensimplementehablarenEspaol-fmd56a.com
+
+${utf8_domain_to_alabel:vietnamese.\x54\xE1\xBA\xA1\x69\x73\x61\x6F\x68\xE1\xBB\x8D\x6B\x68\
+\xC3\xB4\x6E\x67\x74\x68\xE1\xBB\x83\x63\x68\xE1\xBB\x89\x6E\xC3\xB3\x69\x74\x69\xE1\xBA\xBF\
+\x6E\x67\x56\x69\xE1\xBB\x87\x74.com}
+vietnamese.xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g.com
+
+a-label domain to utf-8:
+
+${utf8_domain_from_alabel:arab.xn--ghb.com}
+${utf8_domain_from_alabel:arab.xn--egbpdaj6bu4bxfgehfvwxn.com}
+${utf8_domain_from_alabel:simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com}
+${utf8_domain_from_alabel:trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com}
+${utf8_domain_from_alabel:czech.xn--Proprostnemluvesky-uyb24dma41a.com}
+${utf8_domain_from_alabel:hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com}
+${utf8_domain_from_alabel:hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com}
+${utf8_domain_from_alabel:japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com}
+korean: ${utf8_localpart_from_alabel:xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c}
+${utf8_domain_from_alabel:russian.xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l.com}
+${utf8_domain_from_alabel:spanish.xn--PorqunopuedensimplementehablarenEspaol-fmd56a.com}
+${utf8_domain_from_alabel:vietnamese.xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g.com}
+
+****
diff --git a/test/scripts/4200-International/4201 b/test/scripts/4200-International/4201
new file mode 100644 (file)
index 0000000..eb26006
--- /dev/null
@@ -0,0 +1,265 @@
+# Internationalised mail: smtp
+# Exim test configuration 4200
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# commandline/stdin input, normal rcpt & sender, forwarded
+exim -odi -f user.dontcare@test1.com userx@test.ex
+Test message 1.
+.
+****
+# commandline/stdin input, utf-8 rcpt, forwarded
+exim -odi -f user.dontcare@test1.com user.他们为什么不说中文@test.ex
+Test message 2.
+.
+****
+# commandline/stdin input, utf-8 sender, forwarded
+exim -odi -f 他们为什么不说中文@test1.com userx@test.ex
+Test message 3.
+.
+****
+#
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
+#
+#
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
diff --git a/test/scripts/4200-International/REQUIRES b/test/scripts/4200-International/REQUIRES
new file mode 100644 (file)
index 0000000..c66f680
--- /dev/null
@@ -0,0 +1 @@
+support Experimental_International
diff --git a/test/scripts/4210-GnuTLS-International/4211 b/test/scripts/4210-GnuTLS-International/4211
new file mode 100644 (file)
index 0000000..2e13f3f
--- /dev/null
@@ -0,0 +1,246 @@
+# Internationalised mail: smtp
+# Exim test configuration 4200
+gnutls
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
+#
+#
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
diff --git a/test/scripts/4210-GnuTLS-International/REQUIRES b/test/scripts/4210-GnuTLS-International/REQUIRES
new file mode 100644 (file)
index 0000000..d75e950
--- /dev/null
@@ -0,0 +1,2 @@
+support Experimental_International
+support GnuTLS
diff --git a/test/scripts/4220-OpenSSL-International/4221 b/test/scripts/4220-OpenSSL-International/4221
new file mode 100644 (file)
index 0000000..e06ecd3
--- /dev/null
@@ -0,0 +1,245 @@
+# Internationalised mail: smtp
+# Exim test configuration 4200
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
+#
+#
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
diff --git a/test/scripts/4220-OpenSSL-International/REQUIRES b/test/scripts/4220-OpenSSL-International/REQUIRES
new file mode 100644 (file)
index 0000000..74b249f
--- /dev/null
@@ -0,0 +1,2 @@
+support Experimental_International
+support OpenSSL
index a634ad5..bb642b0 100644 (file)
@@ -341,7 +341,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 062aaaf..fd5795b 100644 (file)
@@ -243,7 +243,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: CALLER@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 5b93c6e..43bcdbf 100644 (file)
@@ -240,7 +240,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: kilos@recurse.test.ex.test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r3
 DSN: processing successful delivery address: kilos@recurse.test.ex.test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -248,7 +248,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: kilos@recurse.test.ex.test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaY-0005vi-00
index 086297c..3232ada 100644 (file)
@@ -329,7 +329,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: 2@b
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
@@ -505,7 +505,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: 2@b
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaY-0005vi-00
index ec373f5..c0a03d3 100644 (file)
@@ -568,7 +568,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userz@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r2
 DSN: processing successful delivery address: usery@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -576,7 +576,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: usery@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r1
 DSN: processing successful delivery address: CALLER@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -584,7 +584,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: CALLER@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r4
 DSN: processing successful delivery address: TESTSUITE/test-mail/junk
 DSN: Sender_address: CALLER@test.ex
@@ -592,7 +592,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: TESTSUITE/test-mail/junk
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r5
 DSN: processing successful delivery address: TESTSUITE/test-mail/junk
 DSN: Sender_address: CALLER@test.ex
@@ -600,7 +600,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: TESTSUITE/test-mail/junk
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r4
 DSN: processing successful delivery address: rd+CALLER@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -608,7 +608,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: rd+CALLER@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r5
 DSN: processing successful delivery address: rd+usery@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -616,7 +616,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: rd+usery@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 27b209d..96e990b 100644 (file)
@@ -191,7 +191,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: TESTSUITE/test-mail/junk
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r1
 DSN: processing successful delivery address: userx@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -199,7 +199,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 9d04fe5..1f791c4 100644 (file)
@@ -18020,7 +18020,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: sender@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaY-0005vi-00
@@ -18057,7 +18057,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: >sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex, ...
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r2
 DSN: processing successful delivery address: userx@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -18065,7 +18065,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index f578e30..67fe44c 100644 (file)
@@ -181,7 +181,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index e3217ab..c8d720b 100644 (file)
@@ -184,7 +184,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 8c0bdb0..cc1864a 100644 (file)
@@ -457,7 +457,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@myhost.test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index f8d86b7..5014887 100644 (file)
@@ -181,7 +181,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: TESTSUITE/test-mail
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 DSN: processing router : r1
 DSN: processing successful delivery address: userx@test.ex
 DSN: Sender_address: CALLER@test.ex
@@ -189,7 +189,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 8a9536a..ae0dbba 100644 (file)
@@ -173,7 +173,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: nofile@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
@@ -357,7 +357,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaY-0005vi-00
index 72b650f..9df6ced 100644 (file)
@@ -171,7 +171,7 @@ DSN: orcpt: NULL  flags: 0
 DSN: envid: NULL  ret: 0
 DSN: Final recipient: userx@test.ex
 DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
 LOG: MAIN
   Completed
 end delivery of 10HmaX-0005vi-00
index 6b561f7..f5b5dce 100644 (file)
@@ -1,4 +1,5 @@
 syntax error: domain missing or malformed
-bounce@π.test.ex
+bounce@xn--1xa.test.ex
+    <-- bounce@π.test.ex
   router = r1, transport = t1
-  host mx.π.test.ex [V4NET.255.255.255] MX=0
+  host mx.xn--1xa.test.ex [V4NET.255.255.255] MX=0
diff --git a/test/stdout/4200 b/test/stdout/4200
new file mode 100644 (file)
index 0000000..1cfb7a9
--- /dev/null
@@ -0,0 +1,69 @@
+> 
+> utf-8 localpart to a-label:
+> 
+> xn--ghb
+> xn--ghb
+> 
+> xn--egbpdaj6bu4bxfgehfvwxn
+> xn--egbpdaj6bu4bxfgehfvwxn
+> 
+> a-label localpart to utf-8:
+> 
+> ل
+> ليهمابتكلموشعربي؟
+> 
+> utf-8 domain to a-label:
+> 
+> bogus.xn--ghb.com
+> bogus.xn--ghb.com
+> 
+> arabic.xn--egbpdaj6bu4bxfgehfvwxn.com
+> arabic.xn--egbpdaj6bu4bxfgehfvwxn.com
+> 
+> simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com
+> simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com
+> 
+> trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com
+> trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com
+> 
+> czech.xn--proprostnemluvesky-uyb24dma41a.com
+> czech.xn--Proprostnemluvesky-uyb24dma41a.com
+> 
+> hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com
+> hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com
+> 
+> hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com
+> hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com
+> 
+> japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com
+> japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com
+> 
+> # the a-label for the phrase in korean is too long for a domain label (63 byte limit)
+> korean: xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c
+> korean: xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c
+> 
+> russian.xn--b1abfaaepdrnnbgefbadotcwatmq2g4l.com
+> russian.xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l.com
+> 
+> spanish.xn--porqunopuedensimplementehablarenespaol-fmd56a.com
+> spanish.xn--PorqunopuedensimplementehablarenEspaol-fmd56a.com
+> 
+> vietnamese.xn--tisaohkhngthchnitingvit-kjcr8268qyxafd2f1b9g.com
+> vietnamese.xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g.com
+> 
+> a-label domain to utf-8:
+> 
+> arab.ل.com
+> arab.ليهمابتكلموشعربي؟.com
+> simpl.chinese.他们为什么不说中文.com
+> trad.chinese.他們爲什麽不說中文.com
+> czech.Pročprostěnemluvíčesky.com
+> hebrew.למההםפשוטלאמדבריםעברית.com
+> hindi.यहलोगहिन्दीक्योंनहींबोलसकतेहैं.com
+> japanese.なぜみんな日本語を話してくれないのか.com
+> korean: 세계의모든사람들이한국어를이해한다면얼마나좋을까
+> russian.почемужеонинеговорятпорусски.com
+> spanish.PorquénopuedensimplementehablarenEspañol.com
+> vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.com
+> 
+> 
diff --git a/test/stdout/4201 b/test/stdout/4201
new file mode 100644 (file)
index 0000000..2baa666
--- /dev/null
@@ -0,0 +1,208 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaX-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaY-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaZ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbH-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbJ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbL-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbN-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbP-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbR-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userA@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userB.જેઠીમધ@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r
diff --git a/test/stdout/4211 b/test/stdout/4211
new file mode 100644 (file)
index 0000000..18eec32
--- /dev/null
@@ -0,0 +1,223 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaX-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaY-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaZ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbD-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbF-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbH-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbJ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbL-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userA@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userB.જેઠીમધ@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r
diff --git a/test/stdout/4221 b/test/stdout/4221
new file mode 100644 (file)
index 0000000..18eec32
--- /dev/null
@@ -0,0 +1,223 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaX-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO client
+??? 250-
+<<< 250-the.local.host.name Hello client [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250-SMTPUTF8
+<<< 250-SMTPUTF8
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+<<< 250 OK
+>>> RCPT TO: <userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: test
+>>> 
+>>> body
+>>> .
+??? 250
+<<< 250 OK id=10HmaY-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaZ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbD-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbF-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.ffail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+533 mailbox name not allowed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbH-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbJ-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.bh\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbL-0005vi-00\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userA@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at client.sfail\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-STARTTLS\r
+250-SMTPUTF8\r
+250 HELP\r
+250 OK\r
+550-Callback setup failed while verifying <userB.જેઠીમધ@test.ex>\r
+550-533 mailbox name not allowed\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 the.local.host.name closing connection\r