]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20140720
authorWietse Venema <wietse@porcupine.org>
Sun, 20 Jul 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Tue, 22 Jul 2014 12:32:01 +0000 (08:32 -0400)
21 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/WISHLIST
postfix/html/bounce.5.html
postfix/html/postconf.5.html
postfix/man/man5/bounce.5
postfix/man/man5/postconf.5
postfix/proto/bounce
postfix/proto/postconf.proto
postfix/src/bounce/Makefile.in
postfix/src/bounce/bounce_notify_util.c
postfix/src/bounce/bounce_service.h
postfix/src/bounce/bounce_template.c
postfix/src/global/mail_version.h
postfix/src/global/uxtext.c
postfix/src/global/xtext.c
postfix/src/util/Makefile.in
postfix/src/util/mac_expand.c
postfix/src/util/mac_expand.h
postfix/src/util/midna.c
postfix/src/util/midna.h

index c690ce828ff9ef03cb4fce2cc1544ec4fda8fcba..37dcdeaef67cfd4f2e7f07a9349e712924b537ea 100644 (file)
@@ -26,6 +26,7 @@
 -TBOUNCE_LOG_FORGE
 -TBOUNCE_LOG_RCPT_BUF
 -TBOUNCE_STAT
+-TBOUNCE_STR_PARAMETER
 -TBOUNCE_TEMPLATE
 -TBOUNCE_TEMPLATES
 -TBOUNCE_TIME_DIVISOR
index 51ea7b184443f05648b99af5bd57da367e6aa597..00297dba253e447c01010511862a89b72ca7aded 100644 (file)
@@ -20261,3 +20261,18 @@ Apologies for any names omitted.
 
        Cleanup: hard-coded GCC dependencies. Eray Aslan. File:
        makedefs.
+
+20140717
+
+       Safety: manipulate unsigned characters while decoding.
+       Files: global/xtext.c, global/uxtext.c.
+
+       Infrastructure: ACE label to UTF-8 conversion. Files:
+       util/midna.[hc].
+
+       Infrastructure: macro expansion with printable() filter.
+       Files: util/mac_expand.[hc].
+
+       Feature: when expanding myhostname or mydomain in bounce
+       template messages, and smtputf8_enable=yes, convert ACE
+       (xn--mumble) labels into UTF-8.  bounce/bounce_template.c.
index 7f4be0f6b53321770bb5a14e30eeaf3a306df50e..dffb68ea29a4fec21ee1b6fe02816ab4bf3cb013 100644 (file)
@@ -8,6 +8,11 @@ Wish list:
 
        Things to do after the stable release:
 
+       up-convert myhostname in MIME boundary strings?
+
+       Table-driven case folding and case-insensitive string 
+       comparison specifically for UTF-8.
+
        When downgrading message/global to 7bit, is quoted-printable
        the appropriate encoding? Should it be base64?
 
index 1c0860e97c6def99383acbe830abbe3a4ab00c61..18051cd402c0aeaeadf0734df72bcff2cb740c98 100644 (file)
@@ -16,16 +16,16 @@ BOUNCE(5)                                                            BOUNCE(5)
 
 <b>DESCRIPTION</b>
        The  Postfix  <a href="bounce.8.html"><b>bounce</b>(8)</a>  server  produces  delivery status notification
-       (DSN) messages for undeliverable mail, delayed mail, successful  deliv-
+       (DSN) messages for undeliverable mail, delayed mail, successful  deliv
        ery or address verification requests.
 
        By  default,  these notifications are generated from built-in templates
        with message headers and message text. Sites can override the  built-in
-       information  by  specifying a bounce template file with the <b><a href="postconf.5.html#bounce_template_file">bounce_tem</a>-</b>
-       <b><a href="postconf.5.html#bounce_template_file">plate_file</a></b> configuration parameter.
+       information  by  specifying a bounce template file with the <b>bounce_tem</b>‐\b
+       <b>plate_file</b> configuration parameter.
 
-       This document describes the general procedure to create a  bounce  tem-
-       plate  file,  followed  by the specific details of bounce template for-
+       This document describes the general procedure to create a  bounce  tem
+       plate  file,  followed  by the specific details of bounce template for
        mats.
 
 <b>GENERAL PROCEDURE</b>
@@ -44,7 +44,7 @@ BOUNCE(5)                                                            BOUNCE(5)
        expansion of time value parameters that  appear  in  the  delayed  mail
        notification text.
 
-       Once  the result is satisfactory, copy the template to the Postfix con-
+       Once  the result is satisfactory, copy the template to the Postfix con
        figuration directory and specify in <a href="postconf.5.html">main.cf</a> something like:
 
        /etc/postfix/<a href="postconf.5.html">main.cf</a>:
@@ -53,13 +53,13 @@ BOUNCE(5)                                                            BOUNCE(5)
 <b>TEMPLATE FILE FORMAT</b>
        The template file can specify templates for failed mail, delayed  mail,
        successful  delivery  or for address verification.  These templates are
