]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.6-20080510
authorWietse Venema <wietse@porcupine.org>
Sat, 10 May 2008 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:34:02 +0000 (06:34 +0000)
17 files changed:
postfix/HISTORY
postfix/README_FILES/SMTPD_POLICY_README
postfix/RELEASE_NOTES
postfix/conf/access
postfix/html/SMTPD_POLICY_README.html
postfix/html/access.5.html
postfix/makedefs
postfix/man/man5/access.5
postfix/proto/SMTPD_POLICY_README.html
postfix/proto/access
postfix/src/bounce/bounce_notify_util.c
postfix/src/global/header_opts.c
postfix/src/global/mail_version.h
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_check.c
postfix/src/tls/tls_verify.c

index b69e9ed8413e5e5924fdc2d7e19aba26c21d6a44..51750adaab01b60a436841507ec742ff2da12041 100644 (file)
@@ -14439,7 +14439,26 @@ Apologies for any names omitted.
        (Postfix 2.1) and smtp/lmtp_generic_maps (Postfix 2.3).
        File: global/mail_params.h.
 
-       Cleanup: the SMTP server's XFORWARD and XCLIENT support
-       was not updated when the smtpd_client_port_logging configuration
+       Cleanup: the SMTP server's XFORWARD and XCLIENT support was
+       not updated when the smtpd_client_port_logging configuration
        parameter was added. Code by Victor Duchovni. Files:
        smtpd/smtpd.c, smtpd/smtpd_peer.c.
+
+20080508
+
+       Cleanup: delivery status notifications now prepend a
+       Return-Path: message header to the returned message.
+       File: bounce/bounce_notify_util.c.
+
+20080509
+
+       Bugfix: null-terminate CN comment string after sanitization.
+       File: smtpd/smtpd.c.
+
+20080510
+
+       Cleanup: when extracting common name and issuer name from
+       TLS certificates, convert the result into UTF-8, and use
+       RFC 2047 encoding when logging these as Received: header
+       comment fields. Based remotely on code by Victor Duchovni.
+       Files: smtpd/smtpd.c, tls/tls_verify.c.
index dbedde37db6ad00d12d7b969b6b3e568cf9a2b98..80e2edbe98b910388b000e88b1c2f6680294531c 100644 (file)
@@ -126,7 +126,10 @@ Notes:
     how the client was authenticated via TLS. These attributes are empty in
     case of no certificate authentication. As of Postfix 2.2.11 these attribute
     values are encoded as xtext: some characters are represented by +XX, where
-    XX is the two-digit hexadecimal representation of the character value.
+    XX is the two-digit hexadecimal representation of the character value. With
+    Postfix 2.5 and later, the decoded string may contain non-ASCII characters.
+    If so, this is a UTF-8 string; xtext encoding works with the bytes of the
+    UTF-8 string, not the characters.
 
   * The "encryption_*" attributes (Postfix 2.3 and later) specify information
     about how the connection is encrypted. With plaintext connections the
index d3ec800e2e46e22b2ebb835314d778003feaa040..fb605fea68da477b0a7123f854e4c1cdadf55a90 100644 (file)
@@ -17,6 +17,13 @@ Incompatibility with Postfix 2.4 and earlier
 If you upgrade from Postfix 2.4 or earlier, read RELEASE_NOTES-2.5
 before proceeding.
 
+Incompatibility with snapshot 20080510
+======================================
+
+In the policy delegation protocol, certificate common name attributes
+are now xtext encoded UTF-8. The xtext decoded attributes may contain
+any UTF-8 value including control characters.
+
 Incompatibility with snapshot 20080428
 ======================================
 
index 9d396594e94ac36b5f25172a4669192a44683df1..18930449ef615abb9bbc8325698a002ebf8d0ca3 100644 (file)
 # 
 #        REJECT optional text...
 #               Reject  the  address etc. that matches the pattern.
-#               Reply with $reject_code optional text...  when  the
-#               optional  text is specified, otherwise reply with a
-#               generic error response message.
+#               Reply   with   "$access_map_reject_code    optional
+#               text..."  when the optional text is specified, oth-
+#               erwise reply with a generic error response message.
 # 
 #        DEFER_IF_REJECT optional text...
-#               Defer the request if some later  restriction  would
-#               result  in  a  REJECT action. Reply with "450 4.7.1
-#               optional text... when the optional text  is  speci-
+#               Defer  the  request if some later restriction would
+#               result in a REJECT action. Reply  with  "450  4.7.1
+#               optional  text..." when the optional text is speci-
 #               fied, otherwise reply with a generic error response
 #               message.
 # 
 #               This feature is available in Postfix 2.1 and later.
 # 
 #        DEFER_IF_PERMIT optional text...
-#               Defer  the  request if some later restriction would
-#               result in a an explicit or implicit PERMIT  action.
-#               Reply  with  "450  4.7.1  optional text... when the
-#               optional text is specified, otherwise reply with  a
+#               Defer the request if some later  restriction  would
+#               result  in a an explicit or implicit PERMIT action.
+#               Reply with "450 4.7.1  optional text..."  when  the
+#               optional  text is specified, otherwise reply with a
 #               generic error response message.
 # 
 #               This feature is available in Postfix 2.1 and later.
 #               reject_unauth_destination, and so on).
 # 
 #        BCC user@domain
-#               Send  one  copy  of  the  message  to the specified
+#               Send one copy  of  the  message  to  the  specified
 #               recipient.
 # 
-#               If multiple BCC actions are  specified  within  the
-#               same  SMTP  MAIL  transaction, only the last action
+#               If  multiple  BCC  actions are specified within the
+#               same SMTP MAIL transaction, only  the  last  action
 #               will be used.
 # 
-#               This feature is not  part  of  the  stable  Postfix
+#               This  feature  is  not  part  of the stable Postfix
 #               release.
 # 
 #        DISCARD optional text...
-#               Claim  successful delivery and silently discard the
-#               message.  Log the optional text if specified,  oth-
+#               Claim successful delivery and silently discard  the
+#               message.   Log the optional text if specified, oth-
 #               erwise log a generic message.
 # 
-#               Note:  this action currently affects all recipients
-#               of the message.   To  discard  only  one  recipient
-#               without  discarding  the  entire  message,  use the
+#               Note: this action currently affects all  recipients
+#               of  the  message.   To  discard  only one recipient
+#               without discarding  the  entire  message,  use  the
 #               transport(5) table to direct mail to the discard(8)
 #               service.
 # 
 #               This feature is available in Postfix 2.0 and later.
 # 