-       named  <b>failure_template</b>,  <b>delay_template</b>,  <b>success_template</b>  and   <b>ver-</b>
+       named  <b>failure_template</b>,  <b>delay_template</b>,  <b>success_template</b>  and   <b>ver</b>‐\b
        <b>ify_template</b>,  respectively.   You  can  but do not have to specify all
        four templates in a bounce template file.
 
        Each template starts with "<i>template</i><b>_</b><i>name</i> <b>=</b> &lt;&lt;<b>EOF</b>" and ends with a  line
        that contains the word "<b>EOF</b>" only. You can change the word EOF, but you
-       can't enclose it in quotes  as  with  the  shell  or  with  Perl  (<i>tem-</i>
+       can't enclose it in quotes  as  with  the  shell  or  with  Perl  (<i>tem</i>
        <i>plate</i><b>_</b><i>name</i> <b>=</b> &lt;&lt;<b>'EOF'</b>). Here is an example:
 
            # The failure template is used for undeliverable mail.
@@ -83,16 +83,16 @@ BOUNCE(5)                                                            BOUNCE(5)
                               The mail system
            EOF
 
-       The  usage and specification of bounce templates is subject to the fol-
+       The  usage and specification of bounce templates is subject to the fol
        lowing restrictions:
 
-       <b>o</b>      No special meaning is given to the  backslash  character  or  to
+       ·      No special meaning is given to the  backslash  character  or  to
               leading whitespace; these are always taken literally.
 
-       <b>o</b>      Inside  the &lt;&lt; context, the "$" character is special. To produce
+       ·      Inside  the &lt;&lt; context, the "$" character is special. To produce
               a "$" character as output, specify "$$".
 
-       <b>o</b>      Outside the &lt;&lt; context, lines beginning with "#" are ignored, as
+       ·      Outside the &lt;&lt; context, lines beginning with "#" are ignored, as
               are empty lines, and lines consisting of whitespace only.
 
        Examples of all templates can be found in the file <b>bounce.cf.default</b> in
@@ -100,7 +100,7 @@ BOUNCE(5)                                                            BOUNCE(5)
 
 <b>TEMPLATE HEADER FORMAT</b>
        The first portion of a bounce template consists  of  optional  template
-       headers.   Some become message headers in the delivery status notifica-
+       headers.   Some become message headers in the delivery status notifica
        tion; some control the formatting of  that  notification.  Headers  not
        specified in a template will be left at their default value.
 
@@ -114,26 +114,26 @@ BOUNCE(5)                                                            BOUNCE(5)
               notification.
 
        <b>Subject:</b>
-              The subject in the message header of the delivery status notifi-
+              The subject in the message header of the delivery status notifi
               cation that is returned to the sender.
 
        <b>Postmaster-Subject:</b>
-              The subject that will be used in Postmaster copies of undeliver-
+              The subject that will be used in Postmaster copies of undeliver
               able  or delayed mail notifications. These copies are sent under
               control of the <a href="postconf.5.html#notify_classes">notify_classes</a> configuration parameter.
 
        The usage and specification of template message headers is  subject  to
        the following restrictions:
 
-       <b>o</b>      Template  message  header  names can be specified in upper case,
+       ·      Template  message  header  names can be specified in upper case,
               lower case or mixed case. Postfix always produces bounce message
               header labels of the form "<b>From:</b>" and "<b>Subject:</b>".
 
-       <b>o</b>      Template message headers must not span multiple lines.
+       ·      Template message headers must not span multiple lines.
 
-       <b>o</b>      Template message headers do not support $parameter expansions.
+       ·      Template message headers do not support $parameter expansions.
 
-       <b>o</b>      Template message headers must contain ASCII characters only, and
+       ·      Template message headers must contain ASCII characters only, and
               must not contain ASCII null characters.
 
 <b>TEMPLATE MESSAGE TEXT FORMAT</b>
@@ -153,16 +153,30 @@ BOUNCE(5)                                                            BOUNCE(5)
               expressed in the time unit specified by <i>suffix</i>.  See above under
               <b><a href="postconf.5.html#delay_warning_time">delay_warning_time</a></b> for possible <i>suffix</i> values.
 
+       <b><a href="postconf.5.html#mydomain">mydomain</a></b>
+              Expands into the value of the <b><a href="postconf.5.html#mydomain">mydomain</a></b>  parameter.   With  "smt‐
+              putf8_enable  = yes", this replaces ACE labels (xn--mumble) with
+              their UTF-8 equivalent.
+
+              This feature is available in Postfix 2.12.
+
+       <b><a href="postconf.5.html#myhostname">myhostname</a></b>
+              Expands into the value of the <b><a href="postconf.5.html#myhostname">myhostname</a></b> parameter.  With  "smt‐
+              putf8_enable  = yes", this replaces ACE labels (xn--mumble) with
+              their UTF-8 equivalent.
+
+              This feature is available in Postfix 2.12.
+
        The usage and specification of template message text is subject to  the
        following restrictions:
 
-       <b>o</b>      The  template  message  text is not sent in Postmaster copies of
+       ·      The  template  message  text is not sent in Postmaster copies of
               delivery status notifications.
 
-       <b>o</b>      If the template  message  text  contains  non-ASCII  characters,
+       ·      If the template  message  text  contains  non-ASCII  characters,
               Postfix  requires  that the <b>Charset:</b> template header is updated.
               Specify an appropriate superset  of  US-ASCII.   A  superset  is
-              needed because Postfix appends ASCII text after the message tem-
+              needed because Postfix appends ASCII text after the message tem
               plate when it sends a delivery status notification.
 
 <b>SEE ALSO</b>
index 90a52c4fa204ec24694559fb3996b80e49ee24d7..8af0a3cce3f591ed5b57fe55eee39342bc6c99d1 100644 (file)
@@ -16413,13 +16413,12 @@ daemon. </dd>
 daemon. </dd>
 
 <dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing.  When
-a message is received with "SMTPUTF8 requested", then the forwarded
-(aliased) message automatically has "SMTPUTF8 requested".  </dd>
+a message is received with "SMTPUTF8 required", then the forwarded
+(aliased) message always has "SMTPUTF8 required".  </dd>
 
 <dt> <b> bounce </b> </dt> <dd> Submission by the <a href="bounce.8.html">bounce(8)</a> daemon.
-When a message is received with "SMTPUTF8 requested", then the
-delivery status notification automatically has "SMTPUTF8 requested".
-</dd>
+When a message is received with "SMTPUTF8 required", then the
+delivery status notification always has "SMTPUTF8 required".  </dd>
 
 <dt> <b> notify </b> </dt> <dd> Postmaster notification from the
 <a href="smtp.8.html">smtp(8)</a> or <a href="smtpd.8.html">smtpd(8)</a> daemon. </dd>
index f039f1810409718a3460c92884a852ffc456ae35..b8aa51bcad479be350121a655584ed26d8db0f19 100644 (file)
@@ -178,6 +178,18 @@ Expands into the value of the \fBmaximal_queue_lifetime\fR
 parameter, expressed in the time unit specified by
 \fIsuffix\fR.  See above under \fBdelay_warning_time\fR for
 possible \fIsuffix\fR values.
+.IP \fBmydomain\fR
+Expands into the value of the \fBmydomain\fR parameter.
+With "smtputf8_enable = yes", this replaces ACE labels
+(xn--mumble) with their UTF-8 equivalent.
+.sp
+This feature is available in Postfix 2.12.
+.IP \fBmyhostname\fR
+Expands into the value of the \fBmyhostname\fR parameter.
+With "smtputf8_enable = yes", this replaces ACE labels
+(xn--mumble) with their UTF-8 equivalent.
+.sp
+This feature is available in Postfix 2.12.
 .PP
 The usage and specification of template message text is
 subject to the following restrictions:
index 7c73e1d075c7e20701b0095023f3e3c1b5c35cab..50471fc47b0cbc9e5e6c1f387c5015db2346578a 100644 (file)
@@ -11229,13 +11229,13 @@ daemon.
 .br
 .IP "\fB forward \fR"
 Local forwarding or aliasing.  When
-a message is received with "SMTPUTF8 requested", then the forwarded
-(aliased) message automatically has "SMTPUTF8 requested".
+a message is received with "SMTPUTF8 required", then the forwarded
+(aliased) message always has "SMTPUTF8 required".
 .br
 .IP "\fB bounce \fR"
 Submission by the \fBbounce\fR(8) daemon.
-When a message is received with "SMTPUTF8 requested", then the
-delivery status notification automatically has "SMTPUTF8 requested".
+When a message is received with "SMTPUTF8 required", then the
+delivery status notification always has "SMTPUTF8 required".
 .br
 .IP "\fB notify \fR"
 Postmaster notification from the
index a76da97c7e7e765e99e546a0d78bb258e033a042..b838f5c3ae0595b9e56987add9a58fe187d9ea33 100644 (file)
 #      parameter, expressed in the time unit specified by
 #      \fIsuffix\fR.  See above under \fBdelay_warning_time\fR for
 #      possible \fIsuffix\fR values.
+# .IP \fBmydomain\fR
+#      Expands into the value of the \fBmydomain\fR parameter.
+#      With "smtputf8_enable = yes", this replaces ACE labels
+#      (xn--mumble) with their UTF-8 equivalent.
+# .sp
+#      This feature is available in Postfix 2.12.
+# .IP \fBmyhostname\fR
+#      Expands into the value of the \fBmyhostname\fR parameter.
+#      With "smtputf8_enable = yes", this replaces ACE labels
+#      (xn--mumble) with their UTF-8 equivalent.
+# .sp
+#      This feature is available in Postfix 2.12.
 # .PP
 #      The usage and specification of template message text is
 #      subject to the following restrictions:
index 98a82e2f04009489855153d77aec7e2dce495ec2..908d19dbc123ab1498d39a603467aea85790af4c 100644 (file)
@@ -16097,13 +16097,12 @@ daemon. </dd>
 daemon. </dd>
 
 <dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing.  When
-a message is received with "SMTPUTF8 requested", then the forwarded
-(aliased) message automatically has "SMTPUTF8 requested".  </dd>
+a message is received with "SMTPUTF8 required", then the forwarded
+(aliased) message always has "SMTPUTF8 required".  </dd>
 
 <dt> <b> bounce </b> </dt> <dd> Submission by the bounce(8) daemon.
-When a message is received with "SMTPUTF8 requested", then the
-delivery status notification automatically has "SMTPUTF8 requested".
-</dd>
+When a message is received with "SMTPUTF8 required", then the
+delivery status notification always has "SMTPUTF8 required".  </dd>
 
 <dt> <b> notify </b> </dt> <dd> Postmaster notification from the
 smtp(8) or smtpd(8) daemon. </dd>
index 3206537a55343460bb472514ca366e2c65f96d8e..1fd913f5c218eac14250c234911830ddc8fdd73d 100644 (file)
@@ -298,6 +298,7 @@ bounce_template.o: ../../include/mac_parse.h
 bounce_template.o: ../../include/mail_conf.h
 bounce_template.o: ../../include/mail_params.h
 bounce_template.o: ../../include/mail_proto.h
+bounce_template.o: ../../include/midna.h
 bounce_template.o: ../../include/msg.h
 bounce_template.o: ../../include/mymalloc.h
 bounce_template.o: ../../include/split_at.h
index e1c27a122accece2590e689d435c2f9aa6b65a4b..d48b7794870f8b32ac300a6cb0a6b8004ef60147 100644 (file)
@@ -227,18 +227,19 @@ static BOUNCE_INFO *bounce_mail_alloc(const char *service,
     /*
      * Bundle up a bunch of parameters and initialize information that will
      * be discovered on the fly.
+     * 
+     * XXX Instead of overriding the returned-message MIME encoding, separate
+     * the returned-message MIME encoding from the (boiler plate, delivery
+     * status) MIME encoding.
      */
     bounce_info = (BOUNCE_INFO *) mymalloc(sizeof(*bounce_info));
     bounce_info->service = service;
     bounce_info->queue_name = queue_name;
     bounce_info->queue_id = queue_id;
     bounce_info->smtputf8 = smtputf8;
-    /* Fix 20140708: propagate smtputf8 attribute to bounce message. */
-    bounce_info->smtputf8_attr =
-       vstring_export(vstring_sprintf(vstring_alloc(20), "%s=%d",
-                                      MAIL_ATTR_SMTPUTF8, smtputf8));
     /* Fix 20140708: override MIME encoding: addresses may be 8bit. */
-    if (bounce_info->smtputf8) {
+    /* Fix 20140718: override MIME encoding: 8bit $myhostname expansion. */
+    if (var_smtputf8_enable /* was: bounce_info->smtputf8 */ ) {
        bounce_info->mime_encoding = "8bit";
     } else if (strcmp(encoding, MAIL_ATTR_ENC_8BIT) == 0) {
        bounce_info->mime_encoding = "8bit";
@@ -442,7 +443,6 @@ void    bounce_mail_free(BOUNCE_INFO *bounce_info)
                 bounce_info->queue_id);
     vstring_free(bounce_info->buf);
     vstring_free(bounce_info->sender);
-    myfree(bounce_info->smtputf8_attr);
     myfree(bounce_info->mail_name);
     myfree((char *) bounce_info->mime_boundary);
     myfree((char *) bounce_info);
@@ -460,6 +460,7 @@ int     bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
      * headers and will make all addresses fully qualified.
      */
 #define STREQ(a, b) (strcasecmp((a), (b)) == 0)
+#define STRNE(a, b) (strcasecmp((a), (b)) != 0)
 
     /*
      * Generic headers.
@@ -493,15 +494,25 @@ int     bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
     /*
      * MIME header.
      */
+#define NOT_US_ASCII(tp) \
+       STRNE(bounce_template_charset(template), "us-ascii")
+
+#define NOT_7BIT_MIME(bp) \
+       (bp->mime_encoding && STRNE(bp->mime_encoding, MAIL_ATTR_ENC_7BIT))
+
     post_mail_fputs(bounce, "");
     post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
     post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
+    /* Fix 20140718: UTF-8 address or $myhostname expansion. */
     post_mail_fprintf(bounce, "Content-Type: %s; charset=%s",
-                     "text/plain", bounce_template_charset(template));
+                     "text/plain", NOT_US_ASCII(template) ?
+                     bounce_template_charset(template) :
+                     NOT_7BIT_MIME(bounce_info) ?
+                     "utf-8" : "us-ascii");
     /* Fix 20140709: addresses may be 8bit. */
-    if (bounce_info->smtputf8)
+    if (NOT_7BIT_MIME(bounce_info))
        post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
-                           bounce_info->mime_encoding);
+                         bounce_info->mime_encoding);
     post_mail_fputs(bounce, "");
 
     return (vstream_ferror(bounce));