-#        DUNNO  Pretend that the lookup key  was  not  found.  This
-#               prevents  Postfix  from  trying  substrings  of the
-#               lookup key (such as a subdomain name, or a  network
+#        DUNNO  Pretend  that  the  lookup  key was not found. This
+#               prevents Postfix  from  trying  substrings  of  the
+#               lookup  key (such as a subdomain name, or a network
 #               address subnetwork).
 # 
 #               This feature is available in Postfix 2.0 and later.
 # 
 #        FILTER transport:destination
-#               After the message is queued, send the  entire  mes-
+#               After  the  message is queued, send the entire mes-
 #               sage through the specified external content filter.
-#               The transport:destination syntax  is  described  in
-#               the  transport(5)  manual  page.   More information
-#               about external content filters is  in  the  Postfix
+#               The  transport:destination  syntax  is described in
+#               the transport(5)  manual  page.   More  information
+#               about  external  content  filters is in the Postfix
 #               FILTER_README file.
 # 
 #               Note: this action overrides the content_filter set-
-#               ting, and currently affects all recipients  of  the
+#               ting,  and  currently affects all recipients of the
 #               message.
 # 
 #               This feature is available in Postfix 2.0 and later.
 # 
 #        HOLD optional text...
-#               Place the message on the hold queue, where it  will
-#               sit  until someone either deletes it or releases it
-#               for delivery.  Log the optional text if  specified,
+#               Place  the message on the hold queue, where it will
+#               sit until someone either deletes it or releases  it
+#               for  delivery.  Log the optional text if specified,
 #               otherwise log a generic message.
 # 
-#               Mail  that  is  placed on hold can be examined with
-#               the postcat(1) command, and  can  be  destroyed  or
+#               Mail that is placed on hold can  be  examined  with
+#               the  postcat(1)  command,  and  can be destroyed or
 #               released with the postsuper(1) command.
 # 
-#               Note:  use  "postsuper -r" to release mail that was
-#               kept on hold for a significant fraction  of  $maxi-
+#               Note: use "postsuper -r" to release mail  that  was
+#               kept  on  hold for a significant fraction of $maxi-
 #               mal_queue_lifetime  or  $bounce_queue_lifetime,  or
-#               longer. Use "postsuper -H" only for mail that  will
+#               longer.  Use "postsuper -H" only for mail that will
 #               not expire within a few delivery attempts.
 # 
-#               Note:  this action currently affects all recipients
+#               Note: this action currently affects all  recipients
 #               of the message.
 # 
 #               This feature is available in Postfix 2.0 and later.
 # 
 #        PREPEND headername: headervalue
-#               Prepend  the  specified  message header to the mes-
-#               sage.  When more than one PREPEND action  executes,
-#               the  first prepended header appears before the sec-
+#               Prepend the specified message header  to  the  mes-
+#               sage.   When more than one PREPEND action executes,
+#               the first prepended header appears before the  sec-
 #               ond etc. prepended header.
 # 
-#               Note: this action must execute before  the  message
-#               content  is received; it cannot execute in the con-
+#               Note:  this  action must execute before the message
+#               content is received; it cannot execute in the  con-
 #               text of smtpd_end_of_data_restrictions.
 # 
 #               This feature is available in Postfix 2.1 and later.
 # 
 #        REDIRECT user@domain
-#               After  the  message  is queued, send the message to
+#               After the message is queued, send  the  message  to
 #               the  specified  address  instead  of  the  intended
 #               recipient(s).
 # 
-#               Note:  this action overrides the FILTER action, and
+#               Note: this action overrides the FILTER action,  and
 #               currently affects all recipients of the message.
 # 
 #               This feature is available in Postfix 2.1 and later.
 # 
 #        WARN optional text...
 #               Log a warning with the optional text, together with
-#               client information and  if  available,  with  helo,
+#               client  information  and  if  available, with helo,
 #               sender, recipient and protocol information.
 # 
 #               This feature is available in Postfix 2.1 and later.
 # 
 # ENHANCED STATUS CODES
-#        Postfix version 2.3  and  later  support  enhanced  status
-#        codes  as  defined  in  RFC 3463.  When an enhanced status
-#        code is specified in an access table,  it  is  subject  to
-#        modification.  The  following  transformations  are needed
-#        when the same access  table  is  used  for  client,  helo,
-#        sender,  or  recipient  access  restrictions;  they happen
+#        Postfix  version  2.3  and  later  support enhanced status
+#        codes as defined in RFC 3463.   When  an  enhanced  status
+#        code  is  specified  in  an access table, it is subject to
+#        modification. The  following  transformations  are  needed
+#        when  the  same  access  table  is  used for client, helo,
+#        sender, or  recipient  access  restrictions;  they  happen
 #        regardless of whether Postfix replies to a MAIL FROM, RCPT
 #        TO or other SMTP command.
 # 
-#        o      When  a sender address matches a REJECT action, the
-#               Postfix SMTP server will transform a recipient  DSN
-#               status  (e.g.,  4.1.1-4.1.6) into the corresponding
+#        o      When a sender address matches a REJECT action,  the
+#               Postfix  SMTP server will transform a recipient DSN
+#               status (e.g., 4.1.1-4.1.6) into  the  corresponding
 #               sender DSN status, and vice versa.
 # 
-#        o      When  non-address  information  matches  a   REJECT
-#               action  (such  as  the HELO command argument or the
-#               client hostname/address), the Postfix  SMTP  server
-#               will  transform  a  sender  or recipient DSN status
-#               into  a  generic  non-address  DSN  status   (e.g.,
+#        o      When   non-address  information  matches  a  REJECT
+#               action (such as the HELO command  argument  or  the
+#               client  hostname/address),  the Postfix SMTP server
+#               will transform a sender  or  recipient  DSN  status
+#               into   a  generic  non-address  DSN  status  (e.g.,
 #               4.0.0).
 # 
 # REGULAR EXPRESSION TABLES
-#        This  section  describes how the table lookups change when
+#        This section describes how the table lookups  change  when
 #        the table is given in the form of regular expressions. For
-#        a  description  of regular expression lookup table syntax,
+#        a description of regular expression lookup  table  syntax,
 #        see regexp_table(5) or pcre_table(5).
 # 
-#        Each pattern is a regular expression that  is  applied  to
+#        Each  pattern  is  a regular expression that is applied to
 #        the entire string being looked up. Depending on the appli-
-#        cation, that string  is  an  entire  client  hostname,  an
+#        cation,  that  string  is  an  entire  client hostname, an
 #        entire client IP address, or an entire mail address. Thus,
 #        no  parent  domain  or  parent  network  search  is  done,
-#        user@domain  mail  addresses  are not broken up into their
+#        user@domain mail addresses are not broken  up  into  their
 #        user@ and domain constituent parts, nor is user+foo broken
 #        up into user and foo.
 # 
-#        Patterns  are applied in the order as specified in the ta-
-#        ble, until a pattern is  found  that  matches  the  search
+#        Patterns are applied in the order as specified in the  ta-
+#        ble,  until  a  pattern  is  found that matches the search
 #        string.
 # 
-#        Actions  are  the  same as with indexed file lookups, with
-#        the additional feature that parenthesized substrings  from
+#        Actions are the same as with indexed  file  lookups,  with
+#        the  additional feature that parenthesized substrings from
 #        the pattern can be interpolated as $1, $2 and so on.
 # 
 # TCP-BASED TABLES
-#        This  section  describes how the table lookups change when
+#        This section describes how the table lookups  change  when
 #        lookups are directed to a TCP-based server. For a descrip-
 #        tion of the TCP client/server lookup protocol, see tcp_ta-
 #        ble(5).  This feature is not available up to and including
 #        Postfix version 2.4.
 # 
-#        Each  lookup  operation uses the entire query string once.
-#        Depending on the application, that  string  is  an  entire
+#        Each lookup operation uses the entire query  string  once.
+#        Depending  on  the  application,  that string is an entire
 #        client hostname, an entire client IP address, or an entire
-#        mail address.  Thus, no parent domain  or  parent  network
-#        search  is done, user@domain mail addresses are not broken
-#        up into their user@ and domain constituent parts,  nor  is
+#        mail  address.   Thus,  no parent domain or parent network
+#        search is done, user@domain mail addresses are not  broken
+#        up  into  their user@ and domain constituent parts, nor is
 #        user+foo broken up into user and foo.
 # 
 #        Actions are the same as with indexed file lookups.
 # 
 # EXAMPLE
-#        The  following  example  uses an indexed file, so that the
-#        order of table entries does not matter. The  example  per-
-#        mits  access  by the client at address 1.2.3.4 but rejects
-#        all other clients in 1.2.3.0/24. Instead  of  hash  lookup
-#        tables,  some  systems use dbm.  Use the command "postconf
-#        -m" to find out what lookup  tables  Postfix  supports  on
+#        The following example uses an indexed file,  so  that  the
+#        order  of  table entries does not matter. The example per-
+#        mits access by the client at address 1.2.3.4  but  rejects
+#        all  other  clients  in 1.2.3.0/24. Instead of hash lookup
+#        tables, some systems use dbm.  Use the  command  "postconf
+#        -m"  to  find  out  what lookup tables Postfix supports on
 #        your system.
 # 
 #        /etc/postfix/main.cf:
 #            1.2.3   REJECT
 #            1.2.3.4 OK
 # 
-#        Execute  the  command  "postmap /etc/postfix/access" after
+#        Execute the command  "postmap  /etc/postfix/access"  after
 #        editing the file.
 # 
 # BUGS
-#        The table format does not understand quoting  conventions.
+#        The  table format does not understand quoting conventions.
 # 
 # SEE ALSO
 #        postmap(1), Postfix lookup table manager
 #        transport(5), transport:nexthop syntax
 # 
 # README FILES
-#        Use  "postconf  readme_directory" or "postconf html_direc-
+#        Use "postconf readme_directory" or  "postconf  html_direc-
 #        tory" to locate this information.
 #        SMTPD_ACCESS_README, built-in SMTP server access control
 #        DATABASE_README, Postfix lookup table overview
 # 
 # LICENSE
-#        The Secure Mailer license must be  distributed  with  this
+#        The  Secure  Mailer  license must be distributed with this
 #        software.
 # 
 # AUTHOR(S)
index 1ad5441f6d93857a887d2ce3a6d1aab6a2fc47af..4471aaf1600c0114c607d47397be7274c23f3e7c 100644 (file)
@@ -173,7 +173,10 @@ stress=
     These attributes are empty in case of no certificate authentication.
     As of Postfix 2.2.11 these attribute values are encoded as
     xtext: some characters are represented by +XX, where XX is the
-    two-digit hexadecimal representation of the character value.
+    two-digit hexadecimal representation of the character value. With
+    Postfix 2.5 and later, the decoded string may contain non-ASCII
+    characters. If so, this is a UTF-8 string; xtext encoding works
+    with the bytes of the UTF-8 string, not the characters.
     </p>
 
     <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
index 230c1dcf16dabd325bb22b77ccab87631d324629..7f7977df2c2813bf8ac6b497ccdf2f30e8335011 100644 (file)
@@ -198,24 +198,24 @@ ACCESS(5)                                                            ACCESS(5)
 
        <b>REJECT</b> <i>optional text...</i>
               Reject  the  address etc. that matches the pattern.
-              Reply with <i>$reject</i><b>_</b><i>code optional text...</i>  when  the
-              optional  text is specified, otherwise reply with a
-              generic error response message.
+              Reply   with   "<b>$<a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a></b>    <i>optional</i>
+              <i>text...</i>"  when the optional text is specified, oth-
+              erwise reply with a generic error response message.
 
        <b>DEFER_IF_REJECT</b> <i>optional text...</i>
-              Defer the request if some later  restriction  would
-              result  in  a  REJECT action. Reply with "<b>450 4.7.1</b>
-              <i>optional text...</i> when the optional text  is  speci-
+              Defer  the  request if some later restriction would
+              result in a REJECT action. Reply  with  "<b>450  4.7.1</b>
+              <i>optional  text...</i>" when the optional text is speci-
               fied, otherwise reply with a generic error response
               message.
 
               This feature is available in Postfix 2.1 and later.
 
        <b>DEFER_IF_PERMIT</b> <i>optional text...</i>
-              Defer  the  request if some later restriction would
-              result in a an explicit or implicit PERMIT  action.
-              Reply  with  "<b>450  4.7.1</b>  <i>optional text...</i> when the
-              optional text is specified, otherwise reply with  a
+              Defer the request if some later  restriction  would
+              result  in a an explicit or implicit PERMIT action.
+              Reply with "<b>450 4.7.1</b>  <i>optional text...</i>"  when  the
+              optional  text is specified, otherwise reply with a
               generic error response message.
 
               This feature is available in Postfix 2.1 and later.
@@ -226,169 +226,169 @@ ACCESS(5)                                                            ACCESS(5)
               <b><a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a></b>, and so on).
 
        <b>BCC</b> <i>user@domain</i>
-              Send  one  copy  of  the  message  to the specified
+              Send one copy  of  the  message  to  the  specified
               recipient.
 