@@ -626,7 +637,7 @@ int     bounce_header_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
                      (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED) ?
                      "global-" : "");
     /* Fix 20140709: addresses may be 8bit. */
-    if (bounce_info->smtputf8)
+    if (NOT_7BIT_MIME(bounce_info))
        post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
                          bounce_info->mime_encoding);
 
@@ -647,13 +658,15 @@ int     bounce_header_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
     }
     post_mail_fprintf(bounce, "X-%s-Queue-ID: %s",
                      bounce_info->mail_name, bounce_info->queue_id);
+
+#define IS_UTF8_ADDRESS(str, len) \
+       ((str)[0] != 0 && !allascii(str) && valid_utf8_string((str), (len)))
+
     /* Fix 20140708: use "utf-8" or "rfc822" as appropriate. */
     if (VSTRING_LEN(bounce_info->sender) > 0)
        post_mail_fprintf(bounce, "X-%s-Sender: %s; %s",
                          bounce_info->mail_name, bounce_info->smtputf8
-                         && STR(bounce_info->sender)[0]
-                         && !allascii(STR(bounce_info->sender))
-                         && valid_utf8_string(STR(bounce_info->sender),
+                         && IS_UTF8_ADDRESS(STR(bounce_info->sender),
                                         VSTRING_LEN(bounce_info->sender)) ?
                          "utf-8" : "rfc822", STR(bounce_info->sender));
     if (bounce_info->arrival_time > 0)
@@ -672,10 +685,9 @@ int     bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
     post_mail_fputs(bounce, "");
     /* Fix 20140708: Don't send "utf-8" type with non-UTF8 address. */
     post_mail_fprintf(bounce, "Final-Recipient: %s; %s",
-                     bounce_info->smtputf8 && rcpt->address[0]
-                     && !allascii(rcpt->address)
-                     && valid_utf8_string(rcpt->address,
-                                          strlen(rcpt->address)) ?
+                     bounce_info->smtputf8
+                     && IS_UTF8_ADDRESS(rcpt->address,
+                                        strlen(rcpt->address)) ?
                      "utf-8" : "rfc822", rcpt->address);
 
     /*
@@ -702,10 +714,9 @@ int     bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
     } else if (NON_NULL_EMPTY(rcpt->orig_addr)) {
        /* Fix 20140708: Don't send "utf-8" type with non-UTF8 address. */
        post_mail_fprintf(bounce, "Original-Recipient: %s; %s",
-                         bounce_info->smtputf8 && rcpt->orig_addr[0]
-                         && !allascii(rcpt->orig_addr)
-                         && valid_utf8_string(rcpt->orig_addr,
-                                              strlen(rcpt->orig_addr)) ?
+                         bounce_info->smtputf8
+                         && IS_UTF8_ADDRESS(rcpt->orig_addr,
+                                            strlen(rcpt->orig_addr)) ?
                          "utf-8" : "rfc822", rcpt->orig_addr);
     }
     post_mail_fprintf(bounce, "Action: %s",
@@ -807,7 +818,7 @@ int     bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
        post_mail_fprintf(bounce, "Content-Type: %s",
                          headers_only == DSN_RET_HDRS ?
                          "text/rfc822-headers" : "message/rfc822");
-    if (bounce_info->mime_encoding)
+    if (NOT_7BIT_MIME(bounce_info))
        post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
                          bounce_info->mime_encoding);
     post_mail_fputs(bounce, "");
index 9ba5ca5038c91eb2789cb46392c8e127b7206f99..f8cc4d6dcc2189290ca2034f7685f7939bb3307c 100644 (file)
@@ -85,7 +85,6 @@ typedef struct {
     BOUNCE_LOG *log_handle;            /* open logfile */
     char   *mail_name;                 /* $mail_name, cooked */
     int     smtputf8;                  /* SMTPUTF8 requested */
-    char   *smtputf8_attr;             /* pre-formatted record value */
 } BOUNCE_INFO;
 
  /* */
index 7888a1867a254cf97e9522cc385884231328d29b..f5b7e19a15c2322f4186d32e0495f810847d6fb0 100644 (file)
 #include <split_at.h>
 #include <stringops.h>
 #include <mymalloc.h>
+#ifndef NO_EAI
+#include <midna.h>
+#endif
 
 /* Global library. */
 
@@ -198,6 +201,21 @@ static const BOUNCE_TIME_PARAMETER time_parameter[] = {
     0, 0,
 };
 