-              If multiple BCC actions are  specified  within  the
-              same  SMTP  MAIL  transaction, only the last action
+              If  multiple  BCC  actions are specified within the
+              same SMTP MAIL transaction, only  the  last  action
               will be used.
 
-              This feature is not  part  of  the  stable  Postfix
+              This  feature  is  not  part  of the stable Postfix
               release.
 
        <b>DISCARD</b> <i>optional text...</i>
-              Claim  successful delivery and silently discard the
-              message.  Log the optional text if specified,  oth-
+              Claim successful delivery and silently discard  the
+              message.   Log the optional text if specified, oth-
               erwise log a generic message.
 
-              Note:  this action currently affects all recipients
-              of the message.   To  discard  only  one  recipient
-              without  discarding  the  entire  message,  use the
+              Note: this action currently affects all  recipients
+              of  the  message.   To  discard  only one recipient
+              without discarding  the  entire  message,  use  the
               <a href="transport.5.html">transport(5)</a> table to direct mail to the <a href="discard.8.html">discard(8)</a>
               service.
 
               This feature is available in Postfix 2.0 and later.
 
-       <b>DUNNO</b>  Pretend that the lookup key  was  not  found.  This
-              prevents  Postfix  from  trying  substrings  of the
-              lookup key (such as a subdomain name, or a  network
+       <b>DUNNO</b>  Pretend  that  the  lookup  key was not found. This
+              prevents Postfix  from  trying  substrings  of  the
+              lookup  key (such as a subdomain name, or a network
               address subnetwork).
 
               This feature is available in Postfix 2.0 and later.
 
        <b>FILTER</b> <i>transport:destination</i>
-              After the message is queued, send the  entire  mes-
+              After  the  message is queued, send the entire mes-
               sage through the specified external content filter.
-              The <i>transport:destination</i> syntax  is  described  in
-              the  <a href="transport.5.html"><b>transport</b>(5)</a>  manual  page.   More information
-              about external content filters is  in  the  Postfix
+              The  <i>transport:destination</i>  syntax  is described in
+              the <a href="transport.5.html"><b>transport</b>(5)</a>  manual  page.   More  information
+              about  external  content  filters is in the Postfix
               <a href="FILTER_README.html">FILTER_README</a> file.
 
               Note: this action overrides the <b><a href="postconf.5.html#content_filter">content_filter</a></b> set-
-              ting, and currently affects all recipients  of  the
+              ting,  and  currently affects all recipients of the
               message.
 
               This feature is available in Postfix 2.0 and later.
 
        <b>HOLD</b> <i>optional text...</i>
-              Place the message on the <b>hold</b> queue, where it  will
-              sit  until someone either deletes it or releases it
-              for delivery.  Log the optional text if  specified,
+              Place  the message on the <b>hold</b> queue, where it will
+              sit until someone either deletes it or releases  it
+              for  delivery.  Log the optional text if specified,
               otherwise log a generic message.
 
-              Mail  that  is  placed on hold can be examined with
-              the <a href="postcat.1.html"><b>postcat</b>(1)</a> command, and  can  be  destroyed  or
+              Mail that is placed on hold can  be  examined  with
+              the  <a href="postcat.1.html"><b>postcat</b>(1)</a>  command,  and  can be destroyed or
               released with the <a href="postsuper.1.html"><b>postsuper</b>(1)</a> command.
 
-              Note:  use  "<b>postsuper -r</b>" to release mail that was
-              kept on hold for a significant fraction  of  <b>$<a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
+              Note: use "<b>postsuper -r</b>" to release mail  that  was
+              kept  on  hold for a significant fraction of <b>$<a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
               <b><a href="postconf.5.html#maximal_queue_lifetime">mal_queue_lifetime</a></b>  or  <b>$<a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b>,  or
-              longer. Use "<b>postsuper -H</b>" only for mail that  will
+              longer.  Use "<b>postsuper -H</b>" only for mail that will
               not expire within a few delivery attempts.
 
-              Note:  this action currently affects all recipients
+              Note: this action currently affects all  recipients
               of the message.
 
               This feature is available in Postfix 2.0 and later.
 
        <b>PREPEND</b> <i>headername: headervalue</i>
-              Prepend  the  specified  message header to the mes-
-              sage.  When more than one PREPEND action  executes,
-              the  first prepended header appears before the sec-
+              Prepend the specified message header  to  the  mes-
+              sage.   When more than one PREPEND action executes,
+              the first prepended header appears before the  sec-
               ond etc. prepended header.
 
-              Note: this action must execute before  the  message
-              content  is received; it cannot execute in the con-
+              Note:  this  action must execute before the message
+              content is received; it cannot execute in the  con-
               text of <b><a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a></b>.
 
               This feature is available in Postfix 2.1 and later.
 
        <b>REDIRECT</b> <i>user@domain</i>
-              After  the  message  is queued, send the message to
+              After the message is queued, send  the  message  to
               the  specified  address  instead  of  the  intended
               recipient(s).
 
-              Note:  this action overrides the FILTER action, and
+              Note: this action overrides the FILTER action,  and
               currently affects all recipients of the message.
 
               This feature is available in Postfix 2.1 and later.
 
        <b>WARN</b> <i>optional text...</i>
               Log a warning with the optional text, together with
-              client information and  if  available,  with  helo,
+              client  information  and  if  available, with helo,
               sender, recipient and protocol information.
 
               This feature is available in Postfix 2.1 and later.
 
 <b>ENHANCED STATUS CODES</b>
-       Postfix version 2.3  and  later  support  enhanced  status
-       codes  as  defined  in  <a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a>.  When an enhanced status
-       code is specified in an access table,  it  is  subject  to
-       modification.  The  following  transformations  are needed
-       when the same access  table  is  used  for  client,  helo,
-       sender,  or  recipient  access  restrictions;  they happen
+       Postfix  version  2.3  and  later  support enhanced status
+       codes as defined in <a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a>.   When  an  enhanced  status
+       code  is  specified  in  an access table, it is subject to
+       modification. The  following  transformations  are  needed
+       when  the  same  access  table  is  used for client, helo,
+       sender, or  recipient  access  restrictions;  they  happen
        regardless of whether Postfix replies to a MAIL FROM, RCPT
        TO or other SMTP command.
 
-       <b>o</b>      When  a sender address matches a REJECT action, the
-              Postfix SMTP server will transform a recipient  DSN
-              status  (e.g.,  4.1.1-4.1.6) into the corresponding
+       <b>o</b>      When a sender address matches a REJECT action,  the
+              Postfix  SMTP server will transform a recipient DSN
+              status (e.g., 4.1.1-4.1.6) into  the  corresponding
               sender DSN status, and vice versa.
 
-       <b>o</b>      When  non-address  information  matches  a   REJECT
-              action  (such  as  the HELO command argument or the
-              client hostname/address), the Postfix  SMTP  server
-              will  transform  a  sender  or recipient DSN status
-              into  a  generic  non-address  DSN  status   (e.g.,
+       <b>o</b>      When   non-address  information  matches  a  REJECT
+              action (such as the HELO command  argument  or  the
+              client  hostname/address),  the Postfix SMTP server
+              will transform a sender  or  recipient  DSN  status
+              into   a  generic  non-address  DSN  status  (e.g.,
               4.0.0).
 
 <b>REGULAR EXPRESSION TABLES</b>
-       This  section  describes how the table lookups change when
+       This section describes how the table lookups  change  when
        the table is given in the form of regular expressions. For
-       a  description  of regular expression lookup table syntax,
+       a description of regular expression lookup  table  syntax,
        see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to
+       Each  pattern  is  a regular expression that is applied to
        the entire string being looked up. Depending on the appli-
-       cation, that string  is  an  entire  client  hostname,  an
+       cation,  that  string  is  an  entire  client hostname, an
        entire client IP address, or an entire mail address. Thus,
        no  parent  domain  or  parent  network  search  is  done,
-       <i>user@domain</i>  mail  addresses  are not broken up into their
+       <i>user@domain</i> mail addresses are not broken  up  into  their
        <i>user@</i> and <i>domain</i> constituent parts, nor is <i>user+foo</i> broken
        up into <i>user</i> and <i>foo</i>.
 
-       Patterns  are applied in the order as specified in the ta-
-       ble, until a pattern is  found  that  matches  the  search
+       Patterns are applied in the order as specified in the  ta-
+       ble,  until  a  pattern  is  found that matches the search
        string.
 
-       Actions  are  the  same as with indexed file lookups, with
-       the additional feature that parenthesized substrings  from
+       Actions are the same as with indexed  file  lookups,  with
+       the  additional feature that parenthesized substrings from
        the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
 
 <b>TCP-BASED TABLES</b>
-       This  section  describes how the table lookups change when
+       This section describes how the table lookups  change  when
        lookups are directed to a TCP-based server. For a descrip-
        tion of the TCP client/server lookup protocol, see <a href="tcp_table.5.html"><b>tcp_ta-</b></a>
        <a href="tcp_table.5.html"><b>ble</b>(5)</a>.  This feature is not available up to and including
        Postfix version 2.4.
 
-       Each  lookup  operation uses the entire query string once.
-       Depending on the application, that  string  is  an  entire
+       Each lookup operation uses the entire query  string  once.
+       Depending  on  the  application,  that string is an entire
        client hostname, an entire client IP address, or an entire
-       mail address.  Thus, no parent domain  or  parent  network
-       search  is done, <i>user@domain</i> mail addresses are not broken
-       up into their <i>user@</i> and <i>domain</i> constituent parts,  nor  is
+       mail  address.   Thus,  no parent domain or parent network
+       search is done, <i>user@domain</i> mail addresses are not  broken
+       up  into  their <i>user@</i> and <i>domain</i> constituent parts, nor is
        <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Actions are the same as with indexed file lookups.
 
 <b>EXAMPLE</b>
-       The  following  example  uses an indexed file, so that the
-       order of table entries does not matter. The  example  per-
-       mits  access  by the client at address 1.2.3.4 but rejects
-       all other clients in 1.2.3.0/24. Instead  of  <b>hash</b>  lookup
-       tables,  some  systems use <b>dbm</b>.  Use the command "<b>postconf</b>
-       <b>-m</b>" to find out what lookup  tables  Postfix  supports  on
+       The following example uses an indexed file,  so  that  the
+       order  of  table entries does not matter. The example per-
+       mits access by the client at address 1.2.3.4  but  rejects
+       all  other  clients  in 1.2.3.0/24. Instead of <b>hash</b> lookup
+       tables, some systems use <b>dbm</b>.  Use the  command  "<b>postconf</b>
+       <b>-m</b>"  to  find  out  what lookup tables Postfix supports on
        your system.
 
        /etc/postfix/<a href="postconf.5.html">main.cf</a>:
@@ -399,11 +399,11 @@ ACCESS(5)                                                            ACCESS(5)
            1.2.3   REJECT
            1.2.3.4 OK
 
-       Execute  the  command  "<b>postmap /etc/postfix/access</b>" after
+       Execute the command  "<b>postmap  /etc/postfix/access</b>"  after
        editing the file.
 
 <b>BUGS</b>
-       The table format does not understand quoting  conventions.
+       The  table format does not understand quoting conventions.
 
 <b>SEE ALSO</b>
        <a href="postmap.1.html">postmap(1)</a>, Postfix lookup table manager
@@ -416,7 +416,7 @@ ACCESS(5)                                                            ACCESS(5)
        <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index df3e7717c4711324bdd71b19af4432d3107e75e7..0053b4508ed241729c9b6585f9c44ae1cef72e79 100644 (file)
@@ -479,7 +479,7 @@ esac
 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} \
 ${WARN='-Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes \
        -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-       -Wunused'}
+       -Wunused -Wno-missing-braces'}
 
 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
 
index e96f4ad3b6a0a79daece466f0a711f123d0aca51..a35383b7c89d716c3990253fa0881b7118f3e387 100644 (file)
@@ -190,12 +190,13 @@ The reply code "421" causes Postfix to disconnect immediately
 (Postfix version 2.3 and later).
 .IP "\fBREJECT \fIoptional text...\fR
 Reject the address etc. that matches the pattern. Reply with
-\fI$reject_code optional text...\fR when the optional text is
+"\fB$access_map_reject_code \fIoptional text...\fR" when the
+optional text is
 specified, otherwise reply with a generic error response message.
 .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
 Defer the request if some later restriction would result in a
 REJECT action. Reply with "\fB450 4.7.1 \fI optional
-text...\fR when the
+text...\fR" when the
 optional text is specified, otherwise reply with a generic error
 response message.
 .sp
@@ -203,7 +204,7 @@ This feature is available in Postfix 2.1 and later.
 .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
 Defer the request if some later restriction would result in a
 an explicit or implicit PERMIT action.
-Reply with "\fB450 4.7.1 \fI optional text...\fR when the
+Reply with "\fB450 4.7.1 \fI optional text...\fR" when the
 optional text is specified, otherwise reply with a generic error
 response message.
 .sp
index bdf79709756f65935184e3f18c1e1f4411bb28ae..d3e6f005f960e7ad09aec310a18a5d2ea15197cc 100644 (file)
@@ -173,7 +173,10 @@ stress=
     These attributes are empty in case of no certificate authentication.
     As of Postfix 2.2.11 these attribute values are encoded as
     xtext: some characters are represented by +XX, where XX is the
-    two-digit hexadecimal representation of the character value.
+    two-digit hexadecimal representation of the character value. With
+    Postfix 2.5 and later, the decoded string may contain non-ASCII
+    characters. If so, this is a UTF-8 string; xtext encoding works
+    with the bytes of the UTF-8 string, not the characters.
     </p>
 
     <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
index 665cc9e8f7ebaaf00000537e0091c94db8a40d9b..088b87eeef338b66239833220cb4fb8aed09971a 100644 (file)
 #      (Postfix version 2.3 and later).
 # .IP "\fBREJECT \fIoptional text...\fR
 #      Reject the address etc. that matches the pattern. Reply with
-#      \fI$reject_code optional text...\fR when the optional text is
+#      "\fB$access_map_reject_code \fIoptional text...\fR" when the
+#      optional text is
 #      specified, otherwise reply with a generic error response message.
 # .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
 #      Defer the request if some later restriction would result in a
 #      REJECT action. Reply with "\fB450 4.7.1 \fI optional
-#      text...\fR when the
+#      text...\fR" when the
 #      optional text is specified, otherwise reply with a generic error
 #      response message.
 # .sp
 # .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
 #      Defer the request if some later restriction would result in a
 #      an explicit or implicit PERMIT action.
-#      Reply with "\fB450 4.7.1 \fI optional text...\fR when the
+#      Reply with "\fB450 4.7.1 \fI optional text...\fR" when the
 #      optional text is specified, otherwise reply with a generic error
 #      response message.
 # .sp
index 44a91ab55b308319dfdbd4e30fef969e39de9e33..9cdf264ffde11ee6dd1c906b65f12d10a6ce3027 100644 (file)
@@ -772,6 +772,16 @@ int     bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
        return (vstream_ferror(bounce));
     }
 
+    /*
+     * XXX The cleanup server removes Return-Path: headers. This should be
+     * done only with mail that enters via a non-SMTP channel, but changing
+     * this now could break other software. Removing Return-Path: could break
+     * digital signatures, though this is unlikely. In any case,
+     * header_checks are more effective when the Return-Path: header is
+     * present, so we prepend one to the bounce message.
+     */
+    post_mail_fprintf(bounce, "Return-Path: <%s>", STR(bounce_info->sender));
+
     /*
      * Copy the original message contents. We're doing raw record output here
      * so that we don't throw away binary transparency yet.
index 0461502ff9fd99a747b01187157aa90ae8eedebd..08808f2d95fe07be61e6bd7907f820cfc5f93020 100644 (file)
  /*
   * Header names are given in the preferred capitalization. The lookups are
   * case-insensitive.
+  * 
+  * XXX Removing Return-Path: headers should probably be done only with mail
+  * that enters via a non-SMTP channel. Changing this now could break other
+  * software. See also comments in bounce_notify_util.c.
   */
 static const HEADER_OPTS header_opts[] = {
     "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
index 8da1f6906a322e5a23c39bf096485396554b01a8..c3fdb6d8d25c83662c75aa1c68ca60aa929bc889 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      "20080428"
+#define MAIL_RELEASE_DATE      "20080510"
 #define MAIL_VERSION_NUMBER    "2.6"
 
 #ifdef SNAPSHOT
index a3b32d79f6b5db902383411e9641e657c958364a..c1c3b8710b6fc5c87eafaf6915dd53e0f45e2503 100644 (file)
@@ -2496,6 +2496,60 @@ static void rcpt_reset(SMTPD_STATE *state)
     state->rcpt_overshoot = 0;
 }
 