+ /*
+  * Parameters whose value may have to be converted to UTF-8 for presentation
+  * purposes.
+  */
+typedef struct {
+    const char *param_name;            /* parameter name */
+    char  **value;                     /* parameter value */
+} BOUNCE_STR_PARAMETER;
+
+static const BOUNCE_STR_PARAMETER str_parameter[] = {
+    VAR_MYHOSTNAME, &var_myhostname,
+    VAR_MYDOMAIN, &var_mydomain,
+    0, 0,
+};
+
  /*
   * SLMs.
   */
@@ -387,8 +405,11 @@ static const char *bounce_template_lookup(const char *key, int unused_mode,
     BOUNCE_TEMPLATE *tp = (BOUNCE_TEMPLATE *) context;
     const BOUNCE_TIME_PARAMETER *bp;
     const BOUNCE_TIME_DIVISOR *bd;
+    const BOUNCE_STR_PARAMETER *sp;
     static VSTRING *buf;
     int     result;
+    const char *asc_val;
+    const char *utf8_val;
 
     /*
      * Look for parameter names that can have a time unit suffix, and scale
@@ -426,6 +447,33 @@ static const char *bounce_template_lookup(const char *key, int unused_mode,
                      key + bp->param_name_len + 1, key);
        }
     }
+
+    /*
+     * Look for parameter names that may have to be up-converted for
+     * presentation purposes.
+     */
+#ifndef NO_EAI
+    if (var_smtputf8_enable) {
+       for (sp = str_parameter; sp->param_name; sp++) {
+           if (strcmp(key, sp->param_name) == 0) {
+               asc_val = sp->value[0];
+               if (!allascii(asc_val)) {
+                   msg_warn("%s: conversion \"%s\" failed: "
+                            "non-ASCII input value: \"%s\"",
+                            tp->origin, key, asc_val);
+                   return (asc_val);
+               } else if ((utf8_val = midna_ascii_to_utf8(asc_val)) == 0) {
+                   msg_warn("%s: conversion \"%s\" failed: "
+                            "input value: \"%s\"",
+                            tp->origin, key, asc_val);
+                   return (asc_val);
+               } else {
+                   return (utf8_val);
+               }
+           }
+       }
+    }
+#endif
     return (mail_conf_lookup_eval(key));
 }
 