+/* rfc2047_comment_encode - encode comment string */
+
+static VSTRING *rfc2047_comment_encode(const char *str, const char *charset)
+{
+    VSTRING *buf = vstring_alloc(30);
+    const unsigned char *cp;
+    int     ch;
+
+    /*
+     * XXX Most of the RFC 2047 "especials" are not special in RFC*822
+     * comments, but we encode them anyway to avoid complaints.
+     * 
+     * XXX In Received: header comments we enclose peer and issuer common names
+     * with "" quotes. This is the cause of several quirks.
+     * 
+     * 1) We encode text that contains the " character, even though that
+     * character is not special for RFC*822.
+     * 
+     * 2) Long comments look ugly when folded in-between quotes, so we ignore
+     * the recommended limit of 75 characters per encoded word.
+     * 
+     * 3) We must encode the the enclosing quotes, to avoid producing invalid
+     * encoded words.
+     */
+#define ESPECIALS "()<>@,;:\"/[]?.="           /* Special in RFC 2047 */
+#define CSPECIALS "\\\"()"                     /* Special in our comments */
+
+    /* Don't encode if not needed. */
+    for (cp = (unsigned char *) str; /* see below */ ; ++cp) {
+       if ((ch = *cp) == 0) {
+           vstring_sprintf(buf, "\"%s\"", str);
+           return (buf);
+       }
+       if (!ISPRINT(ch) || strchr(CSPECIALS, ch))
+           break;
+    }
+
+    /*
+     * Use quoted-printable (like) encoding with spaces mapped to underscore.
+     */
+    vstring_sprintf(buf, "=?%s?Q?=%02X", charset, '"');
+    for (cp = (unsigned char *) str; (ch = *cp) != 0; ++cp) {
+       if (!ISPRINT(ch) || strchr(ESPECIALS CSPECIALS, ch)) {
+           vstring_sprintf_append(buf, "=%02X", ch);
+       } else if (ch == ' ') {
+           VSTRING_ADDCH(buf, '_');
+       } else {
+           VSTRING_ADDCH(buf, ch);
+       }
+    }
+    vstring_sprintf_append(buf, "=%02X?=", '"');
+    return (buf);
+}
+
 /* comment_sanitize - clean up comment string */
 
 static void comment_sanitize(VSTRING *comment_string)
@@ -2526,6 +2580,7 @@ static void comment_sanitize(VSTRING *comment_string)
     }
     while (pc-- > 0)
        VSTRING_ADDCH(comment_string, ')');
+    VSTRING_TERMINATE(comment_string);
 }
 
 /* data_cmd - process DATA command */
@@ -2654,6 +2709,10 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
 
 #define VSTRING_STRDUP(s) vstring_strcpy(vstring_alloc(strlen(s) + 1), (s))
 
+       /*
+        * Certificate CN information is arbitrary content in the UTF-8
+        * character set.
+        */
 #ifdef USE_TLS
        if (var_smtpd_tls_received_header && state->tls_context) {
            out_fprintf(out_stream, REC_TYPE_NORM,
@@ -2663,13 +2722,14 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
                        state->tls_context->cipher_usebits,
                        state->tls_context->cipher_algbits);
            if (TLS_CERT_IS_PRESENT(state->tls_context)) {
-               peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN);
-               comment_sanitize(peer_CN);
-               issuer_CN = VSTRING_STRDUP(state->tls_context->issuer_CN ?
-                                       state->tls_context->issuer_CN : "");
-               comment_sanitize(issuer_CN);
+               peer_CN =
+                   rfc2047_comment_encode(state->tls_context->peer_CN,
+                                          "utf-8");
+               issuer_CN =
+                   rfc2047_comment_encode(state->tls_context->issuer_CN,
+                                          "utf-8");
                out_fprintf(out_stream, REC_TYPE_NORM,
-                           "\t(Client CN \"%s\", Issuer \"%s\" (%s))",
+                           "\t(Client CN %s, Issuer %s (%s))",
                            STR(peer_CN), STR(issuer_CN),
                            TLS_CERT_IS_TRUSTED(state->tls_context) ?
                            "verified OK" : "not verified");
index ac7bb54305e21e74a9d4768f9a6d12d54a554be5..bc3aa25c69afb406aae7f7fb26e0affe2f80c180 100644 (file)
@@ -180,14 +180,6 @@ typedef struct SMTPD_STATE {
     ssize_t milter_argc;
 } SMTPD_STATE;
 
- /*
-  * Construct name[addr] or name[addr]:port as appropriate
-  */
-#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
-    concatenate((name), "[", (addr), "]", \
-               var_smtpd_client_port_log ? ":" : (char *) 0, \
-               (port), (char *) 0)
-
 #define SMTPD_FLAG_HANGUP      (1<<0)  /* disconnect */
 
 #define SMTPD_STATE_XFORWARD_INIT  (1<<0)      /* xforward preset done */
@@ -287,6 +279,14 @@ extern void smtpd_peer_reset(SMTPD_STATE *state);
 #define SMTPD_PEER_CODE_PERM   5
 #define SMTPD_PEER_CODE_FORGED 6
 
+ /*
+  * Construct name[addr] or name[addr]:port as appropriate
+  */
+#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
+       concatenate((name), "[", (addr), "]", \
+                   var_smtpd_client_port_log ? ":" : (char *) 0, \
+                   (port), (char *) 0)
+
  /*
   * Choose between normal or forwarded attributes.
   * 
index d4fadde9562011e0d730240d5d04f1116a0536b7..c88e5df965c21d02fa614dfdd280c5180ab847e8 100644 (file)
@@ -1813,7 +1813,6 @@ static int reject_unverified_address(SMTPD_STATE *state, const char *addr,
                         SND_DSN : "4.1.1",
                         "<%s>: %s rejected: address verification problem",
                         reply_name, reply_class);
-       rqst_status = SMTPD_CHECK_DUNNO;
     } else {
        switch (rcpt_status) {
        default:
index 0c9075061d68bfaed9ce9ce2d1022a8de69cfda9..5a5e0766890f29bf1d325275ab24615f9459d03b 100644 (file)
 /*     tls_peer_CN() returns the text CommonName for the peer
 /*     certificate subject, or an empty string if no CommonName was
 /*     found. The result is allocated with mymalloc() and must be
-/*     freed by the caller.
+/*     freed by the caller; it is arbitrary UTF-8 content.
 /*
 /*     tls_issuer_CN() returns the text CommonName for the peer
 /*     certificate issuer, or an empty string if no CommonName was
 /*     found. The result is allocated with mymalloc() and must be
-/*     freed by the caller.
+/*     freed by the caller; it is arbitrary UTF-8 content.
 /*
 /*     tls_dns_name() returns the string value of a GENERAL_NAME
 /*     from a DNS subjectAltName extension. If non-printable characters
@@ -278,11 +278,9 @@ static char *tls_text_name(X509_NAME *name, int nid, const char *label,
     int     pos;
     X509_NAME_ENTRY *entry;
     ASN1_STRING *entry_str;
-    int     typ;
-    int     len;
-    unsigned char *val;
-    unsigned char *utf;
-    char   *cp;
+    int     asn1_type;
+    int     utf8_length;
+    unsigned char *utf8_value;
 
     if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
        if (gripe != DONT_GRIPE) {
@@ -321,96 +319,72 @@ static char *tls_text_name(X509_NAME *name, int nid, const char *label,
     }
 
     /*
-     * Peername checks are security sensitive, carefully scrutinize the
-     * input!
+     * XXX Convert everything into UTF-8. This is a super-set of ASCII, so we
+     * don't have to bother with separate code paths for ASCII-like content.
+     * If the payload is ASCII then we won't waste lots of CPU cycles
+     * converting it into UTF-8. It's up to OpenSSL to do something
+     * reasonable when converting ASCII formats that contain non-ASCII
+     * content.
+     * 
+     * XXX Don't bother optimizing the string length error check. It is not
+     * worth the complexity.
      */
-    typ = ASN1_STRING_type(entry_str);
-    len = ASN1_STRING_length(entry_str);
-    val = ASN1_STRING_data(entry_str);
+    asn1_type = ASN1_STRING_type(entry_str);
+    if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_str)) < 0) {
+       msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d",
+                myname, TLScontext->namaddr, label, asn1_type);
+       tls_print_errors();
+       return (0);
+    }
 
     /*
-     * http://www.apps.ietf.org/rfc/rfc3280.html#sec-4.1.2.4 Quick Summary:
-     * 
-     * The DirectoryString type is defined as a choice of PrintableString,
-     * TeletexString, BMPString, UTF8String, and UniversalString.  The
-     * UTF8String encoding is the preferred encoding, and all certificates
-     * issued after December 31, 2003 MUST use the UTF8String encoding of
-     * DirectoryString (except as noted below).
-     * 
-     * XXX: 2007, the above has not happened yet (of course), and we continue to
-     * see new certificates with T61STRING (Teletex) attribute values.
-     * 
-     * XXX: 2007, at this time there are only two ASN.1 fixed width multi-byte
-     * string encodings, BMPSTRING (16 bit Unicode) and UniversalString
-     * (32-bit Unicode). The only variable width ASN.1 string encoding is
-     * UTF8 with all the other encodings being 1 byte wide subsets or subsets
-     * of ASCII.
-     * 
-     * Relying on this could simplify the code, because we would never convert
-     * unexpected single-byte encodings, but is involves too many cases to be
-     * sure that we have a complete set and the assumptions may become false.
-     * So, we pessimistically convert encodings not blessed by RFC 2459, and
-     * filter out all types that are not string types as a side-effect of
-     * UTF8 conversion (the ASN.1 library knows which types are string types
-     * and how wide they are...).
-     * 
-     * XXX: Two possible states after switch, either "utf == val" and it MUST
-     * NOT be freed with OPENSSL_free(), or "utf != val" and it MUST be freed
-     * with OPENSSL_free().
+     * No returns without cleaning up. A good optimizer will replace multiple
+     * blocks of identical code by jumps to just one such block.
      */