@@ -453,13 +501,12 @@ void    bounce_template_expand(BOUNCE_XP_PUT_FN out_fn, VSTREAM *fp,
     VSTRING *buf = vstring_alloc(100);
     const char **cpp;
     int     stat;
-    const char *filter = "\t !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
 
     if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER)
        bounce_template_parse_buffer(tp);
 
     for (cpp = tp->message_text; *cpp; cpp++) {
-       stat = mac_expand(buf, *cpp, MAC_EXP_FLAG_NONE, filter,
+       stat = mac_expand(buf, *cpp, MAC_EXP_FLAG_PRINTABLE, (char *) 0,
                          bounce_template_lookup, (char *) tp);
        if (stat & MAC_PARSE_ERROR)
            msg_fatal("%s: bad $name syntax in %s template: %s",
index beb6e6c496c3eacfdf6d4c3446431b6ae95c7515..e216b07afc3c546cc59d4082c2b364a88187cdc6 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20140716"
+#define MAIL_RELEASE_DATE      "20140720"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index ccd0d84a8bdef180add346a96773dbe73efb805f..aade6a8ce5aa3da22159309e7f640fb8ca668687 100644 (file)
@@ -146,10 +146,10 @@ VSTRING *uxtext_quote(VSTRING *quoted, const char *unquoted, const char *special
 
 VSTRING *uxtext_unquote_append(VSTRING *unquoted, const char *quoted)
 {
-    const char *cp;
+    const unsigned char *cp;
     int     ch;
 
-    for (cp = quoted; (ch = *cp) != 0; cp++) {
+    for (cp = (const unsigned char *) quoted; (ch = *cp) != 0; cp++) {
        if (ch == '\\' && cp[1] == 'x' && cp[2] == '{') {
            cp += 2;
            int     unicode = 0;
index 4e73733443c61c248e0986a6247afb7beba7e468..e5605d7be47bdcce175630e4ec2651a04370f579 100644 (file)
@@ -101,10 +101,10 @@ VSTRING *xtext_quote(VSTRING *quoted, const char *unquoted, const char *special)
 
 VSTRING *xtext_unquote_append(VSTRING *unquoted, const char *quoted)
 {
-    const char *cp;
+    const unsigned char *cp;
     int     ch;
 
-    for (cp = quoted; (ch = *cp) != 0; cp++) {
+    for (cp = (const unsigned char *) quoted; (ch = *cp) != 0; cp++) {
        if (ch == '+') {
            if (ISDIGIT(cp[1]))
                ch = (cp[1] - '0') << 4;
index b6c7d57955e9368da84dbceff0d4f8991536c640..4dbe47db484461c52ffe1da829d5ec9f554ab5ae 100644 (file)
@@ -1523,8 +1523,6 @@ load_file.o: vbuf.h
 load_file.o: vstream.h
 load_file.o: warn_stat.h
 load_lib.o: load_lib.c
-load_lib.o: load_lib.h
-load_lib.o: msg.h
 load_lib.o: sys_defs.h
 lowercase.o: lowercase.c
 lowercase.o: stringops.h
@@ -1542,6 +1540,7 @@ mac_expand.o: mac_expand.h
 mac_expand.o: mac_parse.h
 mac_expand.o: msg.h
 mac_expand.o: mymalloc.h
+mac_expand.o: stringops.h
 mac_expand.o: sys_defs.h
 mac_expand.o: vbuf.h
 mac_expand.o: vstring.h
@@ -1599,6 +1598,7 @@ midna.o: msg.h
 midna.o: mymalloc.h
 midna.o: stringops.h
 midna.o: sys_defs.h
+midna.o: valid_hostname.h
 midna.o: vbuf.h
 midna.o: vstring.h
 msg.o: msg.c
index f9fd2e82a34067d7cbefb928e3f03a9ab31d8c71..8c6f6bb3185ba490b1d07f82093e40892c8e98a4 100644 (file)
@@ -54,6 +54,8 @@
 /*     string, including macro names in the values of conditional
 /*     expressions.  Do not expand macros, and do not write to the
 /*     result argument.
+/* .IP MAC_EXP_FLAG_PRINTABLE
+/*     Use the printable() function instead of \fIfilter\fR.
 /* .PP
 /*     The constant MAC_EXP_FLAG_NONE specifies a manifest null value.
 /* .RE
 #include <msg.h>
 #include <vstring.h>
 #include <mymalloc.h>
+#include <stringops.h>
 #include <mac_parse.h>
 #include <mac_expand.h>
 
@@ -197,7 +200,9 @@ static int mac_expand_callback(int type, VSTRING *buf, char *ptr)
            } else {
                len = VSTRING_LEN(mc->result);
                vstring_strcat(mc->result, text);
-               if (mc->filter) {
+               if (mc->flags & MAC_EXP_FLAG_PRINTABLE) {
+                   printable(vstring_str(mc->result) + len, '_');
+               } else if (mc->filter) {
                    cp = vstring_str(mc->result) + len;
                    while (*(cp += strspn(cp, mc->filter)))
                        *cp++ = '_';
index f08cd9c862a33ee3d983fca78d03c01b2263320b..f8fcffebd65a6f37d7e0aa15dda30554a5df0429 100644 (file)
@@ -24,6 +24,7 @@
 #define MAC_EXP_FLAG_RECURSE   (1<<0)
 #define MAC_EXP_FLAG_APPEND    (1<<1)
 #define MAC_EXP_FLAG_SCAN      (1<<2)
+#define MAC_EXP_FLAG_PRINTABLE  (1<<3)
 
  /*
   * Real lookup or just a test?
index 87f71e676563b36459f2230b24b7acf77078c1cc..446af899190f14b2505d48377ca32fffc5bdcb97 100644 (file)
@@ -10,6 +10,9 @@
 /*
 /*     const char *midna_utf8_to_ascii(
 /*     const char *name)
+/*
+/*     const char *midna_ascii_to_utf8(
+/*     const char *name)
 /* DESCRIPTION
 /*     The functions in this module transform domain names from
 /*     or to IDNA form. The result is cached to avoid repeated
@@ -18,6 +21,9 @@
 /*     midna_utf8_to_ascii() converts an UTF-8 domain name to
 /*     ASCII.  The result is a null pointer in case of error.
 /*
+/*     midna_ascii_to_utf8() converts an ASCII domain name to
+/*     UTF-8.  The result is a null pointer in case of error.
+/*
 /*     midna_cache_size specifies the size of the conversion result
 /*     cache.  This value is used only once, upon the first lookup
 /*     request.
@@ -55,6 +61,7 @@
 #include <msg.h>
 #include <ctable.h>
 #include <stringops.h>
+#include <valid_hostname.h>
 #include <midna.h>
 
  /*
@@ -99,9 +106,44 @@ static void *midna_utf8_to_ascii_create(const char *name, void *unused_context)
     }
 }
 
-/* midna_utf8_to_ascii_free - cache element destructor */
+/* midna_ascii_to_utf8_create - convert ASCII domain to UTF8 */
+
+static void *midna_ascii_to_utf8_create(const char *name, void *unused_context)
+{
+    const char myname[] = "midna_ascii_to_utf8_create";
+    char    buf[1024];                 /* XXX */
+    UErrorCode error = U_ZERO_ERROR;
+    UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+    UIDNA  *idna;
+    int     anl;
+
+    /*
+     * Paranoia: do not expose uidna_*() to unfiltered network data.
+     */
+    if (valid_hostname(name, DONT_GRIPE) == 0) {
+       msg_warn("%s: Problem translating domain \"%s\" to UTF8 form: %s",
+                myname, name, "malformed ASCII");
+       return (0);
+    }
+    idna = uidna_openUTS46(UIDNA_DEFAULT, &error);
+    anl = uidna_nameToUnicodeUTF8(idna,
+                                 name, strlen(name),
+                                 buf, sizeof(buf),
+                                 &info,
+                                 &error);
+    uidna_close(idna);
+    if (U_SUCCESS(error) && info.errors == 0 && anl > 0) {
+       return (mystrndup(buf, anl));
+    } else {
+       msg_warn("%s: Problem translating domain \"%s\" to IDNA form: %s",
+                myname, name, u_errorName(error));
+       return (0);
+    }
+}
+
+/* midna_cache_free - cache element destructor */
 
-static void midna_utf8_to_ascii_free(void *value, void *unused_context)
+static void midna_cache_free(void *value, void *unused_context)
 {
     if (value)
        myfree(value);
@@ -116,11 +158,25 @@ const char *midna_utf8_to_ascii(const char *name)
     if (midna_utf8_to_ascii_cache == 0)
        midna_utf8_to_ascii_cache = ctable_create(midna_cache_size,
                                                  midna_utf8_to_ascii_create,
-                                                 midna_utf8_to_ascii_free,
+                                                 midna_cache_free,
                                                  (void *) 0);
     return (ctable_locate(midna_utf8_to_ascii_cache, name));
 }
 
+/* midna_ascii_to_utf8 - convert UTF8 hostname to ASCII */
+
+const char *midna_ascii_to_utf8(const char *name)
+{
+    static CTABLE *midna_ascii_to_utf8_cache = 0;
+
+    if (midna_ascii_to_utf8_cache == 0)
+       midna_ascii_to_utf8_cache = ctable_create(midna_cache_size,
+                                                 midna_ascii_to_utf8_create,
+                                                 midna_cache_free,
+                                                 (void *) 0);
+    return (ctable_locate(midna_ascii_to_utf8_cache, name));
+}
+
 #ifdef TEST
 
  /*
@@ -128,6 +184,7 @@ const char *midna_utf8_to_ascii(const char *name)
   * stderr.
   */
 #include <stdlib.h>
+#include <locale.h>
 
 #include <stringops.h>                 /* XXX temp_utf8_kludge */
 #include <vstring.h>
@@ -138,17 +195,44 @@ const char *midna_utf8_to_ascii(const char *name)
 int     main(int argc, char **argv)
 {
     VSTRING *buffer = vstring_alloc(1);
-    const char *res;
+    const char *bp;
+    const char *ascii;
+    const char *utf8;
+
+    if (setlocale(LC_ALL, "C") == 0)
+       msg_fatal("setlocale(LC_ALL, C) failed: %m");
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
     msg_verbose = 1;
     temp_utf8_kludge = 1;
 
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
-       msg_info("testing: \"%s\"", vstring_str(buffer));
-       res = midna_utf8_to_ascii(vstring_str(buffer));
-       if (res != 0)
-           msg_info("result: \"%s\"", res);
+       msg_info("testing: \"%s\"", bp = vstring_str(buffer));
+       if (!allascii(bp)) {
+           ascii = midna_utf8_to_ascii(bp);
+           if (ascii != 0) {
+               msg_info("\"%s\" -> \"%s\"", bp, ascii);
+               utf8 = midna_ascii_to_utf8(ascii);
+               if (utf8 != 0) {
+                   msg_info("\"%s\" -> \"%s\" -> \"%s\"",
+                            bp, ascii, utf8);
+                   if (strcmp(utf8, bp) != 0)
+                       msg_warn("\"%s\" != \"%s\"", bp, utf8);
+               }
+           }
+       } else {
+           utf8 = midna_ascii_to_utf8(bp);
+           if (utf8 != 0) {
+               msg_info("\"%s\" -> \"%s\"", bp, utf8);
+               ascii = midna_utf8_to_ascii(utf8);
+               if (ascii != 0) {
+                   msg_info("\"%s\" -> \"%s\" -> \"%s\"",
+                            bp, utf8, ascii);
+                   if (strcmp(ascii, bp) != 0)
+                       msg_warn("\"%s\" != \"%s\"", bp, ascii);
+               }
+           }
+       }
     }
     exit(0);
 }
index 5a24a113e149dffb1f2c02cdf43ed6bca3e297c3..1d24777736f730044bc8f9414cb271634288cb78 100644 (file)
@@ -15,6 +15,7 @@
   * External interface.
   */
 extern const char *midna_utf8_to_ascii(const char *);
+extern const char *midna_ascii_to_utf8(const char *);
 
 /* LICENSE
 /* .ad