-    switch (typ) {
-    case V_ASN1_PRINTABLESTRING:               /* X.500 portable ASCII
-                                                * printables */
-    case V_ASN1_IA5STRING:                     /* ISO 646 ~ ASCII */
-    case V_ASN1_T61STRING:                     /* Essentially ISO-Latin */
-    case V_ASN1_UTF8STRING:                    /* UTF8 */
-       utf = val;
-       break;
-
-    default:
+#define TLS_TEXT_NAME_RETURN(x) do { \
+       char *__tls_text_name_temp = (x); \
+       OPENSSL_free(utf8_value); \
+       return (__tls_text_name_temp); \
+    } while (0)
 
-       /*
-        * May shrink in wash, but BMPSTRING only shrinks by 50%. Others may
-        * shrink by up to 75%. We Sanity check the length before bothering
-        * to copy any large strings to convert to UTF8, only to find out
-        * they don't fit. So long as no new MB types are introduced, and
-        * weird string encodings unsanctioned by RFC 3280, are used in the
-        * issuer or subject DN, this "conservative" estimate will be exact.
-        */
-       len >>= (typ == V_ASN1_BMPSTRING) ? 1 : 2;
-       if (len >= CCERT_BUFSIZ) {
-           msg_warn("%s: %s: peer %s too long: %d",
-                    myname, TLScontext->namaddr, label, len);
-           return (0);
-       }
-       if ((len = ASN1_STRING_to_UTF8(&utf, entry_str)) < 0) {
-           msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d",
-                    myname, TLScontext->namaddr, label, typ);
-           tls_print_errors();
-           return (0);
+#if 0
+    for (cp = utf8_value; (ch = *cp) != 0; cp++) {
+       if (ISASCII(ch) && !ISPRINT(ch)) {
+           msg_warn("%s: %s: non-printable content in peer %s",
+                    myname, TLScontext->namaddr, label);
+           TLS_TEXT_NAME_RETURN(0);
        }
     }
-#define RETURN(x) do { if (utf!=val) OPENSSL_free(utf); return (x); } while (0)
+#endif
+
+    /*
+     * Remove trailing null characters. They would give false alarms with the
+     * length check and with the embedded null check.
+     */
+#define TRIM0(s, l) do { while ((l) > 0 && (s)[(l)-1] == 0) --(l); } while (0)
+
+    TRIM0(utf8_value, utf8_length);
 
-    if (len >= CCERT_BUFSIZ) {
+    /*
+     * Enforce the length limit, because the caller will copy the result into
+     * a fixed-length buffer.
+     */
+    if (utf8_length >= CCERT_BUFSIZ) {
        msg_warn("%s: %s: peer %s too long: %d",
-                myname, TLScontext->namaddr, label, len);
-       RETURN(0);
+                myname, TLScontext->namaddr, label, utf8_length);
+       TLS_TEXT_NAME_RETURN(0);
     }
-    if (len != strlen((char *) utf)) {
-       msg_warn("%s: %s: internal NUL in peer %s",
+
+    /*
+     * Don't allow embedded nulls in ASCII or UTF-8 names. OpenSSL is
+     * responsible for producing properly-formatted UTF-8.
+     */
+    if (utf8_length != strlen((char *) utf8_value)) {
+       msg_warn("%s: %s: NULL character in peer %s",
                 myname, TLScontext->namaddr, label);
-       RETURN(0);
-    }
-    for (cp = (char *) utf; *cp; cp++) {
-       if (!ISASCII(*cp) || !ISPRINT(*cp)) {
-           msg_warn("%s: %s: non-printable characters in peer %s",
-                    myname, TLScontext->namaddr, label);
-           RETURN(0);
-       }
+       TLS_TEXT_NAME_RETURN(0);
     }
-    cp = mystrdup((char *) utf);
-    RETURN(cp);
+    TLS_TEXT_NAME_RETURN(mystrdup((char *) utf8_value));
 }
 
 /* tls_dns_name - Extract valid DNS name from subjectAltName value */
@@ -421,6 +395,7 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
     const char *myname = "tls_dns_name";
     char   *cp;
     const char *dnsname;
+    int     len;
 
     /*
      * Peername checks are security sensitive, carefully scrutinize the
@@ -443,6 +418,8 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
      * Safe to treat as an ASCII string possibly holding a DNS name
      */
     dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
+    len = ASN1_STRING_length(gn->d.ia5);
+    TRIM0(dnsname, len);
 
     /*
      * Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING
@@ -451,7 +428,7 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
      * always appended to make sure that the string is terminated, but the
      * ASN.1 length may differ from strlen().
      */
-    if (ASN1_STRING_length(gn->d.ia5) != strlen(dnsname)) {
+    if (len != strlen(dnsname)) {
        msg_warn("%s: %s: internal NUL in subjectAltName",
                 myname, TLScontext->namaddr);
        return 0;
@@ -463,14 +440,13 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
      * compare equal to the expected peername, so being more strict than
      * "printable" is likely excessive...
      */
-    for (cp = (char *) dnsname; cp && *cp; cp++)
-       if (!ISASCII(*cp) || !ISPRINT(*cp)) {
-           cp = mystrdup(dnsname);
-           msg_warn("%s: %s: non-printable characters in subjectAltName: %s",
-                    myname, TLScontext->namaddr, printable(cp, '?'));
-           myfree(cp);
-           return 0;
-       }
+    if (*dnsname && !allprint(dnsname)) {
+       cp = mystrdup(dnsname);
+       msg_warn("%s: %s: non-printable characters in subjectAltName: %.100s",
+                myname, TLScontext->namaddr, printable(cp, '?'));
+       myfree(cp);
+       return 0;
+    }
     return (dnsname);
 }