Robustness: skip LDAP queries with non-UTF-8 search strings
(in anticipation of UTF8SMTP support). File: global/dict_ldap.c.
- Strict UTF-8 validator per RFC 3629. File: util/valid_utf_8.c.
+ Strict UTF-8 validator per RFC 3629. File: util/valid_utf8_string.c.
20100601
Files: global/mail_params.h, mantools/postlink,
proto/postconf.proto, smtpd/smtpd.c, smtpd/smtpd_check.c.
-20140708
-
- Bugfix (introduced 20140701): did not restore jumpbuf
- while evaluatingsmtpd_policy_service_default_action.
- Viktor Dukhovni. File: smtpd/smtpd_check.c.
-
20140709
Cleanup: bitrot in unused function. File: global/defer.c.
Cleanup: add SYSLIBS minus static libraries while building
Postfix shared-library objects. Files: makedefs, util/Makefile.in,
global/Makefile.in, dns/Makefile.in, master/Makefile.in/.
+
+20140708
+
+ Bugfix (introduced 20140701): did not restore jumpbuf while
+ evaluatingsmtpd_policy_service_default_action. Viktor
+ Dukhovni. File: smtpd/smtpd_check.c.
+
+ Feature: VERY PRELIMINARY support for SMTPUTF8 based on an
+ initial implementation by Arnt Gulbrandsen, funded by CNNIC.
+ This implements the syntax of SMTP commands and DSN delivery
+ status notifications. It does not address the problem that
+ the same domain name may show up in different forms: an
+ UTF8-encoded name with non-ASCII charaters, or an IDNA-encoded
+ (xn--mumble) name with ASCII-only characters. This means
+ that access policies, mydestination, virtual_*_domains and
+ relay_domans will have to understand both forms in order
+ to provide complete coverage. For now, SMTPUTF8 support
+ must not be enabled except for testing.
+
+20140710
+
+ Portability: add '-Wl,--enable-new-dtags' to the linker
+ command line with building with Postfix shared libraries
+ on Linux. Viktor Dukhovni. file: makedefs.
+
+20140711
+
+ Background: What is SMTPUTF8 autodetection? Postfix cannot
+ rely solely on the sender's declaration that a message
+ requires SMTPUTF8 support, because UTF8 may be introduced
+ during local processing (for example, the client hostname
+ in Postfix's Received: header, adding @$myorigin or .$mydomain
+ to an incomplete address, address rewriting, alias expansion,
+ automatic BCC recipients, local forwarding, and modifications
+ made by header checks or Milter applications). This means
+ that some form of autodetection is needed that a message
+ requires SMTPUTF8 support.
+
+ Cleanup: don't try to distinguish between UTF that is already
+ present in a message or envelope, and UTF8 that is introduced
+ during local processing (see above). Maintaining this
+ distinction is too problematic.
+
+ Cleanup: mailing list friendliness. Allow delivery of
+ SMTPUTF8 mail to non-SMTPUTF8 servers when a message has
+ no UTF8 headers, no UTF8 envelope sender, and when the
+ specific delivery request contains no UTF8 envelope recipient.
+ This is needed for mailing lists that may have a mix of
+ UTF8 and non-UTF8 subscriber addresses. File: global/smtputf8.h,
+ smtp/smtp_proto.c.
+
+ Cleanup: moved all SMTPUTF8 detection to the cleanup server,
+ so that it can apply equally to sendmail command-line
+ submission, forwarded mail, postmaster notifications,
+ delivery status notifications, mail received with the qmqpd
+ server, address verification probes, as well as UTF8
+ introduced during local processing (see above). Files:
+ cleanup/cleanup_out.c, cleanup/cleanup_addr.c.
+
+ Cleanup: store the SMTPUTF8 message (i.e. non-recipient)
+ flags in the first queue file record, so that the queue
+ manager can find the information without having to read
+ every queue file record. Files: cleanup/cleanup_final.c,
+ *qmgr/qmgr_message.c.
+
+20140713
+
+ Interoperability: new parameter smtputf8_autodetect_classes
+ for selective autodetection that a message requires UTF8SMTP
+ support. During the initial SMTPUTF8 rollout, this is limited
+ by default to Postfix sendmail command-line submissions and
+ address verification probes. Sites that introduce UTF8
+ during local processing (see above) will have to enable
+ SMTPUTF8 autodetection for all mail sources. This feature
+ shares infrastructure with the older internal_filter_classes
+ feature. Files: bounce/bounce_notify_service.c,
+ bounce/bounce_notify_verp.c, bounce/bounce_one_service.c,
+ bounce/bounce_trace_service.c, bounce/bounce_warn_service.c,
+ global/int_filt.c, global/mail_proto.h, global/smtputf8.c,
+ local/forward.c, pickup/pickup.c, qmqpd/qmqpd.c, smtp/smtp_chat.c,
+ smtpd/smtpd.c, smtpd/smtpd_chat.c, verify/verify.c.
+
+ Feature: preliminary message/global support. This does not
+ yet parse encoded message/global (such as message/global
+ sent through an non-8BITMIME system). Such mail cannot yet
+ be inspected with header_checks. File: global/mime_state.c.
|| |platforms that are known to support this |
|| |feature. |
||_____________________________|______________________________________________|
+|| |Do not build with EAI (SMTPUTF8) support. By |
+||-DNO_EAI |default, EAI support is compiled in when the |
+|| |"icuuc" library and header files are found. |
+||_____________________________|______________________________________________|
|| |Do not build with IPv6 support. By default, |
|| |IPv6 support is compiled in on platforms that |
||-DNO_IPV6 |are known to have IPv6 support. Note: this |
|| |platforms that are known to support this |
|| |feature. |
|_\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+|| |Do not build with EAI (SMTPUTF8) support. By |
+||-DNO_EAI |default, EAI support is compiled in when the |
+|| |"icuuc" library and header files are found. |
+|_\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
|| |Do not build with IPv6 support. By default, |
|| |IPv6 support is compiled in on platforms that |
||-DNO_IPV6 |are known to have IPv6 support. Note: this |
--- /dev/null
+Why do we send SMTPUTF_FLAG_RECIPIENT in bounce requests when
+bouncing a single recipient?
+
+Should we encode headers with RFC 2047, when that is the only
+reason that Postfix cannot deliver to a non-UTF8SMTP server?
+
+Items below this line are closed.
+
+Submit DSNs with SMTPUTF8 auto-detection. This requires parsing
+the headers of message/global, message/global-headers,
+and message/global-delivery-status.
+
+Forward local mail with SMTPUTF8 auto-detection, but don't
+break mail that would have been delivered prior to SMTPUTF8
+support.
+
+mailinglist support: if a message requires SMTPUTF8 only because
+some recipient addresses are UTF8, then deliveries to other domains
+should not require SMTPUTF8. This means that Postfix needs to
+maintain multiple flags:
+
+1) The message has UTF8 header values. This is a queue file property.
+
+2) The message has an UTF8 sender address. This is also a queue
+file property.
+
+3) A specific delivery request contains UTF8 recipients. This is
+a delivery-request property.
+
+Only in cases 1) or 2) should all deliveries require SMTPUTF8.
+Otherwise, only cases 3) require SMTPUTF8, and all other
+deliveries can use lagacy SMTP.
+
+Is an smtputf8 bounce always 8bit?
+
+What happens when address rewriting or aliasing introduces non-ASCII
+domains or addresses?
+
+printable() stricter UTF8 parsing.
+
+lowercase() find a way to enable/disable UTF8
+
+qmqpd support.
+
+sendmail: auto-detect or command-line flag?
+
+bounce: don't scan the entire queue file for smtputf8 info. Just
+like encoding, receive smtputf8 info in the "bounce flush" request.
EPOLL support. By default, EPOLL support is compiled in on platforms
that are known to support this feature. </td> </tr>
+<tr> <td> </td> <td> -DNO_EAI </td> <td> Do not build with EAI
+(SMTPUTF8) support. By default, EAI support is compiled in when
+the "icuuc" library and header files are found. </td> </tr>
+
<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6
support. By default, IPv6 support is compiled in on platforms that
are known to have IPv6 support. Note: this directive is for debugging
<b>bounce</b> [generic Postfix daemon options]
<b>DESCRIPTION</b>
- The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta-
+ The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta‐
tus information. Each log file is named after the queue file that it
corresponds to, and is kept in a queue subdirectory named after the
service name in the <a href="master.5.html"><b>master.cf</b></a> file (either <b>bounce</b>, <b>defer</b> or <b>trace</b>).
The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon processes two types of service requests:
- <b>o</b> Append a recipient (non-)delivery status record to a per-message
+ · Append a recipient (non-)delivery status record to a per-message
log file.
- <b>o</b> Enqueue a delivery status notification message, with a copy of a
+ · Enqueue a delivery status notification message, with a copy of a
per-message log file and of the corresponding message. When the
delivery status notification message is enqueued successfully,
the per-message log file is deleted.
- The software does a best notification effort. A non-delivery notifica-
+ The software does a best notification effort. A non-delivery notifica‐
tion is sent even when the log file or the original message cannot be
read.
<a href="http://tools.ietf.org/html/rfc3464">RFC 3464</a> (Delivery Status Notifications)
<a href="http://tools.ietf.org/html/rfc3834">RFC 3834</a> (Auto-Submitted: message header)
<a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> (Internet Message Format)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6532">RFC 6532</a> (Internationalized Message Format)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
Postfix versions before 2.0.
<b><a href="postconf.5.html#bounce_notice_recipient">bounce_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
- ers of mail that Postfix did not deliver and of SMTP conversa-
+ The recipient of postmaster notifications with the message head‐
+ ers of mail that Postfix did not deliver and of SMTP conversa‐
tion transcripts of mail that Postfix did not receive.
<b><a href="postconf.5.html#bounce_size_limit">bounce_size_limit</a> (50000)</b>
Pathname of a configuration file with bounce message templates.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_notice_recipient">delay_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
+ The recipient of postmaster notifications with the message head‐
ers of mail that cannot be delivered within $<a href="postconf.5.html#delay_warning_time">delay_warning_time</a>
time units.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
+ Available in Postfix 2.12 and later:
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
The <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon always performs the following transformations:
- <b>o</b> Insert missing message headers: (<b>Resent-</b>) <b>From:</b>, <b>To:</b>, <b>Message-</b>
+ · Insert missing message headers: (<b>Resent-</b>) <b>From:</b>, <b>To:</b>, <b>Message-</b>
<b>Id:</b>, and <b>Date:</b>.
- <b>o</b> Transform envelope and header addresses to the standard
- <i>user@fully-qualified-domain</i> form that is expected by other Post-
+ · Transform envelope and header addresses to the standard
+ <i>user@fully-qualified-domain</i> form that is expected by other Post‐
fix programs. This task is delegated to the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a>
daemon.
- <b>o</b> Eliminate duplicate envelope recipient addresses.
+ · Eliminate duplicate envelope recipient addresses.
The following address transformations are optional:
- <b>o</b> Optionally, rewrite all envelope and header addresses according
+ · Optionally, rewrite all envelope and header addresses according
to the mappings specified in the <a href="canonical.5.html"><b>canonical</b>(5)</a> lookup tables.
- <b>o</b> Optionally, masquerade envelope sender addresses and message
+ · Optionally, masquerade envelope sender addresses and message
header addresses (i.e. strip host or domain information below
all domains listed in the <b><a href="postconf.5.html#masquerade_domains">masquerade_domains</a></b> parameter, except
for user names listed in <b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a></b>). By default,
address masquerading does not affect envelope recipients.
- <b>o</b> Optionally, expand envelope recipients according to information
+ · Optionally, expand envelope recipients according to information
found in the <a href="virtual.5.html"><b>virtual</b>(5)</a> lookup tables.
The <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon performs sanity checks on the content of each
<b><a href="postconf.5.html#header_checks">header_checks</a> (empty)</b>
Optional lookup tables for content inspection of primary non-
- MIME message headers, as specified in the <a href="header_checks.5.html"><b>header_checks</b>(5)</a> man-
+ MIME message headers, as specified in the <a href="header_checks.5.html"><b>header_checks</b>(5)</a> man‐
ual page.
Available in Postfix version 2.0 and later:
page.
<b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a> ($<a href="postconf.5.html#header_checks">header_checks</a>)</b>
- Optional lookup tables for content inspection of non-MIME mes-
+ Optional lookup tables for content inspection of non-MIME mes‐
sage headers in attached messages, as described in the
<a href="header_checks.5.html"><b>header_checks</b>(5)</a> manual page.
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#message_reject_characters">message_reject_characters</a> (empty)</b>
- The set of characters that Postfix will reject in message con-
+ The set of characters that Postfix will reject in message con‐
tent.
<b><a href="postconf.5.html#message_strip_characters">message_strip_characters</a> (empty)</b>
- The set of characters that Postfix will remove from message con-
+ The set of characters that Postfix will remove from message con‐
tent.
<b>BEFORE QUEUE MILTER CONTROLS</b>
does not arrive via the Postfix <a href="smtpd.8.html"><b>smtpd</b>(8)</a> server.
<b><a href="postconf.5.html#milter_protocol">milter_protocol</a> (6)</b>
- The mail filter protocol version and optional protocol exten-
+ The mail filter protocol version and optional protocol exten‐
sions for communication with a Milter application; prior to
Postfix 2.6 the default protocol is 2.
unavailable or mis-configured.
<b><a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
- The {daemon_name} macro value for Milter (mail filter) applica-
+ The {daemon_name} macro value for Milter (mail filter) applica‐
tions.
<b><a href="postconf.5.html#milter_macro_v">milter_macro_v</a> ($<a href="postconf.5.html#mail_name">mail_name</a> $<a href="postconf.5.html#mail_version">mail_version</a>)</b>
The {v} macro value for Milter (mail filter) applications.
<b><a href="postconf.5.html#milter_connect_timeout">milter_connect_timeout</a> (30s)</b>
- The time limit for connecting to a Milter (mail filter) applica-
+ The time limit for connecting to a Milter (mail filter) applica‐
tion, and for negotiating protocol options.
<b><a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> (30s)</b>
Reject mail with 8-bit text in message headers.
<b><a href="postconf.5.html#strict_8bitmime_body">strict_8bitmime_body</a> (no)</b>
- Reject 8-bit message body text without 8-bit MIME content encod-
+ Reject 8-bit message body text without 8-bit MIME content encod‐
ing information.
<b><a href="postconf.5.html#strict_mime_encoding_domain">strict_mime_encoding_domain</a> (no)</b>
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#detect_8bit_encoding_header">detect_8bit_encoding_header</a> (yes)</b>
- Automatically detect 8BITMIME body content by looking at Con-
+ Automatically detect 8BITMIME body content by looking at Con‐
tent-Transfer-Encoding: message headers; historically, this
behavior was hard-coded to be "always on".
<b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
Optional list of user names that are not subjected to address
- masquerading, even when their address matches $<a href="postconf.5.html#masquerade_domains">masquer</a>-
- <a href="postconf.5.html#masquerade_domains">ade_domains</a>.
+ masquerading, even when their address matches $masquer‐
+ ade_domains.
<b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
What address lookup tables copy an address extension from the
mapping.
<b><a href="postconf.5.html#sender_canonical_classes">sender_canonical_classes</a> (envelope_sender, header_sender)</b>
- What addresses are subject to <a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> address map-
+ What addresses are subject to <a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> address map‐
ping.
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#duplicate_filter_limit">duplicate_filter_limit</a> (1000)</b>
- The maximal number of addresses remembered by the address dupli-
+ The maximal number of addresses remembered by the address dupli‐
cate filter for <a href="aliases.5.html"><b>aliases</b>(5)</a> or <a href="virtual.5.html"><b>virtual</b>(5)</a> alias expansion, or for
<a href="showq.8.html"><b>showq</b>(8)</a> queue displays.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log-
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#delay_warning_time">delay_warning_time</a> (0h)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available in Postfix version 2.1 and later:
<b>bounce</b> [generic Postfix daemon options]
<b>DESCRIPTION</b>
- The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta-
+ The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta‐
tus information. Each log file is named after the queue file that it
corresponds to, and is kept in a queue subdirectory named after the
service name in the <a href="master.5.html"><b>master.cf</b></a> file (either <b>bounce</b>, <b>defer</b> or <b>trace</b>).
The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon processes two types of service requests:
- <b>o</b> Append a recipient (non-)delivery status record to a per-message
+ · Append a recipient (non-)delivery status record to a per-message
log file.
- <b>o</b> Enqueue a delivery status notification message, with a copy of a
+ · Enqueue a delivery status notification message, with a copy of a
per-message log file and of the corresponding message. When the
delivery status notification message is enqueued successfully,
the per-message log file is deleted.
- The software does a best notification effort. A non-delivery notifica-
+ The software does a best notification effort. A non-delivery notifica‐
tion is sent even when the log file or the original message cannot be
read.
<a href="http://tools.ietf.org/html/rfc3464">RFC 3464</a> (Delivery Status Notifications)
<a href="http://tools.ietf.org/html/rfc3834">RFC 3834</a> (Auto-Submitted: message header)
<a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> (Internet Message Format)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6532">RFC 6532</a> (Internationalized Message Format)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
Postfix versions before 2.0.
<b><a href="postconf.5.html#bounce_notice_recipient">bounce_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
- ers of mail that Postfix did not deliver and of SMTP conversa-
+ The recipient of postmaster notifications with the message head‐
+ ers of mail that Postfix did not deliver and of SMTP conversa‐
tion transcripts of mail that Postfix did not receive.
<b><a href="postconf.5.html#bounce_size_limit">bounce_size_limit</a> (50000)</b>
Pathname of a configuration file with bounce message templates.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_notice_recipient">delay_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
+ The recipient of postmaster notifications with the message head‐
ers of mail that cannot be delivered within $<a href="postconf.5.html#delay_warning_time">delay_warning_time</a>
time units.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
+ Available in Postfix 2.12 and later:
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
<b>DESCRIPTION</b>
The Postfix SMTP+LMTP client implements the SMTP and LMTP mail delivery
- protocols. It processes message delivery requests from the queue man-
+ protocols. It processes message delivery requests from the queue man‐
ager. Each request specifies a queue file, a sender address, a domain
or host to deliver to, and recipient information. This program expects
to be run from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
<i>domainname</i>
<i>domainname</i>:<i>port</i>
- Look up the mail exchangers for the specified domain, and con-
+ Look up the mail exchangers for the specified domain, and con‐
nect to the specified port (default: <b>smtp</b>).
[<i>hostname</i>]
[<i>address</i>]:<i>port</i>
Connect to the host at the specified address, and connect to the
- specified port (default: <b>smtp</b>). An IPv6 address must be format-
+ specified port (default: <b>smtp</b>). An IPv6 address must be format‐
ted as [<b>ipv6</b>:<i>address</i>].
<b>LMTP DESTINATION SYNTAX</b>
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
<a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a> (SMTP protocol)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Corrupted message
files are marked so that the queue manager can move them to the <b>corrupt</b>
queue for further inspection.
- Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas-
+ Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas‐
ter is notified of bounces, protocol problems, and of other trouble.
<b>BUGS</b>
there is no support for TLS, and connections are cached in-process,
making it ineffective when the client is used for multiple domains.
- Most smtp_<i>xxx</i> configuration parameters have an lmtp_<i>xxx</i> "mirror" param-
+ Most smtp_<i>xxx</i> configuration parameters have an lmtp_<i>xxx</i> "mirror" param‐
eter for the equivalent LMTP feature. This document describes only
those LMTP-related parameters that aren't simply "mirror" parameters.
<b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
When authenticating to a remote SMTP or LMTP server with the
default setting "no", send no SASL authoriZation ID (authzid);
- send only the SASL authentiCation ID (authcid) plus the auth-
+ send only the SASL authentiCation ID (authcid) plus the auth‐
cid's password.
Available in Postfix version 2.5 and later:
Available in Postfix version 2.6 and later:
<b><a href="postconf.5.html#tcp_windowsize">tcp_windowsize</a> (0)</b>
- An optional workaround for routers that break TCP window scal-
+ An optional workaround for routers that break TCP window scal‐
ing.
Available in Postfix version 2.8 and later:
Change the behavior of the smtp_*_timeout time limits, from a
time limit per read or write system call, to a time limit to
send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes-
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
<b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
<b><a href="postconf.5.html#smtp_delivery_status_filter">smtp_delivery_status_filter</a> ($<a href="postconf.5.html#default_delivery_status_filter">default_delivery_status_filter</a>)</b>
Optional filter for the <a href="smtp.8.html"><b>smtp</b>(8)</a> delivery agent to change the
- delivery status code or explanatory text of successful or unsuc-
+ delivery status code or explanatory text of successful or unsuc‐
cessful deliveries.
<b>MIME PROCESSING CONTROLS</b>
Enable SASL authentication in the Postfix SMTP client.
<b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
- Optional Postfix SMTP client lookup tables with one user-
+ Optional Postfix SMTP client lookup tables with one user‐
name:password entry per remote hostname or domain, or sender
address when sender-dependent authentication is enabled.
<b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
Postfix SMTP client SASL security options; as of Postfix 2.3 the
- list of available features depends on the SASL client implemen-
+ list of available features depends on the SASL client implemen‐
tation that is selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
Enable sender-dependent authentication in the Postfix SMTP
client; this is available only with SASL authentication, and
- disables SMTP connection caching to ensure that mail from dif-
+ disables SMTP connection caching to ensure that mail from dif‐
ferent senders will use the appropriate credentials.
<b><a href="postconf.5.html#smtp_sasl_path">smtp_sasl_path</a> (empty)</b>
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
- An optional table to prevent repeated SASL authentication fail-
+ An optional table to prevent repeated SASL authentication fail‐
ures with the same remote SMTP server hostname, username and
password.
<b><a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> (empty)</b>
A file containing CA certificates of root CAs trusted to sign
- either remote SMTP server certificates or intermediate CA cer-
+ either remote SMTP server certificates or intermediate CA cer‐
tificates.
<b><a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a> (empty)</b>
<b><a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> (empty)</b>
Additional list of ciphers or cipher types to exclude from the
- Postfix SMTP client cipher list at mandatory TLS security lev-
+ Postfix SMTP client cipher list at mandatory TLS security lev‐
els.
<b><a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a> (empty)</b>
<b><a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> (empty)</b>
Optional lookup tables with the Postfix SMTP client TLS security
- policy by next-hop destination; when a non-empty value is speci-
+ policy by next-hop destination; when a non-empty value is speci‐
fied, this overrides the obsolete <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> parameter.
<b><a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> (!SSLv2)</b>
Available in Postfix version 2.4 and later:
- <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a> ($<a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_secu</a>-</b>
- <b><a href="postconf.5.html#smtp_sasl_tls_security_options">rity_options</a>)</b>
+ <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a> ($smtp_sasl_tls_secu</b>‐\b‐
+ <b>rity_options)</b>
The SASL authentication security options that the Postfix SMTP
client uses for TLS encrypted SMTP sessions with a verified
server certificate.
<b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a> (empty)</b>
List of acceptable remote SMTP server certificate fingerprints
- for the "fingerprint" TLS security level (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
- <b><a href="postconf.5.html#smtp_tls_security_level">rity_level</a></b> = fingerprint).
+ for the "fingerprint" TLS security level (<b>smtp_tls_secu</b>‐\b‐
+ <b>rity_level</b> = fingerprint).
<b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (md5)</b>
The message digest algorithm used to construct remote SMTP
use with opportunistic TLS encryption.
<b><a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a> (empty)</b>
- File with the Postfix SMTP client ECDSA certificate in PEM for-
+ File with the Postfix SMTP client ECDSA certificate in PEM for‐
mat.
<b><a href="postconf.5.html#smtp_tls_eckey_file">smtp_tls_eckey_file</a> ($<a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a>)</b>
- File with the Postfix SMTP client ECDSA private key in PEM for-
+ File with the Postfix SMTP client ECDSA private key in PEM for‐
mat.
Available in Postfix version 2.7 and later:
<b><a href="postconf.5.html#smtp_tls_block_early_mail_reply">smtp_tls_block_early_mail_reply</a> (no)</b>
Try to detect a mail hijacking attack based on a TLS protocol
- vulnerability (CVE-2009-3555), where an attacker prepends mali-
+ vulnerability (CVE-2009-3555), where an attacker prepends mali‐
cious HELO, MAIL, RCPT, DATA commands to a Postfix SMTP client
TLS session.
<b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
Optional lookup tables with the Postfix SMTP client TLS usage
- policy by next-hop destination and by remote SMTP server host-
+ policy by next-hop destination and by remote SMTP server host‐
name.
<b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
cipher list.
<b>RESOURCE AND RATE CONTROLS</b>
- <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
- <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
- The maximal number of parallel deliveries to the same destina-
+ <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($default_destination_concur</b>‐\b‐
+ <b>rency_limit)</b>
+ The maximal number of parallel deliveries to the same destina‐
tion via the smtp message delivery transport.
<b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
- The maximal number of recipients per message for the smtp mes-
+ The maximal number of recipients per message for the smtp mes‐
sage delivery transport.
<b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
- The Postfix SMTP client time limit for completing a TCP connec-
+ The Postfix SMTP client time limit for completing a TCP connec‐
tion, or zero (use the operating system built-in time limit).
<b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
and for receiving the initial remote LMTP server response.
<b><a href="postconf.5.html#smtp_xforward_timeout">smtp_xforward_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the XFORWARD com-
+ The Postfix SMTP client time limit for sending the XFORWARD com‐
mand, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
<b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
- The amount of time during which Postfix will use an SMTP connec-
+ The amount of time during which Postfix will use an SMTP connec‐
tion repeatedly.
<b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
- Time limit for connection cache connect, send or receive opera-
+ Time limit for connection cache connect, send or receive opera‐
tions.
Available in Postfix version 2.9 and later:
Change the behavior of the smtp_*_timeout time limits, from a
time limit per read or write system call, to a time limit to
send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes-
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
Available in Postfix version 2.11 and later:
that an SMTP session may be reused before it is closed, or zero
(no limit).
+<b>SMTPUTF8 CONTROLS</b>
+ Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ Enable experimental SMTPUTF8 support for the protocols described
+ in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Enable SMTPUTF8 autodetection for the specified mail origin
+ classes.
+
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
The increment in verbose logging level when a remote client or
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
The recipient of postmaster notifications about mail delivery
- problems that are caused by policy, resource, software or proto-
+ problems that are caused by policy, resource, software or proto‐
col errors.
<b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
detects a "mail loops back to myself" error condition.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log-
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
<b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
When a remote LMTP server announces no DSN support, assume that
- the server performs final delivery, and send "delivered" deliv-
+ the server performs final delivery, and send "delivered" deliv‐
ery status notifications instead of "relayed".
<b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available with Postfix 2.2 and earlier:
to, and one or more recipients. This program expects to be run from
the <a href="master.8.html"><b>master</b>(8)</a> process manager.
- The <a href="local.8.html"><b>local</b>(8)</a> daemon updates queue files and marks recipients as fin-
+ The <a href="local.8.html"><b>local</b>(8)</a> daemon updates queue files and marks recipients as fin‐
ished, or it informs the queue manager that delivery should be tried
again at a later time. Delivery status reports are sent to the
<a href="bounce.8.html"><b>bounce</b>(8)</a>, <a href="defer.8.html"><b>defer</b>(8)</a> or <a href="trace.8.html"><b>trace</b>(8)</a> daemon as appropriate.
Upon delivery, the local delivery agent tries each pathname in the list
until a file is found.
- Delivery via ~/.<b>forward</b> files is done with the privileges of the recip-
+ Delivery via ~/.<b>forward</b> files is done with the privileges of the recip‐
ient. Thus, ~/.<b>forward</b> like files must be readable by the recipient,
and their parent directory needs to have "execute" permission for the
recipient.
- The <b><a href="postconf.5.html#forward_path">forward_path</a></b> parameter is subject to interpolation of <b>$user</b> (recip-
+ The <b><a href="postconf.5.html#forward_path">forward_path</a></b> parameter is subject to interpolation of <b>$user</b> (recip‐
ient username), <b>$home</b> (recipient home directory), <b>$shell</b> (recipient
shell), <b>$recipient</b> (complete recipient address), <b>$extension</b> (recipient
- address extension), <b>$domain</b> (recipient domain), <b>$local</b> (entire recipi-
+ address extension), <b>$domain</b> (recipient domain), <b>$local</b> (entire recipi‐
ent address localpart) and <b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>.</b> The forms
<i>${name?value}</i> and <i>${name:value}</i> expand conditionally to <i>value</i> when
<i>$name</i> is (is not) defined. Characters that may have special meaning to
acceptable characters is specified with the <b><a href="postconf.5.html#forward_expansion_filter">forward_expansion_filter</a></b>
configuration parameter.
- An alias or ~/.<b>forward</b> file may list any combination of external com-
+ An alias or ~/.<b>forward</b> file may list any combination of external com‐
mands, destination file names, <b>:include:</b> directives, or mail addresses.
- See <a href="aliases.5.html"><b>aliases</b>(5)</a> for a precise description. Each line in a user's .<b>for-</b>
+ See <a href="aliases.5.html"><b>aliases</b>(5)</a> for a precise description. Each line in a user's .<b>for</b>‐\b‐
<b>ward</b> file has the same syntax as the right-hand part of an alias.
When an address is found in its own alias expansion, delivery is made
to the user instead. When a user is listed in the user's own ~/.<b>forward</b>
- file, delivery is made to the user's mailbox instead. An empty ~/.<b>for-</b>
+ file, delivery is made to the user's mailbox instead. An empty ~/.<b>for</b>‐\b‐
<b>ward</b> file means do not forward mail.
In order to prevent the mail system from using up unreasonable amounts
are broken up into chunks of length <b><a href="postconf.5.html#line_length_limit">line_length_limit</a></b>.
While expanding aliases, ~/.<b>forward</b> files, and so on, the program
- attempts to avoid duplicate deliveries. The <b><a href="postconf.5.html#duplicate_filter_limit">duplicate_filter_limit</a></b> con-
+ attempts to avoid duplicate deliveries. The <b><a href="postconf.5.html#duplicate_filter_limit">duplicate_filter_limit</a></b> con‐
figuration parameter limits the number of remembered recipients.
<b>MAIL FORWARDING</b>
Mailbox delivery can be delegated to an external command specified with
the <b><a href="postconf.5.html#mailbox_command_maps">mailbox_command_maps</a></b> and <b><a href="postconf.5.html#mailbox_command">mailbox_command</a></b> configuration parameters.
- The command executes with the privileges of the recipient user (excep-
+ The command executes with the privileges of the recipient user (excep‐
tions: secondary groups are not enabled; in case of delivery as root,
the command executes with the privileges of <b><a href="postconf.5.html#default_privs">default_privs</a></b>).
Mailbox delivery can be delegated to alternative message transports
- specified in the <a href="master.5.html"><b>master.cf</b></a> file. The <b><a href="postconf.5.html#mailbox_transport_maps">mailbox_transport_maps</a></b> and <b><a href="postconf.5.html#mailbox_transport">mail</a>-</b>
- <b><a href="postconf.5.html#mailbox_transport">box_transport</a></b> configuration parameters specify an optional message
+ specified in the <a href="master.5.html"><b>master.cf</b></a> file. The <b><a href="postconf.5.html#mailbox_transport_maps">mailbox_transport_maps</a></b> and <b>mail</b>‐\b‐
+ <b>box_transport</b> configuration parameters specify an optional message
transport that is to be used for all local recipients, regardless of
- whether they are found in the UNIX passwd database. The <b><a href="postconf.5.html#fallback_transport_maps">fall</a>-</b>
- <b><a href="postconf.5.html#fallback_transport_maps">back_transport_maps</a></b> and <b><a href="postconf.5.html#fallback_transport">fallback_transport</a></b> parameters specify an
+ whether they are found in the UNIX passwd database. The <b>fall</b>‐\b‐
+ <b>back_transport_maps</b> and <b><a href="postconf.5.html#fallback_transport">fallback_transport</a></b> parameters specify an
optional message transport for recipients that are not found in the
<a href="aliases.5.html">aliases(5)</a> or UNIX passwd database.
to Postfix, prepends an optional <b>Delivered-To:</b> header with the final
envelope recipient address, prepends a <b>Return-Path:</b> header with the
envelope sender address, prepends a > character to lines beginning with
- "<b>From</b> ", and appends an empty line. The mailbox is locked for exclu-
+ "<b>From</b> ", and appends an empty line. The mailbox is locked for exclu‐
sive access while delivery is in progress. In case of problems, an
attempt is made to truncate the mailbox to its original length.
<b>EXTERNAL COMMAND DELIVERY</b>
The <b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_commands</a></b> configuration parameter restricts delivery
- to external commands. The default setting (<b>alias, forward</b>) forbids com-
+ to external commands. The default setting (<b>alias, forward</b>) forbids com‐
mand destinations in <b>:include:</b> files.
- Optionally, the process working directory is changed to the path speci-
+ Optionally, the process working directory is changed to the path speci‐
fied with <b><a href="postconf.5.html#command_execution_directory">command_execution_directory</a></b> (Postfix 2.2 and later). Failure
to change directory causes mail to be deferred.
- The <b><a href="postconf.5.html#command_execution_directory">command_execution_directory</a></b> parameter value is subject to interpo-
+ The <b><a href="postconf.5.html#command_execution_directory">command_execution_directory</a></b> parameter value is subject to interpo‐
lation of <b>$user</b> (recipient username), <b>$home</b> (recipient home directory),
<b>$shell</b> (recipient shell), <b>$recipient</b> (complete recipient address),
<b>$extension</b> (recipient address extension), <b>$domain</b> (recipient domain),
<b>$local</b> (entire recipient address localpart) and <b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>.</b>
The forms <i>${name?value}</i> and <i>${name:value}</i> expand conditionally to <i>value</i>
- when <i>$name</i> is (is not) defined. Characters that may have special mean-
+ when <i>$name</i> is (is not) defined. Characters that may have special mean‐
ing to the shell or file system are replaced by underscores. The list
- of acceptable characters is specified with the <b><a href="postconf.5.html#execution_directory_expansion_filter">execution_direc</a>-</b>
- <b><a href="postconf.5.html#execution_directory_expansion_filter">tory_expansion_filter</a></b> configuration parameter.
+ of acceptable characters is specified with the <b>execution_direc</b>‐\b‐
+ <b>tory_expansion_filter</b> configuration parameter.
The command is executed directly where possible. Assistance by the
shell (<b>/bin/sh</b> on UNIX systems) is used only when the command contains
A limited amount of command output (standard output and standard error)
is captured for inclusion with non-delivery status reports. A command
- is forcibly terminated if it does not complete within <b>com-</b>
+ is forcibly terminated if it does not complete within <b>com</b>‐\b‐
<b>mand_time_limit</b> seconds. Command exit status codes are expected to
follow the conventions defined in <<b>sysexits.h</b>>. Exit status 0 means
normal successful completion.
command output begins with an enhanced status code, this status code
takes precedence over the non-zero exit status.
- A limited amount of message context is exported via environment vari-
+ A limited amount of message context is exported via environment vari‐
ables. Characters that may have special meaning to the shell are
- replaced by underscores. The list of acceptable characters is speci-
+ replaced by underscores. The list of acceptable characters is speci‐
fied with the <b><a href="postconf.5.html#command_expansion_filter">command_expansion_filter</a></b> configuration parameter.
<b>SHELL</b> The recipient user's login shell.
<b>SENDER</b> The entire sender address.
- Additional remote client information is made available via the follow-
+ Additional remote client information is made available via the follow‐
ing environment variables:
<b>CLIENT_ADDRESS</b>
<b>/</b> for <b>qmail</b>-compatible <b>maildir</b> delivery.
The <b><a href="postconf.5.html#allow_mail_to_files">allow_mail_to_files</a></b> configuration parameter restricts delivery to
- external files. The default setting (<b>alias, forward</b>) forbids file des-
+ external files. The default setting (<b>alias, forward</b>) forbids file des‐
tinations in <b>:include:</b> files.
In the case of UNIX-style mailbox delivery, the <a href="local.8.html"><b>local</b>(8)</a> daemon
to separate address extensions from local recipient names.
For example, with "<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> = +</b>", mail for <i>name</i>+<i>foo</i> is
- delivered to the alias <i>name</i>+<i>foo</i> or to the alias <i>name</i>, to the destina-
+ delivered to the alias <i>name</i>+<i>foo</i> or to the alias <i>name</i>, to the destina‐
tions listed in ~<i>name</i>/.<b>forward</b>+<i>foo</i> or in ~<i>name</i>/.<b>forward</b>, to the mailbox
owned by the user <i>name</i>, or it is sent back as undeliverable.
files are marked so that the queue manager can move them to the <b>corrupt</b>
queue afterwards.
- Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas-
+ Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas‐
ter is notified of bounces and of other trouble.
<b>SECURITY</b>
The <a href="local.8.html"><b>local</b>(8)</a> delivery agent needs a dual personality 1) to access the
- private Postfix queue and IPC mechanisms, 2) to impersonate the recipi-
- ent and deliver to recipient-specified files or commands. It is there-
+ private Postfix queue and IPC mechanisms, 2) to impersonate the recipi‐
+ ent and deliver to recipient-specified files or commands. It is there‐
fore security sensitive.
The <a href="local.8.html"><b>local</b>(8)</a> delivery agent disallows regular expression substitution
<b>BUGS</b>
For security reasons, the message delivery status of external commands
or of external files is never checkpointed to file. As a result, the
- program may occasionally deliver more than once to a command or exter-
+ program may occasionally deliver more than once to a command or exter‐
nal file. Better safe than sorry.
Mutually-recursive aliases or ~/.<b>forward</b> files are not detected early.
- The resulting mail forwarding loop is broken by the use of the <b>Deliv-</b>
+ The resulting mail forwarding loop is broken by the use of the <b>Deliv</b>‐\b‐
<b>ered-To:</b> message header.
<b>CONFIGURATION PARAMETERS</b>
<b><a href="postconf.5.html#owner_request_special">owner_request_special</a> (yes)</b>
Give special treatment to owner-listname and listname-request
- address localparts: don't split such addresses when the <a href="postconf.5.html#recipient_delimiter">recipi</a>-
- <a href="postconf.5.html#recipient_delimiter">ent_delimiter</a> is set to "-".
+ address localparts: don't split such addresses when the recipi‐
+ ent_delimiter is set to "-".
<b><a href="postconf.5.html#sun_mailtool_compatibility">sun_mailtool_compatibility</a> (no)</b>
Obsolete SUN mailtool compatibility feature.
Available in Postfix version 2.5.3 and later:
<b><a href="postconf.5.html#strict_mailbox_ownership">strict_mailbox_ownership</a> (yes)</b>
- Defer delivery when a mailbox file is not owned by its recipi-
+ Defer delivery when a mailbox file is not owned by its recipi‐
ent.
<b><a href="postconf.5.html#reset_owner_alias">reset_owner_alias</a> (no)</b>
<b>DELIVERY METHOD CONTROLS</b>
The precedence of <a href="local.8.html"><b>local</b>(8)</a> delivery methods from high to low is:
aliases, .forward files, <a href="postconf.5.html#mailbox_transport_maps">mailbox_transport_maps</a>, <a href="postconf.5.html#mailbox_transport">mailbox_transport</a>,
- <a href="postconf.5.html#mailbox_command_maps">mailbox_command_maps</a>, <a href="postconf.5.html#mailbox_command">mailbox_command</a>, <a href="postconf.5.html#home_mailbox">home_mailbox</a>, <a href="postconf.5.html#mail_spool_directory">mail_spool_direc</a>-
- <a href="postconf.5.html#mail_spool_directory">tory</a>, <a href="postconf.5.html#fallback_transport_maps">fallback_transport_maps</a>, <a href="postconf.5.html#fallback_transport">fallback_transport</a>, and <a href="postconf.5.html#luser_relay">luser_relay</a>.
+ <a href="postconf.5.html#mailbox_command_maps">mailbox_command_maps</a>, <a href="postconf.5.html#mailbox_command">mailbox_command</a>, <a href="postconf.5.html#home_mailbox">home_mailbox</a>, mail_spool_direc‐
+ tory, <a href="postconf.5.html#fallback_transport_maps">fallback_transport_maps</a>, <a href="postconf.5.html#fallback_transport">fallback_transport</a>, and <a href="postconf.5.html#luser_relay">luser_relay</a>.
<b><a href="postconf.5.html#alias_maps">alias_maps</a> (see 'postconf -d' output)</b>
The alias databases that are used for <a href="local.8.html"><b>local</b>(8)</a> delivery.
Time limit for delivery to external commands.
<b><a href="postconf.5.html#duplicate_filter_limit">duplicate_filter_limit</a> (1000)</b>
- The maximal number of addresses remembered by the address dupli-
+ The maximal number of addresses remembered by the address dupli‐
cate filter for <a href="aliases.5.html"><b>aliases</b>(5)</a> or <a href="virtual.5.html"><b>virtual</b>(5)</a> alias expansion, or for
<a href="showq.8.html"><b>showq</b>(8)</a> queue displays.
<b><a href="postconf.5.html#local_destination_concurrency_limit">local_destination_concurrency_limit</a> (2)</b>
The maximal number of parallel deliveries via the local mail
- delivery transport to the same recipient (when "<a href="postconf.5.html#local_destination_recipient_limit">local_destina</a>-
- <a href="postconf.5.html#local_destination_recipient_limit">tion_recipient_limit</a> = 1") or the maximal number of parallel
- deliveries to the same local domain (when "<a href="postconf.5.html#local_destination_recipient_limit">local_destina</a>-
- <a href="postconf.5.html#local_destination_recipient_limit">tion_recipient_limit</a> > 1").
+ delivery transport to the same recipient (when "local_destina‐
+ tion_recipient_limit = 1") or the maximal number of parallel
+ deliveries to the same local domain (when "local_destina‐
+ tion_recipient_limit > 1").
<b><a href="postconf.5.html#local_destination_recipient_limit">local_destination_recipient_limit</a> (1)</b>
The maximal number of recipients per message delivery via the
<b><a href="postconf.5.html#command_expansion_filter">command_expansion_filter</a> (see 'postconf -d' output)</b>
Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery agent allows
- in $name expansions of $<a href="postconf.5.html#mailbox_command">mailbox_command</a> and $<a href="postconf.5.html#command_execution_directory">command_execu</a>-
- <a href="postconf.5.html#command_execution_directory">tion_directory</a>.
+ in $name expansions of $<a href="postconf.5.html#mailbox_command">mailbox_command</a> and $command_execu‐
+ tion_directory.
<b><a href="postconf.5.html#default_privs">default_privs</a> (nobody)</b>
The default rights used by the <a href="local.8.html"><b>local</b>(8)</a> delivery agent for
Available in Postfix version 2.5.3 and later:
<b><a href="postconf.5.html#strict_mailbox_ownership">strict_mailbox_ownership</a> (yes)</b>
- Defer delivery when a mailbox file is not owned by its recipi-
+ Defer delivery when a mailbox file is not owned by its recipi‐
ent.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log-
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#export_environment">export_environment</a> (see 'postconf -d' output)</b>
internal communication channel.
<b><a href="postconf.5.html#local_command_shell">local_command_shell</a> (empty)</b>
- Optional shell program for <a href="local.8.html"><b>local</b>(8)</a> delivery to non-Postfix com-
+ Optional shell program for <a href="local.8.html"><b>local</b>(8)</a> delivery to non-Postfix com‐
mand.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
process will service before terminating voluntarily.
<b><a href="postconf.5.html#prepend_delivered_header">prepend_delivered_header</a> (command, file, forward)</b>
- The message delivery contexts where the Postfix <a href="local.8.html"><b>local</b>(8)</a> deliv-
+ The message delivery contexts where the Postfix <a href="local.8.html"><b>local</b>(8)</a> deliv‐
ery agent prepends a Delivered-To: message header with the
address that the mail was delivered to.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>FILES</b>
<b>sendmail -I</b>
<b>DESCRIPTION</b>
- The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com-
+ The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com‐
patibility interface. For the sake of compatibility with existing
applications, some Sendmail command-line options are recognized but
silently ignored.
arranges for delivery. Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> relies on the <a href="postdrop.1.html"><b>postdrop</b>(1)</a>
command to create a queue file in the <b>maildrop</b> directory.
- Specific command aliases are provided for other common modes of opera-
+ Specific command aliases are provided for other common modes of opera‐
tion:
<b>mailq</b> List the mail queue. Each entry shows the queue file ID, message
<b>*</b> The message is in the <b>active</b> queue, i.e. the message is
selected for delivery.
- <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv-
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv‐
ery attempt will be made until the mail is taken off
hold.
<b>newaliases</b>
Initialize the alias database. If no input file is specified
(with the <b>-oA</b> option, see below), the program processes the
- file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame-
+ file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame‐
ter. If no alias database type is specified, the program uses
the type specified with the <b><a href="postconf.5.html#default_database_type">default_database_type</a></b> configuration
parameter. This mode of operation is implemented by running the
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> command above.
<b>-bl</b> Go into daemon mode. To accept only local connections as with
- Sendmail's <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
+ Sendmail´s <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
the Postfix <a href="postconf.5.html"><b>main.cf</b></a> configuration file.
<b>-bm</b> Read mail from standard input and arrange for delivery. This is
before 2.3.
With all Postfix versions, you can specify a directory pathname
- with the MAIL_CONFIG environment variable to override the loca-
+ with the MAIL_CONFIG environment variable to override the loca‐
tion of configuration files.
<b>-F</b> <i>full</i><b>_</b><i>name</i>
Set the sender full name. This overrides the NAME environment
- variable, and is used only with messages that have no <b>From:</b> mes-
+ variable, and is used only with messages that have no <b>From:</b> mes‐
sage header.
<b>-f</b> <i>sender</i>
the <b>Errors-To:</b> message header overrides the error return
address.
- <b>-G</b> Gateway (relay) submission, as opposed to initial user submis-
- sion. Either do not rewrite addresses at all, or update incom-
+ <b>-G</b> Gateway (relay) submission, as opposed to initial user submis‐
+ sion. Either do not rewrite addresses at all, or update incom‐
plete addresses with the domain information specified with
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a></b>.
<b>-I</b> Initialize alias database. See the <b>newaliases</b> command above.
- <b>-i</b> When reading a message from standard input, don't treat a line
+ <b>-i</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-L</b> <i>label</i> (ignored)
<b>-o7</b> (ignored)
<b>-o8</b> (ignored)
- To send 8-bit or binary content, use an appropriate MIME encap-
+ To send 8-bit or binary content, use an appropriate MIME encap‐
sulation and specify the appropriate <b>-B</b> command-line option.
- <b>-oi</b> When reading a message from standard input, don't treat a line
+ <b>-oi</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-om</b> (ignored)
The sender is never eliminated from alias etc. expansions.
<b>-o</b> <i>x value</i> (ignored)
- Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame-
+ Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame‐
ter in <a href="postconf.5.html"><b>main.cf</b></a> instead.
<b>-r</b> <i>sender</i>
This option is ignored before Postfix version 2.10.
- <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe-
+ <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe‐
cuting the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
Warning: flushing undeliverable mail frequently will result in
poor delivery performance of all other mail.
<b>-q</b><i>interval</i> (ignored)
- The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config-
+ The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config‐
uration parameter instead.
<b>-qI</b><i>queueid</i>
Schedule immediate delivery of mail with the specified queue ID.
- This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com-
+ This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com‐
mand, and is available with Postfix version 2.4 and later.
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is queued for the
- named <i>site</i>. This option accepts only <i>site</i> names that are eligi-
- ble for the "fast flush" service, and is implemented by execut-
+ named <i>site</i>. This option accepts only <i>site</i> names that are eligi‐
+ ble for the "fast flush" service, and is implemented by execut‐
ing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command. See <a href="flush.8.html"><b>flush</b>(8)</a> for more information
about the "fast flush" service.
<b>-XV</b><i>xy</i> (Postfix 2.2 and earlier: <b>-V</b><i>xy</i>)
As <b>-XV</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter characters,
- instead of the characters specified with the <b><a href="postconf.5.html#default_verp_delimiters">default_verp_delim</a>-</b>
- <b><a href="postconf.5.html#default_verp_delimiters">iters</a></b> configuration parameter.
+ instead of the characters specified with the <b>default_verp_delim</b>‐\b‐
+ <b>iters</b> configuration parameter.
- <b>-v</b> Send an email report of the first delivery attempt (Postfix ver-
- sions 2.1 and later). Mail delivery always happens in the back-
- ground. When multiple <b>-v</b> options are given, enable verbose log-
+ <b>-v</b> Send an email report of the first delivery attempt (Postfix ver‐
+ sions 2.1 and later). Mail delivery always happens in the back‐
+ ground. When multiple <b>-v</b> options are given, enable verbose log‐
ging for debugging purposes.
<b>-X</b> <i>log</i><b>_</b><i>file</i> (ignored)
no <b>From:</b> message header. See also the <b>-F</b> option above.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
- gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
- <a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro‐
+ gram. The text below provides only a parameter summary. See <b>post</b>‐\b‐
+ <b>conf</b>(5) for more details including examples.
<b>COMPATIBILITY CONTROLS</b>
Available with Postfix 2.9 and later:
List of users who are authorized to view the queue.
<b><a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
- List of users who are authorized to submit mail with the <a href="sendmail.1.html"><b>send-</b></a>
- <a href="sendmail.1.html"><b>mail</b>(1)</a> command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com-
+ List of users who are authorized to submit mail with the <b>send</b>‐\b‐
+ <b>mail</b>(1) command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com‐
mand).
<b>RESOURCE AND RATE CONTROLS</b>
the Postfix "fast flush" service.
<b><a href="postconf.5.html#fast_flush_domains">fast_flush_domains</a> ($<a href="postconf.5.html#relay_domains">relay_domains</a>)</b>
- Optional list of destinations that are eligible for per-destina-
+ Optional list of destinations that are eligible for per-destina‐
tion logfiles with mail that is queued to those destinations.
<b>VERP CONTROLS</b>
The location of all postfix administrative commands.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_directory">daemon_directory</a> (see 'postconf -d' output)</b>
The time after which the sender receives a copy of the message
headers of mail that is still queued.
- <b><a href="postconf.5.html#enable_errors_to">enable_errors_to</a> (no)</b>
- Report mail delivery errors to the address specified with the
- non-standard Errors-To: message header, instead of the envelope
- sender address (this feature is removed with Postfix version
- 2.2, is turned off by default with Postfix version 2.1, and is
- always turned on with older Postfix versions).
-
<b><a href="postconf.5.html#mail_owner">mail_owner</a> (postfix)</b>
The UNIX system account that owns the Postfix queue and most
Postfix daemon processes.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>FILES</b>
<b>sendmail -I</b>
<b>DESCRIPTION</b>
- The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com-
+ The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com‐
patibility interface. For the sake of compatibility with existing
applications, some Sendmail command-line options are recognized but
silently ignored.
arranges for delivery. Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> relies on the <a href="postdrop.1.html"><b>postdrop</b>(1)</a>
command to create a queue file in the <b>maildrop</b> directory.
- Specific command aliases are provided for other common modes of opera-
+ Specific command aliases are provided for other common modes of opera‐
tion:
<b>mailq</b> List the mail queue. Each entry shows the queue file ID, message
<b>*</b> The message is in the <b>active</b> queue, i.e. the message is
selected for delivery.
- <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv-
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv‐
ery attempt will be made until the mail is taken off
hold.
<b>newaliases</b>
Initialize the alias database. If no input file is specified
(with the <b>-oA</b> option, see below), the program processes the
- file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame-
+ file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame‐
ter. If no alias database type is specified, the program uses
the type specified with the <b><a href="postconf.5.html#default_database_type">default_database_type</a></b> configuration
parameter. This mode of operation is implemented by running the
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> command above.
<b>-bl</b> Go into daemon mode. To accept only local connections as with
- Sendmail's <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
+ Sendmail´s <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
the Postfix <a href="postconf.5.html"><b>main.cf</b></a> configuration file.
<b>-bm</b> Read mail from standard input and arrange for delivery. This is
before 2.3.
With all Postfix versions, you can specify a directory pathname
- with the MAIL_CONFIG environment variable to override the loca-
+ with the MAIL_CONFIG environment variable to override the loca‐
tion of configuration files.
<b>-F</b> <i>full</i><b>_</b><i>name</i>
Set the sender full name. This overrides the NAME environment
- variable, and is used only with messages that have no <b>From:</b> mes-
+ variable, and is used only with messages that have no <b>From:</b> mes‐
sage header.
<b>-f</b> <i>sender</i>
the <b>Errors-To:</b> message header overrides the error return
address.
- <b>-G</b> Gateway (relay) submission, as opposed to initial user submis-
- sion. Either do not rewrite addresses at all, or update incom-
+ <b>-G</b> Gateway (relay) submission, as opposed to initial user submis‐
+ sion. Either do not rewrite addresses at all, or update incom‐
plete addresses with the domain information specified with
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a></b>.
<b>-I</b> Initialize alias database. See the <b>newaliases</b> command above.
- <b>-i</b> When reading a message from standard input, don't treat a line
+ <b>-i</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-L</b> <i>label</i> (ignored)
<b>-o7</b> (ignored)
<b>-o8</b> (ignored)
- To send 8-bit or binary content, use an appropriate MIME encap-
+ To send 8-bit or binary content, use an appropriate MIME encap‐
sulation and specify the appropriate <b>-B</b> command-line option.
- <b>-oi</b> When reading a message from standard input, don't treat a line
+ <b>-oi</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-om</b> (ignored)
The sender is never eliminated from alias etc. expansions.
<b>-o</b> <i>x value</i> (ignored)
- Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame-
+ Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame‐
ter in <a href="postconf.5.html"><b>main.cf</b></a> instead.
<b>-r</b> <i>sender</i>
This option is ignored before Postfix version 2.10.
- <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe-
+ <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe‐
cuting the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
Warning: flushing undeliverable mail frequently will result in
poor delivery performance of all other mail.
<b>-q</b><i>interval</i> (ignored)
- The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config-
+ The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config‐
uration parameter instead.
<b>-qI</b><i>queueid</i>
Schedule immediate delivery of mail with the specified queue ID.
- This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com-
+ This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com‐
mand, and is available with Postfix version 2.4 and later.
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is queued for the
- named <i>site</i>. This option accepts only <i>site</i> names that are eligi-
- ble for the "fast flush" service, and is implemented by execut-
+ named <i>site</i>. This option accepts only <i>site</i> names that are eligi‐
+ ble for the "fast flush" service, and is implemented by execut‐
ing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command. See <a href="flush.8.html"><b>flush</b>(8)</a> for more information
about the "fast flush" service.
<b>-XV</b><i>xy</i> (Postfix 2.2 and earlier: <b>-V</b><i>xy</i>)
As <b>-XV</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter characters,
- instead of the characters specified with the <b><a href="postconf.5.html#default_verp_delimiters">default_verp_delim</a>-</b>
- <b><a href="postconf.5.html#default_verp_delimiters">iters</a></b> configuration parameter.
+ instead of the characters specified with the <b>default_verp_delim</b>‐\b‐
+ <b>iters</b> configuration parameter.
- <b>-v</b> Send an email report of the first delivery attempt (Postfix ver-
- sions 2.1 and later). Mail delivery always happens in the back-
- ground. When multiple <b>-v</b> options are given, enable verbose log-
+ <b>-v</b> Send an email report of the first delivery attempt (Postfix ver‐
+ sions 2.1 and later). Mail delivery always happens in the back‐
+ ground. When multiple <b>-v</b> options are given, enable verbose log‐
ging for debugging purposes.
<b>-X</b> <i>log</i><b>_</b><i>file</i> (ignored)
no <b>From:</b> message header. See also the <b>-F</b> option above.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
- gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
- <a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro‐
+ gram. The text below provides only a parameter summary. See <b>post</b>‐\b‐
+ <b>conf</b>(5) for more details including examples.
<b>COMPATIBILITY CONTROLS</b>
Available with Postfix 2.9 and later:
List of users who are authorized to view the queue.
<b><a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
- List of users who are authorized to submit mail with the <a href="sendmail.1.html"><b>send-</b></a>
- <a href="sendmail.1.html"><b>mail</b>(1)</a> command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com-
+ List of users who are authorized to submit mail with the <b>send</b>‐\b‐
+ <b>mail</b>(1) command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com‐
mand).
<b>RESOURCE AND RATE CONTROLS</b>
the Postfix "fast flush" service.
<b><a href="postconf.5.html#fast_flush_domains">fast_flush_domains</a> ($<a href="postconf.5.html#relay_domains">relay_domains</a>)</b>
- Optional list of destinations that are eligible for per-destina-
+ Optional list of destinations that are eligible for per-destina‐
tion logfiles with mail that is queued to those destinations.
<b>VERP CONTROLS</b>
The location of all postfix administrative commands.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_directory">daemon_directory</a> (see 'postconf -d' output)</b>
The time after which the sender receives a copy of the message
headers of mail that is still queued.
- <b><a href="postconf.5.html#enable_errors_to">enable_errors_to</a> (no)</b>
- Report mail delivery errors to the address specified with the
- non-standard Errors-To: message header, instead of the envelope
- sender address (this feature is removed with Postfix version
- 2.2, is turned off by default with Postfix version 2.1, and is
- always turned on with older Postfix versions).
-
<b><a href="postconf.5.html#mail_owner">mail_owner</a> (postfix)</b>
The UNIX system account that owns the Postfix queue and most
Postfix daemon processes.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>FILES</b>
specified <i>transport:destination</i>.
<b><a href="postconf.5.html#receive_override_options">receive_override_options</a> (empty)</b>
- Enable or disable recipient validation, built-in content filter-
+ Enable or disable recipient validation, built-in content filter‐
ing, or address mapping.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>SEE ALSO</b>
Postfix 2.3 and later use <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> instead. </p>
+</DD>
+
+<DT><b><a name="smtputf8_autodetect_classes">smtputf8_autodetect_classes</a>
+(default: sendmail, verify)</b></DT><DD>
+
+<p> Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes. This is a workaround to avoid chicken-and-egg
+problems during the initial SMTPUTF8 roll-out in environments with
+pre-existing mail flows that contain UTF8. Those mail flows should
+not break because Postfix suddenly refuses to deliver such mail
+to down-stream MTAs that don't announce SMTPUTF8 support. </p>
+
+<p> The problem is that Postfix cannot rely solely on the sender's
+declaration that a message requires SMTPUTF8 support, because UTF8
+may be introduced during local processing (for example, the client
+hostname in Postfix's Received: header, adding @$<a href="postconf.5.html#myorigin">myorigin</a> or
+.$<a href="postconf.5.html#mydomain">mydomain</a> to an incomplete address, address rewriting, alias
+expansion, automatic BCC recipients, local forwarding, and changes
+made by header checks or Milter applications). </p>
+
+<p> For now, the default is to enable "SMTPUTF8 required" autodetection
+only for Postfix sendmail command-line submissions and address
+verification probes. This may change once SMTPUTF8 support achieves
+world domination. However, sites that add UTF8 content via local
+processing (see above) should autodetect the need for SMTPUTF8
+support for all email.</p>
+
+<p> Specify one or more of the following: </p>
+
+<dl compact>
+
+<dt> <b> sendmail </b> </dt> <dd> Submission with the Postfix
+<a href="sendmail.1.html">sendmail(1)</a> command. </dd>
+
+<dt> <b> smtpd </b> </dt> <dd> Mail received with the <a href="smtpd.8.html">smtpd(8)</a>
+daemon. </dd>
+
+<dt> <b> qmqpd </b> </dt> <dd> Mail received with the <a href="qmqpd.8.html">qmqpd(8)</a>
+daemon. </dd>
+
+<dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing.
+</dd>
+
+<dt> <b> bounce </b> </dt> <dd> Submission by the <a href="bounce.8.html">bounce(8)</a> daemon.
+</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>
+
+<dt> <b> verify </b> </dt> <dd> Address verification probe from the
+<a href="verify.8.html">verify(8)</a> daemon. </dd>
+
+<dt> <b> all </b> </dt> <dd> Enable SMTPUTF8 autodetection for all
+mail. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="smtputf8_enable">smtputf8_enable</a>
+(default: no)</b></DT><DD>
+
+<p> Enable experimental SMTPUTF8 support for the protocols described
+in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533. This requires that Postfix is built to support
+these protocols. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="soft_bounce">soft_bounce</a>
</p>
+</DD>
+
+<DT><b><a name="strict_smtputf8">strict_smtputf8</a>
+(default: no)</b></DT><DD>
+
+<p> Enable stricter enforcement of the SMTPUTF8 protocol. The Postfix
+SMTP server accepts UTF8 sender or recipient addresses only when
+the client requests an SMTPUTF8 mail transaction. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="sun_mailtool_compatibility">sun_mailtool_compatibility</a>
of set-group ID privileges, a non-standard directory is allowed
only if:
- <b>o</b> The name is listed in the standard <a href="postconf.5.html"><b>main.cf</b></a> file with the
+ · The name is listed in the standard <a href="postconf.5.html"><b>main.cf</b></a> file with the
<b><a href="postconf.5.html#alternate_config_directories">alternate_config_directories</a></b> configuration parameter.
- <b>o</b> The command is invoked by the super-user.
+ · The command is invoked by the super-user.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
- gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
- <a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro‐
+ gram. The text below provides only a parameter summary. See <b>post</b>‐\b‐
+ <b>conf</b>(5) for more details including examples.
<b><a href="postconf.5.html#alternate_config_directories">alternate_config_directories</a> (empty)</b>
A list of non-default Postfix configuration directories that may
via the MAIL_CONFIG environment parameter.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b><a href="postconf.5.html#trigger_timeout">trigger_timeout</a> (10s)</b>
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
- List of users who are authorized to submit mail with the <a href="sendmail.1.html"><b>send-</b></a>
- <a href="sendmail.1.html"><b>mail</b>(1)</a> command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com-
+ List of users who are authorized to submit mail with the <b>send</b>‐\b‐
+ <b>mail</b>(1) command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com‐
mand).
<b>FILES</b>
<b>qmqpd</b> [generic Postfix daemon options]
<b>DESCRIPTION</b>
- The Postfix QMQP server receives one message per connection. Each mes-
+ The Postfix QMQP server receives one message per connection. Each mes‐
sage is piped through the <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon, and is placed into the
<a href="QSHAPE_README.html#incoming_queue"><b>incoming</b> queue</a> as one single queue file. The program expects to be run
from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
- The QMQP server implements one access policy: only explicitly autho-
+ The QMQP server implements one access policy: only explicitly autho‐
rized client hosts are allowed to use the service.
<b>SECURITY</b>
It is therefore not possible to reject individual recipients.
The QMQP protocol requires the server to receive the entire message
- before replying. If a message is malformed, or if any netstring compo-
+ before replying. If a message is malformed, or if any netstring compo‐
nent is longer than acceptable, Postfix replies immediately and closes
the connection. It is left up to the client to handle the situation.
specified <i>transport:destination</i>.
<b><a href="postconf.5.html#receive_override_options">receive_override_options</a> (empty)</b>
- Enable or disable recipient validation, built-in content filter-
+ Enable or disable recipient validation, built-in content filter‐
ing, or address mapping.
+<b>SMTPUTF8 CONTROLS</b>
+ Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
+
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#line_length_limit">line_length_limit</a> (2048)</b>
- Upon input, long lines are chopped up into pieces of at most
+ Upon input, long lines are chopped up into pieces of at most
this length; upon delivery, long lines are reconstructed.
<b><a href="postconf.5.html#hopcount_limit">hopcount_limit</a> (50)</b>
in the primary message headers.
<b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
- The maximal size in bytes of a message, including envelope
+ The maximal size in bytes of a message, including envelope
information.
<b><a href="postconf.5.html#qmqpd_timeout">qmqpd_timeout</a> (300s)</b>
- The time limit for sending or receiving information over the
+ The time limit for sending or receiving information over the
network.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
- The increment in verbose logging level when a remote client or
+ The increment in verbose logging level when a remote client or
server matches a pattern in the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
<b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
- Optional list of remote client or server hostname or network
+ Optional list of remote client or server hostname or network
address patterns that cause the verbose logging level to
increase by the amount specified in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
<b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
- Safety net to keep mail queued that would otherwise be returned
+ Safety net to keep mail queued that would otherwise be returned
to the sender.
<b>TARPIT CONTROLS</b>
<b><a href="postconf.5.html#qmqpd_error_delay">qmqpd_error_delay</a> (1s)</b>
- How long the Postfix QMQP server will pause before sending a
+ How long the Postfix QMQP server will pause before sending a
negative reply to the remote QMQP client.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to handle a
+ How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
- The time limit for sending or receiving information over an
+ The time limit for sending or receiving information over an
internal communication channel.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix daemon process
+ The maximum amount of time that an idle Postfix daemon process
waits for an incoming connection before terminating voluntarily.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
The process name of a Postfix command or daemon process.
<b><a href="postconf.5.html#qmqpd_authorized_clients">qmqpd_authorized_clients</a> (empty)</b>
- What remote QMQP clients are allowed to connect to the Postfix
+ What remote QMQP clients are allowed to connect to the Postfix
QMQP server port.
<b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b><a href="postconf.5.html#verp_delimiter_filter">verp_delimiter_filter</a> (-=+)</b>
- The characters Postfix accepts as VERP delimiter characters on
+ The characters Postfix accepts as VERP delimiter characters on
the Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command line and in SMTP commands.
Available in Postfix version 2.5 and later:
<b>sendmail -I</b>
<b>DESCRIPTION</b>
- The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com-
+ The Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> command implements the Postfix to Sendmail com‐
patibility interface. For the sake of compatibility with existing
applications, some Sendmail command-line options are recognized but
silently ignored.
arranges for delivery. Postfix <a href="sendmail.1.html"><b>sendmail</b>(1)</a> relies on the <a href="postdrop.1.html"><b>postdrop</b>(1)</a>
command to create a queue file in the <b>maildrop</b> directory.
- Specific command aliases are provided for other common modes of opera-
+ Specific command aliases are provided for other common modes of opera‐
tion:
<b>mailq</b> List the mail queue. Each entry shows the queue file ID, message
<b>*</b> The message is in the <b>active</b> queue, i.e. the message is
selected for delivery.
- <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv-
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no further deliv‐
ery attempt will be made until the mail is taken off
hold.
<b>newaliases</b>
Initialize the alias database. If no input file is specified
(with the <b>-oA</b> option, see below), the program processes the
- file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame-
+ file(s) specified with the <b><a href="postconf.5.html#alias_database">alias_database</a></b> configuration parame‐
ter. If no alias database type is specified, the program uses
the type specified with the <b><a href="postconf.5.html#default_database_type">default_database_type</a></b> configuration
parameter. This mode of operation is implemented by running the
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> command above.
<b>-bl</b> Go into daemon mode. To accept only local connections as with
- Sendmail's <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
+ Sendmail´s <b>-bl</b> option, specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback</b>" in
the Postfix <a href="postconf.5.html"><b>main.cf</b></a> configuration file.
<b>-bm</b> Read mail from standard input and arrange for delivery. This is
before 2.3.
With all Postfix versions, you can specify a directory pathname
- with the MAIL_CONFIG environment variable to override the loca-
+ with the MAIL_CONFIG environment variable to override the loca‐
tion of configuration files.
<b>-F</b> <i>full</i><b>_</b><i>name</i>
Set the sender full name. This overrides the NAME environment
- variable, and is used only with messages that have no <b>From:</b> mes-
+ variable, and is used only with messages that have no <b>From:</b> mes‐
sage header.
<b>-f</b> <i>sender</i>
the <b>Errors-To:</b> message header overrides the error return
address.
- <b>-G</b> Gateway (relay) submission, as opposed to initial user submis-
- sion. Either do not rewrite addresses at all, or update incom-
+ <b>-G</b> Gateway (relay) submission, as opposed to initial user submis‐
+ sion. Either do not rewrite addresses at all, or update incom‐
plete addresses with the domain information specified with
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a></b>.
<b>-I</b> Initialize alias database. See the <b>newaliases</b> command above.
- <b>-i</b> When reading a message from standard input, don't treat a line
+ <b>-i</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-L</b> <i>label</i> (ignored)
<b>-o7</b> (ignored)
<b>-o8</b> (ignored)
- To send 8-bit or binary content, use an appropriate MIME encap-
+ To send 8-bit or binary content, use an appropriate MIME encap‐
sulation and specify the appropriate <b>-B</b> command-line option.
- <b>-oi</b> When reading a message from standard input, don't treat a line
+ <b>-oi</b> When reading a message from standard input, don´t treat a line
with only a <b>.</b> character as the end of input.
<b>-om</b> (ignored)
The sender is never eliminated from alias etc. expansions.
<b>-o</b> <i>x value</i> (ignored)
- Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame-
+ Set option <i>x</i> to <i>value</i>. Use the equivalent configuration parame‐
ter in <a href="postconf.5.html"><b>main.cf</b></a> instead.
<b>-r</b> <i>sender</i>
This option is ignored before Postfix version 2.10.
- <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe-
+ <b>-q</b> Attempt to deliver all queued mail. This is implemented by exe‐
cuting the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
Warning: flushing undeliverable mail frequently will result in
poor delivery performance of all other mail.
<b>-q</b><i>interval</i> (ignored)
- The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config-
+ The interval between queue runs. Use the <b><a href="postconf.5.html#queue_run_delay">queue_run_delay</a></b> config‐
uration parameter instead.
<b>-qI</b><i>queueid</i>
Schedule immediate delivery of mail with the specified queue ID.
- This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com-
+ This option is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> com‐
mand, and is available with Postfix version 2.4 and later.
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is queued for the
- named <i>site</i>. This option accepts only <i>site</i> names that are eligi-
- ble for the "fast flush" service, and is implemented by execut-
+ named <i>site</i>. This option accepts only <i>site</i> names that are eligi‐
+ ble for the "fast flush" service, and is implemented by execut‐
ing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command. See <a href="flush.8.html"><b>flush</b>(8)</a> for more information
about the "fast flush" service.
<b>-XV</b><i>xy</i> (Postfix 2.2 and earlier: <b>-V</b><i>xy</i>)
As <b>-XV</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter characters,
- instead of the characters specified with the <b><a href="postconf.5.html#default_verp_delimiters">default_verp_delim</a>-</b>
- <b><a href="postconf.5.html#default_verp_delimiters">iters</a></b> configuration parameter.
+ instead of the characters specified with the <b>default_verp_delim</b>‐\b‐
+ <b>iters</b> configuration parameter.
- <b>-v</b> Send an email report of the first delivery attempt (Postfix ver-
- sions 2.1 and later). Mail delivery always happens in the back-
- ground. When multiple <b>-v</b> options are given, enable verbose log-
+ <b>-v</b> Send an email report of the first delivery attempt (Postfix ver‐
+ sions 2.1 and later). Mail delivery always happens in the back‐
+ ground. When multiple <b>-v</b> options are given, enable verbose log‐
ging for debugging purposes.
<b>-X</b> <i>log</i><b>_</b><i>file</i> (ignored)
no <b>From:</b> message header. See also the <b>-F</b> option above.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
- gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
- <a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro‐
+ gram. The text below provides only a parameter summary. See <b>post</b>‐\b‐
+ <b>conf</b>(5) for more details including examples.
<b>COMPATIBILITY CONTROLS</b>
Available with Postfix 2.9 and later:
List of users who are authorized to view the queue.
<b><a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
- List of users who are authorized to submit mail with the <a href="sendmail.1.html"><b>send-</b></a>
- <a href="sendmail.1.html"><b>mail</b>(1)</a> command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com-
+ List of users who are authorized to submit mail with the <b>send</b>‐\b‐
+ <b>mail</b>(1) command (and with the privileged <a href="postdrop.1.html"><b>postdrop</b>(1)</a> helper com‐
mand).
<b>RESOURCE AND RATE CONTROLS</b>
the Postfix "fast flush" service.
<b><a href="postconf.5.html#fast_flush_domains">fast_flush_domains</a> ($<a href="postconf.5.html#relay_domains">relay_domains</a>)</b>
- Optional list of destinations that are eligible for per-destina-
+ Optional list of destinations that are eligible for per-destina‐
tion logfiles with mail that is queued to those destinations.
<b>VERP CONTROLS</b>
The location of all postfix administrative commands.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_directory">daemon_directory</a> (see 'postconf -d' output)</b>
The time after which the sender receives a copy of the message
headers of mail that is still queued.
- <b><a href="postconf.5.html#enable_errors_to">enable_errors_to</a> (no)</b>
- Report mail delivery errors to the address specified with the
- non-standard Errors-To: message header, instead of the envelope
- sender address (this feature is removed with Postfix version
- 2.2, is turned off by default with Postfix version 2.1, and is
- always turned on with older Postfix versions).
-
<b><a href="postconf.5.html#mail_owner">mail_owner</a> (postfix)</b>
The UNIX system account that owns the Postfix queue and most
Postfix daemon processes.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>FILES</b>
<b>DESCRIPTION</b>
The Postfix SMTP+LMTP client implements the SMTP and LMTP mail delivery
- protocols. It processes message delivery requests from the queue man-
+ protocols. It processes message delivery requests from the queue man‐
ager. Each request specifies a queue file, a sender address, a domain
or host to deliver to, and recipient information. This program expects
to be run from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
<i>domainname</i>
<i>domainname</i>:<i>port</i>
- Look up the mail exchangers for the specified domain, and con-
+ Look up the mail exchangers for the specified domain, and con‐
nect to the specified port (default: <b>smtp</b>).
[<i>hostname</i>]
[<i>address</i>]:<i>port</i>
Connect to the host at the specified address, and connect to the
- specified port (default: <b>smtp</b>). An IPv6 address must be format-
+ specified port (default: <b>smtp</b>). An IPv6 address must be format‐
ted as [<b>ipv6</b>:<i>address</i>].
<b>LMTP DESTINATION SYNTAX</b>
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
<a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a> (SMTP protocol)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Corrupted message
files are marked so that the queue manager can move them to the <b>corrupt</b>
queue for further inspection.
- Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas-
+ Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas‐
ter is notified of bounces, protocol problems, and of other trouble.
<b>BUGS</b>
there is no support for TLS, and connections are cached in-process,
making it ineffective when the client is used for multiple domains.
- Most smtp_<i>xxx</i> configuration parameters have an lmtp_<i>xxx</i> "mirror" param-
+ Most smtp_<i>xxx</i> configuration parameters have an lmtp_<i>xxx</i> "mirror" param‐
eter for the equivalent LMTP feature. This document describes only
those LMTP-related parameters that aren't simply "mirror" parameters.
<b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
When authenticating to a remote SMTP or LMTP server with the
default setting "no", send no SASL authoriZation ID (authzid);
- send only the SASL authentiCation ID (authcid) plus the auth-
+ send only the SASL authentiCation ID (authcid) plus the auth‐
cid's password.
Available in Postfix version 2.5 and later:
Available in Postfix version 2.6 and later:
<b><a href="postconf.5.html#tcp_windowsize">tcp_windowsize</a> (0)</b>
- An optional workaround for routers that break TCP window scal-
+ An optional workaround for routers that break TCP window scal‐
ing.
Available in Postfix version 2.8 and later:
Change the behavior of the smtp_*_timeout time limits, from a
time limit per read or write system call, to a time limit to
send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes-
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
<b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
<b><a href="postconf.5.html#smtp_delivery_status_filter">smtp_delivery_status_filter</a> ($<a href="postconf.5.html#default_delivery_status_filter">default_delivery_status_filter</a>)</b>
Optional filter for the <a href="smtp.8.html"><b>smtp</b>(8)</a> delivery agent to change the
- delivery status code or explanatory text of successful or unsuc-
+ delivery status code or explanatory text of successful or unsuc‐
cessful deliveries.
<b>MIME PROCESSING CONTROLS</b>
Enable SASL authentication in the Postfix SMTP client.
<b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
- Optional Postfix SMTP client lookup tables with one user-
+ Optional Postfix SMTP client lookup tables with one user‐
name:password entry per remote hostname or domain, or sender
address when sender-dependent authentication is enabled.
<b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
Postfix SMTP client SASL security options; as of Postfix 2.3 the
- list of available features depends on the SASL client implemen-
+ list of available features depends on the SASL client implemen‐
tation that is selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
Enable sender-dependent authentication in the Postfix SMTP
client; this is available only with SASL authentication, and
- disables SMTP connection caching to ensure that mail from dif-
+ disables SMTP connection caching to ensure that mail from dif‐
ferent senders will use the appropriate credentials.
<b><a href="postconf.5.html#smtp_sasl_path">smtp_sasl_path</a> (empty)</b>
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
- An optional table to prevent repeated SASL authentication fail-
+ An optional table to prevent repeated SASL authentication fail‐
ures with the same remote SMTP server hostname, username and
password.
<b><a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> (empty)</b>
A file containing CA certificates of root CAs trusted to sign
- either remote SMTP server certificates or intermediate CA cer-
+ either remote SMTP server certificates or intermediate CA cer‐
tificates.
<b><a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a> (empty)</b>
<b><a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> (empty)</b>
Additional list of ciphers or cipher types to exclude from the
- Postfix SMTP client cipher list at mandatory TLS security lev-
+ Postfix SMTP client cipher list at mandatory TLS security lev‐
els.
<b><a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a> (empty)</b>
<b><a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> (empty)</b>
Optional lookup tables with the Postfix SMTP client TLS security
- policy by next-hop destination; when a non-empty value is speci-
+ policy by next-hop destination; when a non-empty value is speci‐
fied, this overrides the obsolete <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> parameter.
<b><a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> (!SSLv2)</b>
Available in Postfix version 2.4 and later:
- <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a> ($<a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_secu</a>-</b>
- <b><a href="postconf.5.html#smtp_sasl_tls_security_options">rity_options</a>)</b>
+ <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a> ($smtp_sasl_tls_secu</b>‐\b‐
+ <b>rity_options)</b>
The SASL authentication security options that the Postfix SMTP
client uses for TLS encrypted SMTP sessions with a verified
server certificate.
<b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a> (empty)</b>
List of acceptable remote SMTP server certificate fingerprints
- for the "fingerprint" TLS security level (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
- <b><a href="postconf.5.html#smtp_tls_security_level">rity_level</a></b> = fingerprint).
+ for the "fingerprint" TLS security level (<b>smtp_tls_secu</b>‐\b‐
+ <b>rity_level</b> = fingerprint).
<b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (md5)</b>
The message digest algorithm used to construct remote SMTP
use with opportunistic TLS encryption.
<b><a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a> (empty)</b>
- File with the Postfix SMTP client ECDSA certificate in PEM for-
+ File with the Postfix SMTP client ECDSA certificate in PEM for‐
mat.
<b><a href="postconf.5.html#smtp_tls_eckey_file">smtp_tls_eckey_file</a> ($<a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a>)</b>
- File with the Postfix SMTP client ECDSA private key in PEM for-
+ File with the Postfix SMTP client ECDSA private key in PEM for‐
mat.
Available in Postfix version 2.7 and later:
<b><a href="postconf.5.html#smtp_tls_block_early_mail_reply">smtp_tls_block_early_mail_reply</a> (no)</b>
Try to detect a mail hijacking attack based on a TLS protocol
- vulnerability (CVE-2009-3555), where an attacker prepends mali-
+ vulnerability (CVE-2009-3555), where an attacker prepends mali‐
cious HELO, MAIL, RCPT, DATA commands to a Postfix SMTP client
TLS session.
<b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
Optional lookup tables with the Postfix SMTP client TLS usage
- policy by next-hop destination and by remote SMTP server host-
+ policy by next-hop destination and by remote SMTP server host‐
name.
<b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
cipher list.
<b>RESOURCE AND RATE CONTROLS</b>
- <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
- <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
- The maximal number of parallel deliveries to the same destina-
+ <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($default_destination_concur</b>‐\b‐
+ <b>rency_limit)</b>
+ The maximal number of parallel deliveries to the same destina‐
tion via the smtp message delivery transport.
<b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
- The maximal number of recipients per message for the smtp mes-
+ The maximal number of recipients per message for the smtp mes‐
sage delivery transport.
<b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
- The Postfix SMTP client time limit for completing a TCP connec-
+ The Postfix SMTP client time limit for completing a TCP connec‐
tion, or zero (use the operating system built-in time limit).
<b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
and for receiving the initial remote LMTP server response.
<b><a href="postconf.5.html#smtp_xforward_timeout">smtp_xforward_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the XFORWARD com-
+ The Postfix SMTP client time limit for sending the XFORWARD com‐
mand, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
<b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
- The amount of time during which Postfix will use an SMTP connec-
+ The amount of time during which Postfix will use an SMTP connec‐
tion repeatedly.
<b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
- Time limit for connection cache connect, send or receive opera-
+ Time limit for connection cache connect, send or receive opera‐
tions.
Available in Postfix version 2.9 and later:
Change the behavior of the smtp_*_timeout time limits, from a
time limit per read or write system call, to a time limit to
send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes-
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
Available in Postfix version 2.11 and later:
that an SMTP session may be reused before it is closed, or zero
(no limit).
+<b>SMTPUTF8 CONTROLS</b>
+ Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ Enable experimental SMTPUTF8 support for the protocols described
+ in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Enable SMTPUTF8 autodetection for the specified mail origin
+ classes.
+
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
The increment in verbose logging level when a remote client or
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
The recipient of postmaster notifications about mail delivery
- problems that are caused by policy, resource, software or proto-
+ problems that are caused by policy, resource, software or proto‐
col errors.
<b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
detects a "mail loops back to myself" error condition.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log-
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
<b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
When a remote LMTP server announces no DSN support, assume that
- the server performs final delivery, and send "delivered" deliv-
+ the server performs final delivery, and send "delivered" deliv‐
ery status notifications instead of "relayed".
<b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available with Postfix 2.2 and earlier:
The SMTP server accepts network connection requests and performs zero
or more SMTP transactions per connection. Each received message is
piped through the <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon, and is placed into the <b>incoming</b>
- queue as one single queue file. For this mode of operation, the pro-
+ queue as one single queue file. For this mode of operation, the pro‐
gram expects to be run from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
Alternatively, the SMTP server be can run in stand-alone mode; this is
The SMTP server implements a variety of policies for connection
requests, and for parameters given to <b>HELO, ETRN, MAIL FROM, VRFY</b> and
- <b>RCPT TO</b> commands. They are detailed below and in the <a href="postconf.5.html"><b>main.cf</b></a> configura-
+ <b>RCPT TO</b> commands. They are detailed below and in the <a href="postconf.5.html"><b>main.cf</b></a> configura‐
tion file.
<b>SECURITY</b>
<a href="http://tools.ietf.org/html/rfc4409">RFC 4409</a> (Message submission)
<a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a> (SMTP protocol)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
- Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas-
+ Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter, the postmas‐
ter is notified of bounces, protocol problems, policy violations, and
of other trouble.
<b><a href="postconf.5.html#smtpd_tls_always_issue_session_ids">smtpd_tls_always_issue_session_ids</a> (yes)</b>
Force the Postfix SMTP server to issue a TLS session id, even
- when TLS session caching is turned off (<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_ses</a>-
- <a href="postconf.5.html#smtpd_tls_session_cache_database">sion_cache_database</a> is empty).
+ when TLS session caching is turned off (smtpd_tls_ses‐
+ sion_cache_database is empty).
Available in Postfix version 2.6 and later:
<b><a href="postconf.5.html#tcp_windowsize">tcp_windowsize</a> (0)</b>
- An optional workaround for routers that break TCP window scal-
+ An optional workaround for routers that break TCP window scal‐
ing.
Available in Postfix version 2.7 and later:
Available in Postfix version 2.9 and later:
<b><a href="postconf.5.html#smtpd_per_record_deadline">smtpd_per_record_deadline</a> (normal: no, overload: yes)</b>
- Change the behavior of the <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> and <a href="postconf.5.html#smtpd_starttls_timeout">smtpd_start</a>-
- <a href="postconf.5.html#smtpd_starttls_timeout">tls_timeout</a> time limits, from a time limit per read or write
+ Change the behavior of the <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> and smtpd_start‐
+ tls_timeout time limits, from a time limit per read or write
system call, to a time limit to send or receive a complete
record (an SMTP command line, SMTP response line, SMTP message
content line, or TLS protocol message).
Postfix address rewriting.
<b><a href="postconf.5.html#receive_override_options">receive_override_options</a> (empty)</b>
- Enable or disable recipient validation, built-in content filter-
+ Enable or disable recipient validation, built-in content filter‐
ing, or address mapping.
Available in Postfix version 2.2 and later:
update incomplete addresses with the domain name in $<a href="postconf.5.html#myorigin">myorigin</a> or
$<a href="postconf.5.html#mydomain">mydomain</a>; either don't rewrite message headers from other
clients at all, or rewrite message headers and update incomplete
- addresses with the domain specified in the <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_re</a>-
- <a href="postconf.5.html#remote_header_rewrite_domain">write_domain</a> parameter.
+ addresses with the domain specified in the remote_header_re‐
+ write_domain parameter.
<b>BEFORE-SMTPD PROXY AGENT</b>
Available in Postfix version 2.10 and later:
<b>AFTER QUEUE EXTERNAL CONTENT INSPECTION CONTROLS</b>
As of version 1.0, Postfix can be configured to send new mail to an
external content filter AFTER the mail is queued. This content filter
- is expected to inject mail back into a (Postfix or other) MTA for fur-
+ is expected to inject mail back into a (Postfix or other) MTA for fur‐
ther delivery. See the <a href="FILTER_README.html">FILTER_README</a> document for details.
<b><a href="postconf.5.html#content_filter">content_filter</a> (empty)</b>
<b>BEFORE QUEUE EXTERNAL CONTENT INSPECTION CONTROLS</b>
As of version 2.1, the Postfix SMTP server can be configured to send
incoming mail to a real-time SMTP-based content filter BEFORE mail is
- queued. This content filter is expected to inject mail back into Post-
- fix. See the <a href="SMTPD_PROXY_README.html">SMTPD_PROXY_README</a> document for details on how to config-
+ queued. This content filter is expected to inject mail back into Post‐
+ fix. See the <a href="SMTPD_PROXY_README.html">SMTPD_PROXY_README</a> document for details on how to config‐
ure and operate this feature.
<b><a href="postconf.5.html#smtpd_proxy_filter">smtpd_proxy_filter</a> (empty)</b>
The hostname and TCP port of the mail filtering proxy server.
<b><a href="postconf.5.html#smtpd_proxy_ehlo">smtpd_proxy_ehlo</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
- How the Postfix SMTP server announces itself to the proxy fil-
+ How the Postfix SMTP server announces itself to the proxy fil‐
ter.
<b><a href="postconf.5.html#smtpd_proxy_options">smtpd_proxy_options</a> (empty)</b>
- List of options that control how the Postfix SMTP server commu-
+ List of options that control how the Postfix SMTP server commu‐
nicates with a before-queue content filter.
<b><a href="postconf.5.html#smtpd_proxy_timeout">smtpd_proxy_timeout</a> (100s)</b>
As of version 2.3, Postfix supports the Sendmail version 8 Milter (mail
filter) protocol. These content filters run outside Postfix. They can
inspect the SMTP command stream and the message content, and can
- request modifications before mail is queued. For details see the <a href="MILTER_README.html">MIL</a>-
- <a href="MILTER_README.html">TER_README</a> document.
+ request modifications before mail is queued. For details see the MIL‐
+ <a href="TER_README.html">TER_README</a> document.
<b><a href="postconf.5.html#smtpd_milters">smtpd_milters</a> (empty)</b>
A list of Milter (mail filter) applications for new mail that
arrives via the Postfix <a href="smtpd.8.html"><b>smtpd</b>(8)</a> server.
<b><a href="postconf.5.html#milter_protocol">milter_protocol</a> (6)</b>
- The mail filter protocol version and optional protocol exten-
+ The mail filter protocol version and optional protocol exten‐
sions for communication with a Milter application; prior to
Postfix 2.6 the default protocol is 2.
unavailable or mis-configured.
<b><a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
- The {daemon_name} macro value for Milter (mail filter) applica-
+ The {daemon_name} macro value for Milter (mail filter) applica‐
tions.
<b><a href="postconf.5.html#milter_macro_v">milter_macro_v</a> ($<a href="postconf.5.html#mail_name">mail_name</a> $<a href="postconf.5.html#mail_version">mail_version</a>)</b>
The {v} macro value for Milter (mail filter) applications.
<b><a href="postconf.5.html#milter_connect_timeout">milter_connect_timeout</a> (30s)</b>
- The time limit for connecting to a Milter (mail filter) applica-
+ The time limit for connecting to a Milter (mail filter) applica‐
tion, and for negotiating protocol options.
<b><a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> (30s)</b>
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#receive_override_options">receive_override_options</a> (empty)</b>
- Enable or disable recipient validation, built-in content filter-
+ Enable or disable recipient validation, built-in content filter‐
ing, or address mapping.
<b>EXTERNAL CONTENT INSPECTION CONTROLS</b>
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtpd_authorized_xforward_hosts">smtpd_authorized_xforward_hosts</a> (empty)</b>
- What remote SMTP clients are allowed to use the XFORWARD fea-
+ What remote SMTP clients are allowed to use the XFORWARD fea‐
ture.
<b>SASL AUTHENTICATION CONTROLS</b>
<b><a href="postconf.5.html#smtpd_sasl_security_options">smtpd_sasl_security_options</a> (noanonymous)</b>
Postfix SMTP server SASL security options; as of Postfix 2.3 the
- list of available features depends on the SASL server implemen-
+ list of available features depends on the SASL server implemen‐
tation that is selected with <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b>.
<b><a href="postconf.5.html#smtpd_sender_login_maps">smtpd_sender_login_maps</a> (empty)</b>
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#cyrus_sasl_config_path">cyrus_sasl_config_path</a> (empty)</b>
- Search path for Cyrus SASL application configuration files, cur-
+ Search path for Cyrus SASL application configuration files, cur‐
rently used only to locate the $<a href="postconf.5.html#smtpd_sasl_path">smtpd_sasl_path</a>.conf file.
Available in Postfix version 2.11 and later:
<b><a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> (empty)</b>
The SMTP TLS security level for the Postfix SMTP server; when a
- non-empty value is specified, this overrides the obsolete param-
+ non-empty value is specified, this overrides the obsolete param‐
eters <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> and <a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>.
<b><a href="postconf.5.html#smtpd_sasl_tls_security_options">smtpd_sasl_tls_security_options</a> ($<a href="postconf.5.html#smtpd_sasl_security_options">smtpd_sasl_security_options</a>)</b>
<b><a href="postconf.5.html#smtpd_tls_CAfile">smtpd_tls_CAfile</a> (empty)</b>
A file containing (PEM format) CA certificates of root CAs
- trusted to sign either remote SMTP client certificates or inter-
+ trusted to sign either remote SMTP client certificates or inter‐
mediate CA certificates.
<b><a href="postconf.5.html#smtpd_tls_CApath">smtpd_tls_CApath</a> (empty)</b>
A directory containing (PEM format) CA certificates of root CAs
- trusted to sign either remote SMTP client certificates or inter-
+ trusted to sign either remote SMTP client certificates or inter‐
mediate CA certificates.
<b><a href="postconf.5.html#smtpd_tls_always_issue_session_ids">smtpd_tls_always_issue_session_ids</a> (yes)</b>
Force the Postfix SMTP server to issue a TLS session id, even
- when TLS session caching is turned off (<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_ses</a>-
- <a href="postconf.5.html#smtpd_tls_session_cache_database">sion_cache_database</a> is empty).
+ when TLS session caching is turned off (smtpd_tls_ses‐
+ sion_cache_database is empty).
<b><a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> (no)</b>
Ask a remote SMTP client for a client certificate.
<b><a href="postconf.5.html#smtpd_tls_auth_only">smtpd_tls_auth_only</a> (no)</b>
When TLS encryption is optional in the Postfix SMTP server, do
- not announce or accept SASL authentication over unencrypted con-
+ not announce or accept SASL authentication over unencrypted con‐
nections.
<b><a href="postconf.5.html#smtpd_tls_ccert_verifydepth">smtpd_tls_ccert_verifydepth</a> (9)</b>
<b><a href="postconf.5.html#smtpd_tls_mandatory_exclude_ciphers">smtpd_tls_mandatory_exclude_ciphers</a> (empty)</b>
Additional list of ciphers or cipher types to exclude from the
- Postfix SMTP server cipher list at mandatory TLS security lev-
+ Postfix SMTP server cipher list at mandatory TLS security lev‐
els.
<b><a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> (!SSLv2)</b>
use with opportunistic TLS encryption.
<b><a href="postconf.5.html#smtpd_tls_eccert_file">smtpd_tls_eccert_file</a> (empty)</b>
- File with the Postfix SMTP server ECDSA certificate in PEM for-
+ File with the Postfix SMTP server ECDSA certificate in PEM for‐
mat.
<b><a href="postconf.5.html#smtpd_tls_eckey_file">smtpd_tls_eckey_file</a> ($<a href="postconf.5.html#smtpd_tls_eccert_file">smtpd_tls_eccert_file</a>)</b>
- File with the Postfix SMTP server ECDSA private key in PEM for-
+ File with the Postfix SMTP server ECDSA private key in PEM for‐
mat.
<b><a href="postconf.5.html#smtpd_tls_eecdh_grade">smtpd_tls_eecdh_grade</a> (see 'postconf -d' output)</b>
Available in Postfix version 2.8 and later:
<b><a href="postconf.5.html#tls_preempt_cipherlist">tls_preempt_cipherlist</a> (no)</b>
- With SSLv3 and later, use the Postfix SMTP server's cipher pref-
+ With SSLv3 and later, use the Postfix SMTP server's cipher pref‐
erence order instead of the remote client's cipher preference
order.
Obsolete Postfix < 2.3 control for the Postfix SMTP server TLS
cipher list.
+<b>SMTPUTF8 CONTROLS</b>
+ Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ Enable experimental SMTPUTF8 support for the protocols described
+ in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
+
+ <b><a href="postconf.5.html#strict_smtputf8">strict_smtputf8</a> (no)</b>
+ Enable stricter enforcement of the SMTPUTF8 protocol.
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
+
<b>VERP SUPPORT CONTROLS</b>
- With VERP style delivery, each recipient of a message receives a cus-
+ With VERP style delivery, each recipient of a message receives a cus‐
tomized copy of the message with his/her own recipient address encoded
- in the envelope sender address. The <a href="VERP_README.html">VERP_README</a> file describes config-
+ in the envelope sender address. The <a href="VERP_README.html">VERP_README</a> file describes config‐
uration and operation details of Postfix support for variable envelope
return path addresses. VERP style delivery is requested with the SMTP
XVERP command or with the "sendmail -V" command-line option and is
Available in Postfix version 1.1 and 2.0:
<b><a href="postconf.5.html#authorized_verp_clients">authorized_verp_clients</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
- What remote SMTP clients are allowed to specify the XVERP com-
+ What remote SMTP clients are allowed to specify the XVERP com‐
mand.
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtpd_authorized_verp_clients">smtpd_authorized_verp_clients</a> ($<a href="postconf.5.html#authorized_verp_clients">authorized_verp_clients</a>)</b>
- What remote SMTP clients are allowed to specify the XVERP com-
+ What remote SMTP clients are allowed to specify the XVERP com‐
mand.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
The recipient of postmaster notifications about mail delivery
- problems that are caused by policy, resource, software or proto-
+ problems that are caused by policy, resource, software or proto‐
col errors.
<b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
<b>KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS</b>
As of Postfix version 2.0, the SMTP server rejects mail for unknown
- recipients. This prevents the mail queue from clogging up with undeliv-
+ recipients. This prevents the mail queue from clogging up with undeliv‐
erable MAILER-DAEMON messages. Additional information on this topic is
in the <a href="LOCAL_RECIPIENT_README.html">LOCAL_RECIPIENT_README</a> and <a href="ADDRESS_CLASS_README.html">ADDRESS_CLASS_README</a> documents.
<b><a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a> (<a href="proxymap.8.html">proxy</a>:unix:passwd.byname $<a href="postconf.5.html#alias_maps">alias_maps</a>)</b>
Lookup tables with all names or addresses of local recipients: a
- recipient address is local when its domain matches $<a href="postconf.5.html#mydestination">mydestina</a>-
- <a href="postconf.5.html#mydestination">tion</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or $<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
+ recipient address is local when its domain matches $mydestina‐
+ tion, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or $<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
<b><a href="postconf.5.html#unknown_local_recipient_reject_code">unknown_local_recipient_reject_code</a> (550)</b>
The numerical Postfix SMTP server response code when a recipient
<b><a href="postconf.5.html#unknown_relay_recipient_reject_code">unknown_relay_recipient_reject_code</a> (550)</b>
The numerical Postfix SMTP server reply code when a recipient
- address matches $<a href="postconf.5.html#relay_domains">relay_domains</a>, and <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> speci-
+ address matches $<a href="postconf.5.html#relay_domains">relay_domains</a>, and <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> speci‐
fies a list of lookup tables that does not match the recipient
address.
<b><a href="postconf.5.html#unknown_virtual_alias_reject_code">unknown_virtual_alias_reject_code</a> (550)</b>
The Postfix SMTP server reply code when a recipient address
- matches $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>, and $<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> speci-
+ matches $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>, and $<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> speci‐
fies a list of lookup tables that does not match the recipient
address.
<b><a href="postconf.5.html#unknown_virtual_mailbox_reject_code">unknown_virtual_mailbox_reject_code</a> (550)</b>
The Postfix SMTP server reply code when a recipient address
matches $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>, and $<a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a>
- specifies a list of lookup tables that does not match the recip-
+ specifies a list of lookup tables that does not match the recip‐
ient address.
<b>RESOURCE AND RATE CONTROLS</b>
this length; upon delivery, long lines are reconstructed.
<b><a href="postconf.5.html#queue_minfree">queue_minfree</a> (0)</b>
- The minimal amount of free space in bytes in the queue file sys-
+ The minimal amount of free space in bytes in the queue file sys‐
tem that is needed to receive mail.
<b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
Attempt to look up the remote SMTP client hostname, and verify
that the name matches the client IP address.
- The per SMTP client connection count and request rate limits are imple-
+ The per SMTP client connection count and request rate limits are imple‐
mented in co-operation with the <a href="anvil.8.html"><b>anvil</b>(8)</a> service, and are available in
Postfix version 2.2 and later.
Available in Postfix version 2.9 and later:
<b><a href="postconf.5.html#smtpd_per_record_deadline">smtpd_per_record_deadline</a> (normal: no, overload: yes)</b>
- Change the behavior of the <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> and <a href="postconf.5.html#smtpd_starttls_timeout">smtpd_start</a>-
- <a href="postconf.5.html#smtpd_starttls_timeout">tls_timeout</a> time limits, from a time limit per read or write
+ Change the behavior of the <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> and smtpd_start‐
+ tls_timeout time limits, from a time limit per read or write
system call, to a time limit to send or receive a complete
record (an SMTP command line, SMTP response line, SMTP message
content line, or TLS protocol message).
The default action when an SMTPD policy service request fails.
<b><a href="postconf.5.html#smtpd_policy_service_request_limit">smtpd_policy_service_request_limit</a> (0)</b>
- The maximal number of requests per SMTPD policy service connec-
+ The maximal number of requests per SMTPD policy service connec‐
tion, or zero (no limit).
<b><a href="postconf.5.html#smtpd_policy_service_try_limit">smtpd_policy_service_try_limit</a> (2)</b>
request before giving up.
<b><a href="postconf.5.html#smtpd_policy_service_retry_delay">smtpd_policy_service_retry_delay</a> (1s)</b>
- The delay between attempts to resend a failed SMTPD policy ser-
+ The delay between attempts to resend a failed SMTPD policy ser‐
vice request.
<b>ACCESS CONTROLS</b>
$<a href="postconf.5.html#smtpd_helo_restrictions">smtpd_helo_restrictions</a>.
<b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf -d' output)</b>
- What Postfix features match subdomains of "domain.tld" automati-
+ What Postfix features match subdomains of "domain.tld" automati‐
cally, instead of requiring an explicit ".domain.tld" pattern.
<b><a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> (empty)</b>
<b><a href="postconf.5.html#allow_untrusted_routing">allow_untrusted_routing</a> (no)</b>
Forward mail with sender-specified routing
- (user[@%!]remote[@%!]site) from untrusted clients to destina-
+ (user[@%!]remote[@%!]site) from untrusted clients to destina‐
tions matching $<a href="postconf.5.html#relay_domains">relay_domains</a>.
<b><a href="postconf.5.html#smtpd_restriction_classes">smtpd_restriction_classes</a> (empty)</b>
<a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a>.
<b>SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS</b>
- Postfix version 2.1 introduces sender and recipient address verifica-
+ Postfix version 2.1 introduces sender and recipient address verifica‐
tion. This feature is implemented by sending probe email messages that
are not actually delivered. This feature is requested via the
<a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a> and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> access
restrictions. The status of verification probes is maintained by the
- <a href="verify.8.html"><b>verify</b>(8)</a> server. See the file <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VERIFICATION_README</a> for infor-
+ <a href="verify.8.html"><b>verify</b>(8)</a> server. See the file <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VERIFICATION_README</a> for infor‐
mation about how to configure and operate the Postfix sender/recipient
address verification service.
of an address verification request in progress.
<b><a href="postconf.5.html#address_verify_poll_delay">address_verify_poll_delay</a> (3s)</b>
- The delay between queries for the completion of an address veri-
+ The delay between queries for the completion of an address veri‐
fication request in progress.
<b><a href="postconf.5.html#address_verify_sender">address_verify_sender</a> ($<a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a>)</b>
<b><a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> (450)</b>
The numerical Postfix SMTP server response when a recipient
- address is rejected by the <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> restric-
+ address is rejected by the <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> restric‐
tion.
Available in Postfix version 2.6 and later:
fails due to a temporary error condition.
<b><a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
- The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipi</a>-
- <a href="postconf.5.html#reject_unverified_recipient">ent</a> fails due to a temporary error condition.
+ The Postfix SMTP server's action when reject_unverified_recipi‐
+ ent fails due to a temporary error condition.
Available with Postfix 2.9 and later:
<a href="postconf.5.html#reject_unknown_client_hostname">reject_unknown_client_hostname</a> restriction.
<b><a href="postconf.5.html#unknown_hostname_reject_code">unknown_hostname_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code when the host-
+ The numerical Postfix SMTP server response code when the host‐
name specified with the HELO or EHLO command is rejected by the
<a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> restriction.
<b><a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a> (550)</b>
The numerical Postfix SMTP server response code when a remote
- SMTP client request is blocked by the <a href="postconf.5.html#reject_multi_recipient_bounce">reject_multi_recipi</a>-
- <a href="postconf.5.html#reject_multi_recipient_bounce">ent_bounce</a> restriction.
+ SMTP client request is blocked by the reject_multi_recipi‐
+ ent_bounce restriction.
<b><a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> (empty)</b>
Optional lookup tables with RBL response templates.
fails due to a temporary error condition.
<b><a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
- The Postfix SMTP server's action when <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_host</a>-
- <a href="postconf.5.html#reject_unknown_helo_hostname">name</a> fails due to an temporary error condition.
+ The Postfix SMTP server's action when reject_unknown_helo_host‐
+ name fails due to an temporary error condition.
<b><a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
The Postfix SMTP server's action when
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
The location of all postfix administrative commands.
<b><a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a> (double-bounce)</b>
- The sender address of postmaster notifications that are gener-
+ The sender address of postmaster notifications that are gener‐
ated by the mail system.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
The internet hostname of this mail system.
<b><a href="postconf.5.html#mynetworks">mynetworks</a> (see 'postconf -d' output)</b>
- The list of "trusted" remote SMTP clients that have more privi-
+ The list of "trusted" remote SMTP clients that have more privi‐
leges than "strangers".
<b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT, GET, POST)</b>
- List of commands that cause the Postfix SMTP server to immedi-
+ List of commands that cause the Postfix SMTP server to immedi‐
ately terminate the session with a 221 code.
Available in Postfix version 2.5 and later:
<b>bounce</b> [generic Postfix daemon options]
<b>DESCRIPTION</b>
- The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta-
+ The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon maintains per-message log files with delivery sta‐
tus information. Each log file is named after the queue file that it
corresponds to, and is kept in a queue subdirectory named after the
service name in the <a href="master.5.html"><b>master.cf</b></a> file (either <b>bounce</b>, <b>defer</b> or <b>trace</b>).
The <a href="bounce.8.html"><b>bounce</b>(8)</a> daemon processes two types of service requests:
- <b>o</b> Append a recipient (non-)delivery status record to a per-message
+ · Append a recipient (non-)delivery status record to a per-message
log file.
- <b>o</b> Enqueue a delivery status notification message, with a copy of a
+ · Enqueue a delivery status notification message, with a copy of a
per-message log file and of the corresponding message. When the
delivery status notification message is enqueued successfully,
the per-message log file is deleted.
- The software does a best notification effort. A non-delivery notifica-
+ The software does a best notification effort. A non-delivery notifica‐
tion is sent even when the log file or the original message cannot be
read.
<a href="http://tools.ietf.org/html/rfc3464">RFC 3464</a> (Delivery Status Notifications)
<a href="http://tools.ietf.org/html/rfc3834">RFC 3834</a> (Auto-Submitted: message header)
<a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> (Internet Message Format)
+ <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a> (Internationalized SMTP)
+ <a href="http://tools.ietf.org/html/rfc6532">RFC 6532</a> (Internationalized Message Format)
+ <a href="http://tools.ietf.org/html/rfc6533">RFC 6533</a> (Internationalized Delivery Status Notifications)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
Postfix versions before 2.0.
<b><a href="postconf.5.html#bounce_notice_recipient">bounce_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
- ers of mail that Postfix did not deliver and of SMTP conversa-
+ The recipient of postmaster notifications with the message head‐
+ ers of mail that Postfix did not deliver and of SMTP conversa‐
tion transcripts of mail that Postfix did not receive.
<b><a href="postconf.5.html#bounce_size_limit">bounce_size_limit</a> (50000)</b>
Pathname of a configuration file with bounce message templates.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_notice_recipient">delay_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications with the message head-
+ The recipient of postmaster notifications with the message head‐
ers of mail that cannot be delivered within $<a href="postconf.5.html#delay_warning_time">delay_warning_time</a>
time units.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
+ Available in Postfix 2.12 and later:
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
principle.
<b>CONFIGURATION PARAMETERS</b>
- Changes to <a href="postconf.5.html"><b>main.cf</b></a> are not picked up automatically, as <a href="verify.8.html"><b>verify</b>(8)</a> pro-
- cesses are long-lived. Use the command "<b>postfix reload</b>" after a config-
+ Changes to <a href="postconf.5.html"><b>main.cf</b></a> are not picked up automatically, as <a href="verify.8.html"><b>verify</b>(8)</a> pro‐
+ cesses are long-lived. Use the command "<b>postfix reload</b>" after a config‐
uration change.
The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
Available with Postfix 2.7 and later:
<b><a href="postconf.5.html#address_verify_cache_cleanup_interval">address_verify_cache_cleanup_interval</a> (12h)</b>
- The amount of time between <a href="verify.8.html"><b>verify</b>(8)</a> address verification data-
+ The amount of time between <a href="verify.8.html"><b>verify</b>(8)</a> address verification data‐
base cleanup runs.
<b>PROBE MESSAGE ROUTING CONTROLS</b>
message routing mechanisms.
<b><a href="postconf.5.html#address_verify_relayhost">address_verify_relayhost</a> ($<a href="postconf.5.html#relayhost">relayhost</a>)</b>
- Overrides the <a href="postconf.5.html#relayhost">relayhost</a> parameter setting for address verifica-
+ Overrides the <a href="postconf.5.html#relayhost">relayhost</a> parameter setting for address verifica‐
tion probes.
<b><a href="postconf.5.html#address_verify_transport_maps">address_verify_transport_maps</a> ($<a href="postconf.5.html#transport_maps">transport_maps</a>)</b>
- Overrides the <a href="postconf.5.html#transport_maps">transport_maps</a> parameter setting for address veri-
+ Overrides the <a href="postconf.5.html#transport_maps">transport_maps</a> parameter setting for address veri‐
fication probes.
<b><a href="postconf.5.html#address_verify_local_transport">address_verify_local_transport</a> ($<a href="postconf.5.html#local_transport">local_transport</a>)</b>
- Overrides the <a href="postconf.5.html#local_transport">local_transport</a> parameter setting for address ver-
+ Overrides the <a href="postconf.5.html#local_transport">local_transport</a> parameter setting for address ver‐
ification probes.
<b><a href="postconf.5.html#address_verify_virtual_transport">address_verify_virtual_transport</a> ($<a href="postconf.5.html#virtual_transport">virtual_transport</a>)</b>
verification probes.
<b><a href="postconf.5.html#address_verify_relay_transport">address_verify_relay_transport</a> ($<a href="postconf.5.html#relay_transport">relay_transport</a>)</b>
- Overrides the <a href="postconf.5.html#relay_transport">relay_transport</a> parameter setting for address ver-
+ Overrides the <a href="postconf.5.html#relay_transport">relay_transport</a> parameter setting for address ver‐
ification probes.
<b><a href="postconf.5.html#address_verify_default_transport">address_verify_default_transport</a> ($<a href="postconf.5.html#default_transport">default_transport</a>)</b>
Available in Postfix 2.3 and later:
- <b><a href="postconf.5.html#address_verify_sender_dependent_relayhost_maps">address_verify_sender_dependent_relayhost_maps</a> ($<a href="postconf.5.html#sender_dependent_relayhost_maps">sender_depen</a>-</b>
- <b><a href="postconf.5.html#sender_dependent_relayhost_maps">dent_relayhost_maps</a>)</b>
+ <b><a href="postconf.5.html#address_verify_sender_dependent_relayhost_maps">address_verify_sender_dependent_relayhost_maps</a> ($sender_depen</b>‐\b‐
+ <b>dent_relayhost_maps)</b>
Overrides the <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> parameter setting
for address verification probes.
Available in Postfix 2.7 and later:
- <b><a href="postconf.5.html#address_verify_sender_dependent_default_transport_maps">address_verify_sender_dependent_default_transport_maps</a> ($<a href="postconf.5.html#sender_dependent_default_transport_maps">sender_depen</a>-</b>
- <b><a href="postconf.5.html#sender_dependent_default_transport_maps">dent_default_transport_maps</a>)</b>
+ <b><a href="postconf.5.html#address_verify_sender_dependent_default_transport_maps">address_verify_sender_dependent_default_transport_maps</a> ($sender_depen</b>‐\b‐
+ <b>dent_default_transport_maps)</b>
Overrides the <a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a> parameter
setting for address verification probes.
+<b>SMTPUTF8 CONTROLS</b>
+ Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+
+ <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
+ Enable SMTPUTF8 autodetection for the specified mail origin
+ classes.
+
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con‐
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to handle a
+ How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
- The time limit for sending or receiving information over an
+ The time limit for sending or receiving information over an
internal communication channel.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
<b>SEE ALSO</b>
# Do not build with Linux EPOLL support.
# By default, EPOLL support is compiled in on platforms that
# are known to support it.
+# .IP \fB-DNO_EAI\fR
+# Do not build with EAI (SMTPUTF8) support.
# .IP \fB-DNO_IPV6\fR
# Do not build with IPv6 support.
# By default, IPv6 support is compiled in on platforms that
: ${SHLIB_SUFFIX=.so}
: ${SHLIB_CFLAGS=-fPIC}
: ${SHLIB_LD='gcc -shared -Wl,-soname,${LIB}'}
- : ${SHLIB_RPATH='-Wl,-rpath,${SHLIB_DIR}'}
+ : ${SHLIB_RPATH='-Wl,--enable-new-dtags -Wl,-rpath,${SHLIB_DIR}'}
: ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
: ${PLUGIN_LD='gcc -shared'}
;;
: ${SHLIB_SUFFIX=.so}
: ${SHLIB_CFLAGS=-fPIC}
: ${SHLIB_LD='gcc -shared -Wl,-soname,${LIB}'}
- : ${SHLIB_RPATH='-Wl,-rpath,${SHLIB_DIR}'}
+ : ${SHLIB_RPATH='-Wl,--enable-new-dtags -Wl,-rpath,${SHLIB_DIR}'}
: ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
: ${PLUGIN_LD='gcc -shared'}
;;
rm -f makedefs.test makedefs.test.[co]
esac
+#
+# Look for ICU and enable unicode email if available. This tests
+# a different function that Postfix uses in order to avoid having UTF8
+# in this file. The two functions use the same data structures, so they
+# should be equivalent for testing purposes.
+#
+case "$CCARGS" in
+ *-DNO_EAI*) ;;
+ *) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
+ cat >makedefs.test.c <<'EOF'
+#include <unicode/uidna.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ char buf[1024];
+ UErrorCode error = U_ZERO_ERROR;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UIDNA *idna = uidna_openUTS46(UIDNA_DEFAULT, &error);
+
+ exit(uidna_labelToUnicodeUTF8(idna,
+ "xn--lgbbat1ad8j", /* an arabic TLD */
+ 15,
+ buf,
+ sizeof(buf),
+ &info,
+ &error) != 14);
+}
+EOF
+ ${CC-gcc} -o makedefs.test makedefs.test.c -I/usr/local/include \
+ -L/usr/local/lib -licuuc >/dev/null 2>&1
+ if ./makedefs.test 2>/dev/null ; then
+ SYSLIBS="$SYSLIBS -L/usr/local/lib -licuuc"
+ else
+ CCARGS="$CCARGS -DNO_EAI"
+ fi
+ rm -f makedefs.test makedefs.test.[co]
+esac
+
#
# OpenSSL has no configuration query utility, but we don't try to
# guess. We assume includes in /usr/include/openssl and libraries in
.IP "\fBdelay_warning_time (0h)\fR"
The time after which the sender receives a copy of the message
headers of mail that is still queued.
-.IP "\fBenable_errors_to (no)\fR"
-Report mail delivery errors to the address specified with the
-non-standard Errors-To: message header, instead of the envelope
-sender address (this feature is removed with Postfix version 2.2, is
-turned off by default with Postfix version 2.1, and is always turned on
-with older Postfix versions).
.IP "\fBmail_owner (postfix)\fR"
The UNIX system account that owns the Postfix queue and most Postfix
daemon processes.
.PP
This feature is available in Postfix 2.2 and later. With
Postfix 2.3 and later use smtpd_tls_security_level instead.
+.SH smtputf8_autodetect_classes (default: sendmail, verify)
+Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes. This is a workaround to avoid chicken-and-egg
+problems during the initial SMTPUTF8 roll-out in environments with
+pre-existing mail flows that contain UTF8. Those mail flows should
+not break because Postfix suddenly refuses to deliver such mail
+to down-stream MTAs that don't announce SMTPUTF8 support.
+.PP
+The problem is that Postfix cannot rely solely on the sender's
+declaration that a message requires SMTPUTF8 support, because UTF8
+may be introduced during local processing (for example, the client
+hostname in Postfix's Received: header, adding @$myorigin or
+\&.$mydomain to an incomplete address, address rewriting, alias
+expansion, automatic BCC recipients, local forwarding, and changes
+made by header checks or Milter applications).
+.PP
+For now, the default is to enable "SMTPUTF8 required" autodetection
+only for Postfix sendmail command-line submissions and address
+verification probes. This may change once SMTPUTF8 support achieves
+world domination. However, sites that add UTF8 content via local
+processing (see above) should autodetect the need for SMTPUTF8
+support for all email.
+.PP
+Specify one or more of the following:
+.IP "\fB sendmail \fR"
+Submission with the Postfix
+\fBsendmail\fR(1) command.
+.br
+.IP "\fB smtpd \fR"
+Mail received with the \fBsmtpd\fR(8)
+daemon.
+.br
+.IP "\fB qmqpd \fR"
+Mail received with the \fBqmqpd\fR(8)
+daemon.
+.br
+.IP "\fB forward \fR"
+Local forwarding or aliasing.
+.br
+.IP "\fB bounce \fR"
+Submission by the \fBbounce\fR(8) daemon.
+.br
+.IP "\fB notify \fR"
+Postmaster notification from the
+\fBsmtp\fR(8) or \fBsmtpd\fR(8) daemon.
+.br
+.IP "\fB verify \fR"
+Address verification probe from the
+\fBverify\fR(8) daemon.
+.br
+.IP "\fB all \fR"
+Enable SMTPUTF8 autodetection for all
+mail.
+.br
+.br
+.PP
+This feature is available in Postfix 2.12 and later.
+.SH smtputf8_enable (default: no)
+Enable experimental SMTPUTF8 support for the protocols described
+in RFC 6531..6533. This requires that Postfix is built to support
+these protocols.
+.PP
+This feature is available in Postfix 2.12 and later.
.SH soft_bounce (default: no)
Safety net to keep mail queued that would otherwise be returned to
the sender. This parameter disables locally-generated bounces,
.PP
By default, the Postfix SMTP server accepts RFC 822 syntax in MAIL
FROM and RCPT TO addresses.
+.SH strict_smtputf8 (default: no)
+Enable stricter enforcement of the SMTPUTF8 protocol. The Postfix
+SMTP server accepts UTF8 sender or recipient addresses only when
+the client requests an SMTPUTF8 mail transaction.
+.PP
+This feature is available in Postfix 2.12 and later.
.SH sun_mailtool_compatibility (default: no)
Obsolete SUN mailtool compatibility feature. Instead, use
"mailbox_delivery_lock = dotlock".
RFC 3464 (Delivery Status Notifications)
RFC 3834 (Auto-Submitted: message header)
RFC 5322 (Internet Message Format)
+RFC 6531 (Internationalized SMTP)
+RFC 6532 (Internationalized Message Format)
+RFC 6533 (Internationalized Delivery Status Notifications)
.SH DIAGNOSTICS
.ad
.fi
.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
The mail system name that is prepended to the process name in syslog
records, so that "smtpd" becomes, for example, "postfix/smtpd".
+.PP
+Available in Postfix 2.12 and later:
+.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes.
.SH "FILES"
.na
.nf
.IP "\fBreceive_override_options (empty)\fR"
Enable or disable recipient validation, built-in content
filtering, or address mapping.
+.SH "SMTPUTF8 CONTROLS"
+.na
+.nf
+.ad
+.fi
+Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes.
.SH "RESOURCE AND RATE CONTROLS"
.na
.nf
RFC 3463 (Enhanced Status Codes)
RFC 4954 (AUTH command)
RFC 5321 (SMTP protocol)
+RFC 6531 (Internationalized SMTP)
+RFC 6533 (Internationalized Delivery Status Notifications)
.SH DIAGNOSTICS
.ad
.fi
When SMTP connection caching is enabled, the number of times
that an SMTP session may be reused before it is closed, or zero (no
limit).
+.SH "SMTPUTF8 CONTROLS"
+.na
+.nf
+.ad
+.fi
+Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+.IP "\fBsmtputf8_enable (no)\fR"
+Enable experimental SMTPUTF8 support for the protocols described
+in RFC 6531..6533.
+.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+Enable SMTPUTF8 autodetection for the specified mail origin
+classes.
.SH "TROUBLE SHOOTING CONTROLS"
.na
.nf
RFC 4409 (Message submission)
RFC 4954 (AUTH command)
RFC 5321 (SMTP protocol)
+RFC 6531 (Internationalized SMTP)
+RFC 6533 (Internationalized Delivery Status Notifications)
.SH DIAGNOSTICS
.ad
.fi
.IP "\fBsmtpd_tls_cipherlist (empty)\fR"
Obsolete Postfix < 2.3 control for the Postfix SMTP server TLS
cipher list.
+.SH "SMTPUTF8 CONTROLS"
+.na
+.nf
+.ad
+.fi
+Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+.IP "\fBsmtputf8_enable (no)\fR"
+Enable experimental SMTPUTF8 support for the protocols described
+in RFC 6531..6533.
+.IP "\fBstrict_smtputf8 (no)\fR"
+Enable stricter enforcement of the SMTPUTF8 protocol.
+.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes.
.SH "VERP SUPPORT CONTROLS"
.na
.nf
.IP "\fBaddress_verify_sender_dependent_default_transport_maps ($sender_dependent_default_transport_maps)\fR"
Overrides the sender_dependent_default_transport_maps parameter
setting for address verification probes.
+.SH "SMTPUTF8 CONTROLS"
+.na
+.nf
+.ad
+.fi
+Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+Enable SMTPUTF8 autodetection for the specified mail origin
+classes.
.SH "MISCELLANEOUS CONTROLS"
.na
.nf
s;\btlsproxy_tls_security_level\b;<a href="postconf.5.html#tlsproxy_tls_security_level">$&</a>;g;
s;\btlsproxy_use_tls\b;<a href="postconf.5.html#tlsproxy_use_tls">$&</a>;g;
+ # SMTPUTF8
+
+ s;\bsmtputf8_enable\b;<a href="postconf.5.html#smtputf8_enable">$&</a>;g;
+ s;\bstrict_smtputf8\b;<a href="postconf.5.html#strict_smtputf8">$&</a>;g;
+ s;\bsmtputf8_autodetect_classes\b;<a href="postconf.5.html#smtputf8_autodetect_classes">$&</a>;g;
+
# Service-defined parameters...
s;\bpolicy_time_limit\b;<a href="postconf.5.html#transport_time_limit">$&</a>;g;
EPOLL support. By default, EPOLL support is compiled in on platforms
that are known to support this feature. </td> </tr>
+<tr> <td> </td> <td> -DNO_EAI </td> <td> Do not build with EAI
+(SMTPUTF8) support. By default, EAI support is compiled in when
+the "icuuc" library and header files are found. </td> </tr>
+
<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6
support. By default, IPv6 support is compiled in on platforms that
are known to have IPv6 support. Note: this directive is for debugging
service request. Specify a value greater than zero. </p>
<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM smtputf8_enable no
+
+<p> Enable experimental SMTPUTF8 support for the protocols described
+in RFC 6531..6533. This requires that Postfix is built to support
+these protocols. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM strict_smtputf8 no
+
+<p> Enable stricter enforcement of the SMTPUTF8 protocol. The Postfix
+SMTP server accepts UTF8 sender or recipient addresses only when
+the client requests an SMTPUTF8 mail transaction. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM smtputf8_autodetect_classes sendmail, verify
+
+<p> Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes. This is a workaround to avoid chicken-and-egg
+problems during the initial SMTPUTF8 roll-out in environments with
+pre-existing mail flows that contain UTF8. Those mail flows should
+not break because Postfix suddenly refuses to deliver such mail
+to down-stream MTAs that don't announce SMTPUTF8 support. </p>
+
+<p> The problem is that Postfix cannot rely solely on the sender's
+declaration that a message requires SMTPUTF8 support, because UTF8
+may be introduced during local processing (for example, the client
+hostname in Postfix's Received: header, adding @$myorigin or
+.$mydomain to an incomplete address, address rewriting, alias
+expansion, automatic BCC recipients, local forwarding, and changes
+made by header checks or Milter applications). </p>
+
+<p> For now, the default is to enable "SMTPUTF8 required" autodetection
+only for Postfix sendmail command-line submissions and address
+verification probes. This may change once SMTPUTF8 support achieves
+world domination. However, sites that add UTF8 content via local
+processing (see above) should autodetect the need for SMTPUTF8
+support for all email.</p>
+
+<p> Specify one or more of the following: </p>
+
+<dl compact>
+
+<dt> <b> sendmail </b> </dt> <dd> Submission with the Postfix
+sendmail(1) command. </dd>
+
+<dt> <b> smtpd </b> </dt> <dd> Mail received with the smtpd(8)
+daemon. </dd>
+
+<dt> <b> qmqpd </b> </dt> <dd> Mail received with the qmqpd(8)
+daemon. </dd>
+
+<dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing.
+</dd>
+
+<dt> <b> bounce </b> </dt> <dd> Submission by the bounce(8) daemon.
+</dd>
+
+<dt> <b> notify </b> </dt> <dd> Postmaster notification from the
+smtp(8) or smtpd(8) daemon. </dd>
+
+<dt> <b> verify </b> </dt> <dd> Address verification probe from the
+verify(8) daemon. </dd>
+
+<dt> <b> all </b> </dt> <dd> Enable SMTPUTF8 autodetection for all
+mail. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
bounce_notify_service.o: ../../include/dsn.h
bounce_notify_service.o: ../../include/dsn_buf.h
bounce_notify_service.o: ../../include/dsn_mask.h
-bounce_notify_service.o: ../../include/int_filt.h
+bounce_notify_service.o: ../../include/iostuff.h
bounce_notify_service.o: ../../include/mail_addr.h
bounce_notify_service.o: ../../include/mail_error.h
bounce_notify_service.o: ../../include/mail_params.h
+bounce_notify_service.o: ../../include/mail_proto.h
bounce_notify_service.o: ../../include/mail_queue.h
bounce_notify_service.o: ../../include/msg.h
bounce_notify_service.o: ../../include/msg_stats.h
bounce_notify_service.o: ../../include/name_mask.h
bounce_notify_service.o: ../../include/post_mail.h
bounce_notify_service.o: ../../include/rcpt_buf.h
+bounce_notify_service.o: ../../include/rec_type.h
bounce_notify_service.o: ../../include/recipient_list.h
bounce_notify_service.o: ../../include/sys_defs.h
bounce_notify_service.o: ../../include/vbuf.h
bounce_notify_util.o: ../../include/dsn_buf.h
bounce_notify_util.o: ../../include/dsn_mask.h
bounce_notify_util.o: ../../include/events.h
-bounce_notify_util.o: ../../include/int_filt.h
bounce_notify_util.o: ../../include/iostuff.h
bounce_notify_util.o: ../../include/is_header.h
bounce_notify_util.o: ../../include/lex_822.h
bounce_notify_verp.o: ../../include/dsn.h
bounce_notify_verp.o: ../../include/dsn_buf.h
bounce_notify_verp.o: ../../include/dsn_mask.h
-bounce_notify_verp.o: ../../include/int_filt.h
+bounce_notify_verp.o: ../../include/iostuff.h
bounce_notify_verp.o: ../../include/mail_addr.h
bounce_notify_verp.o: ../../include/mail_error.h
bounce_notify_verp.o: ../../include/mail_params.h
+bounce_notify_verp.o: ../../include/mail_proto.h
bounce_notify_verp.o: ../../include/mail_queue.h
bounce_notify_verp.o: ../../include/msg.h
bounce_notify_verp.o: ../../include/msg_stats.h
bounce_notify_verp.o: ../../include/name_mask.h
bounce_notify_verp.o: ../../include/post_mail.h
bounce_notify_verp.o: ../../include/rcpt_buf.h
+bounce_notify_verp.o: ../../include/rec_type.h
bounce_notify_verp.o: ../../include/recipient_list.h
bounce_notify_verp.o: ../../include/sys_defs.h
bounce_notify_verp.o: ../../include/vbuf.h
bounce_one_service.o: ../../include/dsn.h
bounce_one_service.o: ../../include/dsn_buf.h
bounce_one_service.o: ../../include/dsn_mask.h
-bounce_one_service.o: ../../include/int_filt.h
+bounce_one_service.o: ../../include/iostuff.h
bounce_one_service.o: ../../include/mail_addr.h
bounce_one_service.o: ../../include/mail_error.h
bounce_one_service.o: ../../include/mail_params.h
+bounce_one_service.o: ../../include/mail_proto.h
bounce_one_service.o: ../../include/msg.h
bounce_one_service.o: ../../include/msg_stats.h
bounce_one_service.o: ../../include/name_mask.h
bounce_one_service.o: ../../include/post_mail.h
bounce_one_service.o: ../../include/rcpt_buf.h
+bounce_one_service.o: ../../include/rec_type.h
bounce_one_service.o: ../../include/recipient_list.h
bounce_one_service.o: ../../include/sys_defs.h
bounce_one_service.o: ../../include/vbuf.h
bounce_trace_service.o: ../../include/dsn.h
bounce_trace_service.o: ../../include/dsn_buf.h
bounce_trace_service.o: ../../include/dsn_mask.h
-bounce_trace_service.o: ../../include/int_filt.h
+bounce_trace_service.o: ../../include/iostuff.h
bounce_trace_service.o: ../../include/mail_addr.h
bounce_trace_service.o: ../../include/mail_error.h
bounce_trace_service.o: ../../include/mail_params.h
+bounce_trace_service.o: ../../include/mail_proto.h
bounce_trace_service.o: ../../include/mail_queue.h
bounce_trace_service.o: ../../include/msg.h
bounce_trace_service.o: ../../include/msg_stats.h
bounce_trace_service.o: ../../include/name_mask.h
bounce_trace_service.o: ../../include/post_mail.h
bounce_trace_service.o: ../../include/rcpt_buf.h
+bounce_trace_service.o: ../../include/rec_type.h
bounce_trace_service.o: ../../include/recipient_list.h
bounce_trace_service.o: ../../include/sys_defs.h
bounce_trace_service.o: ../../include/vbuf.h
bounce_warn_service.o: ../../include/dsn.h
bounce_warn_service.o: ../../include/dsn_buf.h
bounce_warn_service.o: ../../include/dsn_mask.h
-bounce_warn_service.o: ../../include/int_filt.h
+bounce_warn_service.o: ../../include/iostuff.h
bounce_warn_service.o: ../../include/mail_addr.h
bounce_warn_service.o: ../../include/mail_error.h
bounce_warn_service.o: ../../include/mail_params.h
+bounce_warn_service.o: ../../include/mail_proto.h
bounce_warn_service.o: ../../include/mail_queue.h
bounce_warn_service.o: ../../include/msg.h
bounce_warn_service.o: ../../include/name_mask.h
bounce_warn_service.o: ../../include/post_mail.h
bounce_warn_service.o: ../../include/rcpt_buf.h
+bounce_warn_service.o: ../../include/rec_type.h
bounce_warn_service.o: ../../include/recipient_list.h
bounce_warn_service.o: ../../include/sys_defs.h
bounce_warn_service.o: ../../include/vbuf.h
/* RFC 3464 (Delivery Status Notifications)
/* RFC 3834 (Auto-Submitted: message header)
/* RFC 5322 (Internet Message Format)
+/* RFC 6531 (Internationalized SMTP)
+/* RFC 6532 (Internationalized Message Format)
+/* RFC 6533 (Internationalized Delivery Status Notifications)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* CONFIGURATION PARAMETERS
/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
/* The mail system name that is prepended to the process name in syslog
/* records, so that "smtpd" becomes, for example, "postfix/smtpd".
+/* .PP
+/* Available in Postfix 2.12 and later:
+/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+/* Detect that a message requires SMTPUTF8 support for the specified
+/* mail origin classes.
/* FILES
/* /var/spool/postfix/bounce/* non-delivery records
/* /var/spool/postfix/defer/* non-delivery records
static int bounce_notify_proto(char *service_name, VSTREAM *client,
int (*service) (int, char *, char *, char *,
- char *, char *, char *, int,
+ char *, int, char *, char *, int,
BOUNCE_TEMPLATES *))
{
const char *myname = "bounce_notify_proto";
int flags;
+ int smtputf8;
int dsn_ret;
/*
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, &smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, &dsn_ret,
- ATTR_TYPE_END) != 7) {
+ ATTR_TYPE_END) != 8) {
msg_warn("malformed request");
return (-1);
}
}
printable(STR(dsn_envid), '?');
if (msg_verbose)
- msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s envid=%s ret=0x%x",
+ msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x",
myname, flags, service_name, STR(queue_name), STR(queue_id),
- STR(encoding), STR(sender), STR(dsn_envid), dsn_ret);
+ STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
+ dsn_ret);
/*
* On request by the client, set up a trap to delete the log file in case
* Execute the request.
*/
return (service(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding),
+ STR(queue_id), STR(encoding), smtputf8,
STR(sender), STR(dsn_envid), dsn_ret,
bounce_templates));
}
{
const char *myname = "bounce_verp_proto";
int flags;
+ int smtputf8;
int dsn_ret;
/*
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, &smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, &dsn_ret,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
- ATTR_TYPE_END) != 8) {
+ ATTR_TYPE_END) != 9) {
msg_warn("malformed request");
return (-1);
}
return (-1);
}
if (msg_verbose)
- msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s envid=%s ret=0x%x delim=%s",
+ msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x delim=%s",
myname, flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding), STR(sender),
+ STR(queue_id), STR(encoding), smtputf8, STR(sender),
STR(dsn_envid), dsn_ret, STR(verp_delims));
/*
if (!*STR(sender) || !strcasecmp(STR(sender), mail_addr_double_bounce())) {
msg_warn("request to send VERP-style notification of bounced mail");
return (bounce_notify_service(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding),
+ STR(queue_id), STR(encoding), smtputf8,
STR(sender), STR(dsn_envid), dsn_ret,
bounce_templates));
} else
return (bounce_notify_verp(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding),
+ STR(queue_id), STR(encoding), smtputf8,
STR(sender), STR(dsn_envid), dsn_ret,
STR(verp_delims), bounce_templates));
}
{
const char *myname = "bounce_one_proto";
int flags;
+ int smtputf8;
int dsn_ret;
/*
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, &smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, &dsn_ret,
ATTR_TYPE_FUNC, rcpb_scan, (void *) rcpt_buf,
ATTR_TYPE_FUNC, dsb_scan, (void *) dsn_buf,
- ATTR_TYPE_END) != 9) {
+ ATTR_TYPE_END) != 10) {
msg_warn("malformed request");
return (-1);
}
* RECIPIENT_FROM_RCPT_BUF().
*/
if (msg_verbose)
- msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s sender=%s envid=%s dsn_ret=0x%x orig_to=%s to=%s off=%ld dsn_orig=%s notif=0x%x stat=%s act=%s why=%s",
+ msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s dsn_ret=0x%x orig_to=%s to=%s off=%ld dsn_orig=%s notif=0x%x stat=%s act=%s why=%s",
myname, flags, STR(queue_name), STR(queue_id),
- STR(encoding), STR(sender), STR(dsn_envid), dsn_ret,
- STR(rcpt_buf->orig_addr), STR(rcpt_buf->address),
+ STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
+ dsn_ret, STR(rcpt_buf->orig_addr), STR(rcpt_buf->address),
rcpt_buf->offset, STR(rcpt_buf->dsn_orcpt),
rcpt_buf->dsn_notify, STR(dsn_buf->status),
STR(dsn_buf->action), STR(dsn_buf->reason));
* Execute the request.
*/
return (bounce_one_service(flags, STR(queue_name), STR(queue_id),
- STR(encoding), STR(sender), STR(dsn_envid),
- dsn_ret, rcpt_buf, dsn_buf, bounce_templates));
+ STR(encoding), smtputf8, STR(sender),
+ STR(dsn_envid), dsn_ret, rcpt_buf,
+ dsn_buf, bounce_templates));
}
/* bounce_service - parse bounce command type and delegate */
/* SYNOPSIS
/* #include "bounce_service.h"
/*
-/* int bounce_notify_service(flags, queue_name, queue_id, encoding,
-/* sender, dsn_envid, dsn_ret, templates)
+/* int bounce_notify_service(flags, service, queue_name, queue_id,
+/* encoding, smtputf8, sender, dsn_envid,
+/* dsn_ret, templates)
/* int flags;
+/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
+/* int smtputf8;
/* char *sender;
/* char *dsn_envid;
/* int dsn_ret;
#include <mail_error.h>
#include <bounce.h>
#include <dsn_mask.h>
+#include <rec_type.h>
/* Application-specific. */
int bounce_notify_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- char *recipient, char *dsn_envid,
- int dsn_ret, BOUNCE_TEMPLATES *ts)
+ int smtputf8, char *recipient,
+ char *dsn_envid, int dsn_ret,
+ BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
* notification is enabled.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, ts->failure);
+ encoding, smtputf8, dsn_envid,
+ ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
postmaster = var_2bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
/* .in -4
/* } BOUNCE_INFO;
/*
-/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id,
-/* encoding, dsn_envid, template)
+/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id, encoding,
+/* smtputf8, dsn_envid, template)
/* const char *service;
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
+/* int smtputf8;
/* const char *dsn_envid;
/* const BOUNCE_TEMPLATE *template;
/*
/* BOUNCE_INFO *bounce_mail_one_init(queue_name, queue_id, encoding,
-/* dsn_envid, dsn_notify, rcpt_buf,
-/* dsn_buf, template)
+/* smtputf8, dsn_envid, dsn_notify,
+/* rcpt_buf, dsn_buf, template)
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
+/* int smtputf8;
/* int dsn_notify;
/* const char *dsn_envid;
/* RCPT_BUF *rcpt_buf;
const char *queue_name,
const char *queue_id,
const char *encoding,
+ int smtputf8,
const char *dsn_envid,
RCPT_BUF *rcpt_buf,
DSN_BUF *dsn_buf,
bounce_info->service = service;
bounce_info->queue_name = queue_name;
bounce_info->queue_id = queue_id;
- if (strcmp(encoding, MAIL_ATTR_ENC_8BIT) == 0) {
+ 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) {
+ bounce_info->mime_encoding = "8bit";
+ } else if (strcmp(encoding, MAIL_ATTR_ENC_8BIT) == 0) {
bounce_info->mime_encoding = "8bit";
} else if (strcmp(encoding, MAIL_ATTR_ENC_7BIT) == 0) {
bounce_info->mime_encoding = "7bit";
const char *queue_name,
const char *queue_id,
const char *encoding,
+ int smtputf8,
const char *dsn_envid,
BOUNCE_TEMPLATE *template)
{
dsn_buf = dsb_create();
}
bounce_info = bounce_mail_alloc(service, queue_name, queue_id, encoding,
- dsn_envid, rcpt_buf, dsn_buf,
+ smtputf8, dsn_envid, rcpt_buf, dsn_buf,
template, log_handle);
return (bounce_info);
}
BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
const char *queue_id,
const char *encoding,
+ int smtputf8,
const char *dsn_envid,
RCPT_BUF *rcpt_buf,
DSN_BUF *dsn_buf,
* Initialize the bounce_info structure for just one recipient.
*/
bounce_info = bounce_mail_alloc("none", queue_name, queue_id, encoding,
- dsn_envid, rcpt_buf, dsn_buf, template,
- (BOUNCE_LOG *) 0);
+ smtputf8, dsn_envid, rcpt_buf, dsn_buf,
+ template, (BOUNCE_LOG *) 0);
return (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);
post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
post_mail_fprintf(bounce, "Content-Type: %s; charset=%s",
"text/plain", bounce_template_charset(template));
+ /* Fix 20140709: addresses may be 8bit. */
+ if (bounce_info->smtputf8)
+ post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
+ bounce_info->mime_encoding);
post_mail_fputs(bounce, "");
return (vstream_ferror(bounce));
post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
post_mail_fprintf(bounce, "Content-Description: %s",
"Delivery report");
- post_mail_fprintf(bounce, "Content-Type: %s", "message/delivery-status");
+ post_mail_fprintf(bounce, "Content-Type: message/%sdelivery-status",
+ bounce_info->smtputf8 ? "global-" : "");
+ /* Fix 20140709: addresses may be 8bit. */
+ if (bounce_info->smtputf8)
+ post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
+ bounce_info->mime_encoding);
/*
* According to RFC 1894: The body of a message/delivery-status consists
}
post_mail_fprintf(bounce, "X-%s-Queue-ID: %s",
bounce_info->mail_name, bounce_info->queue_id);
+ /* Fix 20140708: use "utf-8" or "rfc822" as appropriate. */
if (VSTRING_LEN(bounce_info->sender) > 0)
- post_mail_fprintf(bounce, "X-%s-Sender: rfc822; %s",
- bounce_info->mail_name, STR(bounce_info->sender));
+ 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),
+ VSTRING_LEN(bounce_info->sender)) ?
+ "utf-8" : "rfc822", STR(bounce_info->sender));
if (bounce_info->arrival_time > 0)
post_mail_fprintf(bounce, "Arrival-Date: %s",
mail_date(bounce_info->arrival_time));
DSN *dsn = &bounce_info->dsn_buf->dsn;
post_mail_fputs(bounce, "");
- post_mail_fprintf(bounce, "Final-Recipient: rfc822; %s", rcpt->address);
+ /* 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)) ?
+ "utf-8" : "rfc822", rcpt->address);
/*
* XXX DSN
if (NON_NULL_EMPTY(rcpt->dsn_orcpt)) {
post_mail_fprintf(bounce, "Original-Recipient: %s", rcpt->dsn_orcpt);
} else if (NON_NULL_EMPTY(rcpt->orig_addr)) {
- post_mail_fprintf(bounce, "Original-Recipient: rfc822; %s",
- 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)) ?
+ "utf-8" : "rfc822", rcpt->orig_addr);
}
post_mail_fprintf(bounce, "Action: %s",
IS_FAILURE_TEMPLATE(bounce_info->template) ?
"Undelivered " : "",
headers_only == DSN_RET_HDRS ?
"Message Headers" : "Message");
- post_mail_fprintf(bounce, "Content-Type: %s",
- headers_only == DSN_RET_HDRS ?
- "text/rfc822-headers" : "message/rfc822");
+ if (bounce_info->smtputf8)
+ post_mail_fprintf(bounce, "Content-Type: message/%s",
+ headers_only == DSN_RET_HDRS ?
+ "global-headers" : "global");
+ else
+ post_mail_fprintf(bounce, "Content-Type: %s",
+ headers_only == DSN_RET_HDRS ?
+ "text/rfc822-headers" : "message/rfc822");
if (bounce_info->mime_encoding)
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
bounce_info->mime_encoding);
/* SYNOPSIS
/* #include "bounce_service.h"
/*
-/* int bounce_notify_verp(flags, service, queue_name, queue_id, sender,
+/* int bounce_notify_verp(flags, service, queue_name, queue_id,
+/* encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, verp_delims,
/* templates)
/* int flags;
+/* char *service;
/* char *queue_name;
/* char *queue_id;
+/* char *encoding;
+/* int smtputf8;
/* char *sender;
/* char *dsn_envid;
/* int dsn_ret;
#include <verp_sender.h>
#include <bounce.h>
#include <dsn_mask.h>
+#include <rec_type.h>
/* Application-specific. */
int bounce_notify_verp(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- char *recipient, char *dsn_envid,
- int dsn_ret, char *verp_delims,
- BOUNCE_TEMPLATES *ts)
+ int smtputf8, char *recipient,
+ char *dsn_envid, int dsn_ret,
+ char *verp_delims, BOUNCE_TEMPLATES *ts)
{
const char *myname = "bounce_notify_verp";
BOUNCE_INFO *bounce_info;
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, ts->failure);
+ encoding, smtputf8, dsn_envid,
+ ts->failure);
/*
* If we have no recipient list then we can't send VERP replies. Send
vstring_strcpy(rcpt_buf->address, "(recipient address unavailable)");
(void) RECIPIENT_FROM_RCPT_BUF(rcpt_buf);
bounce_status = bounce_one_service(flags, queue_name, queue_id,
- encoding, recipient, dsn_envid,
- dsn_ret, rcpt_buf, dsn_buf, ts);
+ encoding, smtputf8, recipient,
+ dsn_envid, dsn_ret, rcpt_buf,
+ dsn_buf, ts);
rcpb_free(rcpt_buf);
dsb_free(dsn_buf);
bounce_mail_free(bounce_info);
} else {
verp_sender(verp_buf, verp_delims, recipient, rcpt);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster,
/* #include "bounce_service.h"
/*
/* int bounce_one_service(flags, queue_name, queue_id, encoding,
-/* orig_sender, envid, ret,
+/* smtputf8, orig_sender, envid, ret,
/* rcpt_buf, dsn_buf, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
+/* int smtputf8;
/* char *orig_sender;
/* char *envid;
/* int ret;
#include <mail_error.h>
#include <bounce.h>
#include <dsn_mask.h>
+#include <rec_type.h>
/* Application-specific. */
/* bounce_one_service - send a bounce for one recipient */
int bounce_one_service(int flags, char *queue_name, char *queue_id,
- char *encoding, char *orig_sender,
- char *dsn_envid, int dsn_ret,
- RCPT_BUF *rcpt_buf, DSN_BUF *dsn_buf,
- BOUNCE_TEMPLATES *ts)
+ char *encoding, int smtputf8,
+ char *orig_sender, char *dsn_envid,
+ int dsn_ret, RCPT_BUF *rcpt_buf,
+ DSN_BUF *dsn_buf, BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_one_init(queue_name, queue_id, encoding,
- dsn_envid, rcpt_buf, dsn_buf,
- ts->failure);
+ smtputf8, dsn_envid, rcpt_buf,
+ dsn_buf, ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
} else {
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_2bounce_rcpt,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
bounce_status = 0;
} else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, orig_sender,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
*/
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_bounce_rcpt,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, var_bounce_rcpt,
/*
* bounce_notify_service.c
*/
-extern int bounce_notify_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
+extern int bounce_notify_service(int, char *, char *, char *, char *, int, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_warn_service.c
*/
-extern int bounce_warn_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
+extern int bounce_warn_service(int, char *, char *, char *, char *, int, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_trace_service.c
*/
-extern int bounce_trace_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
+extern int bounce_trace_service(int, char *, char *, char *, char *, int, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_notify_verp.c
*/
-extern int bounce_notify_verp(int, char *, char *, char *, char *, char *, char *, int, char *, BOUNCE_TEMPLATES *);
+extern int bounce_notify_verp(int, char *, char *, char *, char *, int, char *, char *, int, char *, BOUNCE_TEMPLATES *);
/*
* bounce_one_service.c
*/
-extern int bounce_one_service(int, char *, char *, char *, char *, char *, int, RCPT_BUF *, DSN_BUF *, BOUNCE_TEMPLATES *);
+extern int bounce_one_service(int, char *, char *, char *, int, char *, char *, int, RCPT_BUF *, DSN_BUF *, BOUNCE_TEMPLATES *);
/*
* bounce_cleanup.c
DSN_BUF *dsn_buf; /* delivery status info */
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;
/* */
-extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, const char *, BOUNCE_TEMPLATE *);
-extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, const char *, RCPT_BUF *, DSN_BUF *, BOUNCE_TEMPLATE *);
+extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, int, const char *, BOUNCE_TEMPLATE *);
+extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, int, const char *, RCPT_BUF *, DSN_BUF *, BOUNCE_TEMPLATE *);
extern void bounce_mail_free(BOUNCE_INFO *);
extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *, int);
extern int bounce_boilerplate(VSTREAM *, BOUNCE_INFO *);
/*
* Parse pseudo-header labels and values.
+ *
+ * XXX EAI: allow UTF8 in template headers when responding to SMTPUTF8
+ * message. Sending SMTPUTF8 in reponse to non-SMTPUTF8 mail would make
+ * no sense.
*/
#define GETLINE(line, buf) \
(((line) = (buf)) != 0 ? ((buf) = split_at((buf), '\n'), (line)) : 0)
/* SYNOPSIS
/* #include "bounce_service.h"
/*
-/* int bounce_trace_service(flags, queue_name, queue_id, encoding,
-/* sender, char *envid, int ret, templates)
+/* int bounce_trace_service(flags, service, queue_name, queue_id,
+/* encoding, smtputf8, sender, envid,
+/* ret, templates)
/* int flags;
+/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
+/* int smtputf8;
/* char *sender;
/* char *envid;
/* int ret;
#include <mail_addr.h>
#include <mail_error.h>
#include <dsn_mask.h>
+#include <rec_type.h>
#include <deliver_request.h> /* USR_VRFY and RECORD flags */
/* Application-specific. */
int bounce_trace_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
+ int smtputf8,
char *recipient, char *dsn_envid,
int unused_dsn_ret,
BOUNCE_TEMPLATES *ts)
#define NON_DSN_FLAGS (DEL_REQ_FLAG_USR_VRFY | DEL_REQ_FLAG_RECORD)
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid,
+ encoding, smtputf8, dsn_envid,
flags & NON_DSN_FLAGS ?
ts->verify : ts->success);
*/
new_id = vstring_alloc(10);
if ((bounce = post_mail_fopen_nowait(sender, recipient,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
/* SYNOPSIS
/* #include "bounce_service.h"
/*
-/* int bounce_warn_service(flags, queue_name, queue_id, encoding,
-/* sender, envid, dsn_ret, templates)
+/* int bounce_warn_service(flags, service, queue_name, queue_id,
+/* encoding, smtputf8, sender, envid,
+/* dsn_ret, templates)
/* int flags;
+/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
+/* int smtputf8;
/* char *sender;
/* char *envid;
/* int dsn_ret;
#include <mail_addr.h>
#include <mail_error.h>
#include <dsn_mask.h>
+#include <rec_type.h>
/* Application-specific. */
int bounce_warn_service(int unused_flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- char *recipient, char *dsn_envid,
- int dsn_ret, BOUNCE_TEMPLATES *ts)
+ int smtputf8, char *recipient,
+ char *dsn_envid, int dsn_ret,
+ BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
* notify_classes restrictions.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, ts->delay);
+ encoding, smtputf8, dsn_envid, ts->delay);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
cleanup_addr.o: ../../include/nvtable.h
cleanup_addr.o: ../../include/rec_type.h
cleanup_addr.o: ../../include/resolve_clnt.h
+cleanup_addr.o: ../../include/smtputf8.h
cleanup_addr.o: ../../include/string_list.h
cleanup_addr.o: ../../include/stringops.h
cleanup_addr.o: ../../include/sys_defs.h
cleanup_api.o: ../../include/rec_type.h
cleanup_api.o: ../../include/recipient_list.h
cleanup_api.o: ../../include/resolve_clnt.h
+cleanup_api.o: ../../include/smtputf8.h
cleanup_api.o: ../../include/string_list.h
cleanup_api.o: ../../include/sys_defs.h
cleanup_api.o: ../../include/tok822.h
cleanup_envelope.o: ../../include/recipient_list.h
cleanup_envelope.o: ../../include/record.h
cleanup_envelope.o: ../../include/resolve_clnt.h
+cleanup_envelope.o: ../../include/smtputf8.h
cleanup_envelope.o: ../../include/string_list.h
cleanup_envelope.o: ../../include/stringops.h
cleanup_envelope.o: ../../include/sys_defs.h
cleanup_out.o: ../../include/rec_type.h
cleanup_out.o: ../../include/record.h
cleanup_out.o: ../../include/resolve_clnt.h
+cleanup_out.o: ../../include/smtputf8.h
cleanup_out.o: ../../include/split_at.h
cleanup_out.o: ../../include/string_list.h
+cleanup_out.o: ../../include/stringops.h
cleanup_out.o: ../../include/sys_defs.h
cleanup_out.o: ../../include/tok822.h
cleanup_out.o: ../../include/vbuf.h
struct CLEANUP_REGION *free_regions;/* unused regions */
struct CLEANUP_REGION *body_regions;/* regions with body content */
struct CLEANUP_REGION *curr_body_region;
+
+ /*
+ * Internationalization.
+ */
+ int smtputf8; /* what support is desired */
} CLEANUP_STATE;
/*
#include <mail_addr_find.h>
#include <mail_proto.h>
#include <dsn_mask.h>
+#include <smtputf8.h>
/* Application-specific. */
#include "cleanup.h"
#define STR vstring_str
+#define LEN VSTRING_LEN
#define IGNORE_EXTENSION (char **) 0
/* cleanup_addr_sender - process envelope sender record */
&& (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
}
+ /* Fix 20140711: Auto-detect an UTF8 sender. */
+ if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
+ && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
+ state->smtputf8 |= SMTPUTF8_FLAG_SENDER;
+ /* Fix 20140713: request SMTPUTF8 support selectively. */
+ if (state->flags & CLEANUP_FLAG_AUTOUTF8)
+ state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ }
CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
if (state->sender) /* XXX Can't happen */
myfree(state->sender);
&& (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
}
+ /* Fix 20140711: Auto-detect an UTF8 recipient. */
+ if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
+ && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
+ /* Fix 20140713: request SMTPUTF8 support selectively. */
+ if (state->flags & CLEANUP_FLAG_AUTOUTF8)
+ state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ }
cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify,
state->orig_rcpt, STR(clean_addr));
if (state->recip) /* This can happen */
&& (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
}
+ /* Fix 20140711: Auto-detect an UTF8 recipient. */
+ if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
+ && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
+ /* Fix 20140713: request SMTPUTF8 support selectively. */
+ if (state->flags & CLEANUP_FLAG_AUTOUTF8)
+ state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ }
cleanup_out_recipient(state, dsn_orcpt, dsn_notify,
STR(clean_addr), STR(clean_addr));
vstring_free(clean_addr);
/* to translate the result into human-readable text.
/*
/* cleanup_free() destroys its argument.
+/* .IP CLEANUP_FLAG_SMTPUTF8
+/* Request SMTPUTF8 support when delivering mail.
+/* .IP CLEANUP_FLAG_AUTOUTF8
+/* Autodetection: request SMTPUTF8 support if the message
+/* contains an UTF8 message header, sender, or recipient.
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* SEE ALSO
#include <mail_stream.h>
#include <mail_flow.h>
#include <rec_type.h>
+#include <smtputf8.h>
/* Milter library. */
} else {
state->err_mask = ~0;
}
+ if (state->flags & CLEANUP_FLAG_SMTPUTF8)
+ state->smtputf8 = SMTPUTF8_FLAG_REQUESTED;
}
/* cleanup_flush - finish queue file */
bounce_err =
bounce_flush(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
- encoding, state->sender, dsn_envid,
- dsn_ret);
+ encoding, state->smtputf8, state->sender,
+ dsn_envid, dsn_ret);
} else {
bounce_err =
bounce_flush_verp(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
- encoding, state->sender, dsn_envid,
- dsn_ret, state->verp_delims);
+ encoding, state->smtputf8, state->sender,
+ dsn_envid, dsn_ret, state->verp_delims);
}
if (bounce_err != 0) {
msg_warn("%s: bounce message failure", state->queue_id);
#include <sys_defs.h>
#include <string.h>
#include <stdlib.h>
+#include <stdio.h> /* ssscanf() */
#include <ctype.h>
/* Utility library. */
#include <mail_proto.h>
#include <dsn_mask.h>
#include <rec_attr_map.h>
+#include <smtputf8.h>
/* Application-specific. */
(REC_TYPE_SIZE_CAST2) 0, /* content offset */
(REC_TYPE_SIZE_CAST3) 0, /* recipient count */
(REC_TYPE_SIZE_CAST4) 0, /* qmgr options */
- (REC_TYPE_SIZE_CAST5) 0); /* content length */
+ (REC_TYPE_SIZE_CAST5) 0, /* content length */
+ (REC_TYPE_SIZE_CAST6) 0); /* smtputf8 */
/*
* Pass control to the actual envelope processing routine.
/*
* Initial envelope non-recipient record processing.
+ *
+ * If the message was requeued with "postsuper -r" use their
+ * SMTPUTF8_REQUESTED flag.
*/
if (state->flags & CLEANUP_FLAG_INRCPT)
/* Tell qmgr that recipient records are mixed with other information. */
state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER;
- if (type == REC_TYPE_SIZE)
- /* Use our own SIZE record instead. */
+ if (type == REC_TYPE_SIZE) {
+ /* Use our own SIZE record, except for the SMTPUTF8_REQUESTED flag. */
+ (void) sscanf(buf, "%*s $*s %*s %*s %*s %d", &state->smtputf8);
+ state->smtputf8 &= SMTPUTF8_FLAG_REQUESTED;
return;
+ }
if (mapped_type == REC_TYPE_CTIME)
/* Use our own expiration time base record instead. */
return;
(REC_TYPE_SIZE_CAST2) state->data_offset,
(REC_TYPE_SIZE_CAST3) state->rcpt_count,
(REC_TYPE_SIZE_CAST4) state->qmgr_opts,
- (REC_TYPE_SIZE_CAST5) state->cont_length);
+ (REC_TYPE_SIZE_CAST5) state->cont_length,
+ (REC_TYPE_SIZE_CAST6) state->smtputf8);
}
#include <vstring.h>
#include <vstream.h>
#include <split_at.h>
+#include <stringops.h>
/* Global library. */
#include <cleanup_user.h>
#include <mail_params.h>
#include <lex_822.h>
+#include <smtputf8.h>
/* Application-specific. */
#include "cleanup.h"
+#define STR vstring_str
+
/* cleanup_out - output one single record */
void cleanup_out(CLEANUP_STATE *state, int type, const char *string, ssize_t len)
char *next_line;
ssize_t line_len;
+ /*
+ * Fix 20140711: Auto-detect the presence of a non-ASCII header.
+ */
+ if (var_smtputf8_enable && *STR(header_buf) && !allascii(STR(header_buf))) {
+ state->smtputf8 |= SMTPUTF8_FLAG_HEADER;
+ /* Fix 20140713: request SMTPUTF8 support selectively. */
+ if (state->flags & CLEANUP_FLAG_AUTOUTF8)
+ state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ }
+
/*
* Prepend a tab to continued header lines that went through the address
* rewriting machinery. See cleanup_fold_header(state) below for the form
state->milter_ext_rcpt = 0;
state->milter_err_text = 0;
state->free_regions = state->body_regions = state->curr_body_region = 0;
+ state->smtputf8 = 0;
return (state);
}
match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \
dict_memcache.c mail_version.c memcache_proto.c server_acl.c \
- mkmap_fail.c haproxy_srvr.c dsn_filter.c dynamicmaps.c
+ mkmap_fail.c haproxy_srvr.c dsn_filter.c dynamicmaps.c uxtext.c \
+ smtputf8.c
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \
dict_memcache.o mail_version.o memcache_proto.o server_acl.o \
- mkmap_fail.o haproxy_srvr.o dsn_filter.o dynamicmaps.o \
- $(NON_PLUGIN_MAP_OBJ)
+ mkmap_fail.o haproxy_srvr.o dsn_filter.o dynamicmaps.o uxtext.o \
+ smtputf8.o $(NON_PLUGIN_MAP_OBJ)
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
fold_addr.h header_body_checks.h data_redirect.h match_service.h \
addr_match_list.h smtp_reply_footer.h safe_ultostr.h \
verify_sender_addr.h dict_memcache.h memcache_proto.h server_acl.h \
- haproxy_srvr.h dsn_filter.h dynamicmaps.h
+ haproxy_srvr.h dsn_filter.h dynamicmaps.h uxtext.h smtputf8.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
verify_clnt xtext anvil_clnt scache ehlo_mask \
valid_mailhost_addr own_inet_addr header_body_checks \
data_redirect addr_match_list safe_ultostr verify_sender_addr \
- mail_version mail_dict server_acl
+ mail_version mail_dict server_acl uxtext
LIBS = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
LIB_DIR = ../../lib
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
+uxtext: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
verify_clnt: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
input_transp.o: input_transp.c
input_transp.o: input_transp.h
input_transp.o: mail_params.h
+int_filt.o: ../../include/attr.h
+int_filt.o: ../../include/iostuff.h
int_filt.o: ../../include/msg.h
int_filt.o: ../../include/name_mask.h
int_filt.o: ../../include/sys_defs.h
int_filt.o: ../../include/vbuf.h
+int_filt.o: ../../include/vstream.h
int_filt.o: ../../include/vstring.h
int_filt.o: cleanup_user.h
int_filt.o: int_filt.c
int_filt.o: int_filt.h
int_filt.o: mail_params.h
+int_filt.o: mail_proto.h
is_header.o: ../../include/sys_defs.h
is_header.o: is_header.c
is_header.o: is_header.h
post_mail.o: ../../include/vstream.h
post_mail.o: ../../include/vstring.h
post_mail.o: cleanup_user.h
-post_mail.o: int_filt.h
post_mail.o: mail_date.h
post_mail.o: mail_params.h
post_mail.o: mail_proto.h
smtp_stream.o: ../../include/vstring_vstream.h
smtp_stream.o: smtp_stream.c
smtp_stream.o: smtp_stream.h
+smtputf8.o: ../../include/attr.h
+smtputf8.o: ../../include/iostuff.h
+smtputf8.o: ../../include/msg.h
+smtputf8.o: ../../include/name_mask.h
+smtputf8.o: ../../include/sys_defs.h
+smtputf8.o: ../../include/vbuf.h
+smtputf8.o: ../../include/vstream.h
+smtputf8.o: ../../include/vstring.h
+smtputf8.o: cleanup_user.h
+smtputf8.o: mail_params.h
+smtputf8.o: mail_proto.h
+smtputf8.o: smtputf8.c
+smtputf8.o: smtputf8.h
split_addr.o: ../../include/split_at.h
split_addr.o: ../../include/sys_defs.h
split_addr.o: mail_addr.h
user_acl.o: string_list.h
user_acl.o: user_acl.c
user_acl.o: user_acl.h
+uxtext.o: ../../include/msg.h
+uxtext.o: ../../include/sys_defs.h
+uxtext.o: ../../include/vbuf.h
+uxtext.o: ../../include/vstring.h
+uxtext.o: uxtext.c
+uxtext.o: uxtext.h
valid_mailhost_addr.o: ../../include/msg.h
valid_mailhost_addr.o: ../../include/myaddrinfo.h
valid_mailhost_addr.o: ../../include/sys_defs.h
/* SYNOPSIS
/* #include <abounce.h>
/*
-/* void abounce_flush(flags, queue, id, encoding, sender,
+/* void abounce_flush(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void abounce_flush_verp(flags, queue, id, encoding, sender,
+/* void abounce_flush_verp(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_flush(flags, queue, id, encoding, sender,
+/* void adefer_flush(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_flush_verp(flags, queue, id, encoding, sender,
+/* void adefer_flush_verp(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_warn(flags, queue, id, encoding, sender,
+/* void adefer_warn(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void atrace_flush(flags, queue, id, encoding, sender,
+/* void atrace_flush(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* file has the same name as the original message file.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
+/* .IP smtputf8
+/* The level of SMTPUTF8 support (to be defined).
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
int command, int flags,
const char *queue, const char *id,
const char *encoding,
+ int smtputf8,
const char *sender,
const char *dsn_envid,
int dsn_ret,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp,
ATTR_TYPE_END) == 0
&& vstream_fflush(ap->fp) == 0) {
- ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
+ ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
(char *) ap, ABOUNCE_TIMEOUT);
} else {
abounce_done(ap, -1);
/* abounce_flush_verp - asynchronous bounce flush */
void abounce_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- const char *verp, ABOUNCE_FN callback,
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, const char *verp,
+ ABOUNCE_FN callback,
char *context)
{
abounce_request_verp(MAIL_CLASS_PRIVATE, var_bounce_service,
- BOUNCE_CMD_VERP, flags, queue, id, encoding,
+ BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
sender, dsn_envid, dsn_ret, verp, callback, context);
}
/* adefer_flush_verp - asynchronous defer flush */
void adefer_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- const char *verp, ABOUNCE_FN callback,
- char *context)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, const char *verp,
+ ABOUNCE_FN callback, char *context)
{
flags |= BOUNCE_FLAG_DELRCPT;
abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
- BOUNCE_CMD_VERP, flags, queue, id, encoding,
+ BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
sender, dsn_envid, dsn_ret, verp, callback, context);
}
static void abounce_request(const char *class, const char *service,
int command, int flags,
const char *queue, const char *id,
- const char *encoding, const char *sender,
+ const char *encoding, int smtputf8,
+ const char *sender,
const char *dsn_envid, int dsn_ret,
ABOUNCE_FN callback, char *context)
{
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
ATTR_TYPE_END) == 0
&& vstream_fflush(ap->fp) == 0) {
- ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
+ ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
(char *) ap, ABOUNCE_TIMEOUT);
} else {
abounce_done(ap, -1);
/* abounce_flush - asynchronous bounce flush */
void abounce_flush(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- ABOUNCE_FN callback, char *context)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, ABOUNCE_FN callback,
+ char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
- flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
- callback, context);
+ flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ dsn_ret, callback, context);
}
/* adefer_flush - asynchronous defer flush */
void adefer_flush(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- ABOUNCE_FN callback, char *context)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, ABOUNCE_FN callback, char *context)
{
flags |= BOUNCE_FLAG_DELRCPT;
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
- flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
- callback, context);
+ flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ dsn_ret, callback, context);
}
/* adefer_warn - send copy of defer log to sender as warning bounce */
void adefer_warn(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- ABOUNCE_FN callback, char *context)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, ABOUNCE_FN callback, char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
- flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
- callback, context);
+ flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ dsn_ret, callback, context);
}
/* atrace_flush - asynchronous trace flush */
void atrace_flush(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- ABOUNCE_FN callback, char *context)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, ABOUNCE_FN callback, char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_trace_service, BOUNCE_CMD_TRACE,
- flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
- callback, context);
+ flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ dsn_ret, callback, context);
}
*/
typedef void (*ABOUNCE_FN) (int, char *);
-extern void abounce_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
-extern void adefer_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
-extern void adefer_warn(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
-extern void atrace_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
+extern void abounce_flush(int, const char *, const char *, const char *, int, const char *, const char *, int, ABOUNCE_FN, char *);
+extern void adefer_flush(int, const char *, const char *, const char *, int, const char *, const char *, int, ABOUNCE_FN, char *);
+extern void adefer_warn(int, const char *, const char *, const char *, int, const char *, const char *, int, ABOUNCE_FN, char *);
+extern void atrace_flush(int, const char *, const char *, const char *, int, const char *, const char *, int, ABOUNCE_FN, char *);
-extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
-extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
+extern void abounce_flush_verp(int, const char *, const char *, const char *, int, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
+extern void adefer_flush_verp(int, const char *, const char *, const char *, int, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
/* LICENSE
/* .ad
/* const char *relay;
/* DSN *dsn;
/*
-/* int bounce_flush(flags, queue, id, encoding, sender,
+/* int bounce_flush(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int bounce_flush_verp(flags, queue, id, encoding, sender,
-/* dsn_envid, dsn_ret, verp_delims)
+/* int bounce_flush_verp(flags, queue, id, encoding, smtputf8,
+/* sender, dsn_envid, dsn_ret, verp_delims)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* const char *verp_delims;
/*
-/* int bounce_one(flags, queue, id, encoding, sender, envid, ret,
-/* stats, recipient, relay, dsn)
+/* int bounce_one(flags, queue, id, encoding, smtputf8, sender,
+/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* RECIPIENT *rcpt;
/* const char *relay;
/*
-/* int bounce_one_intern(flags, queue, id, encoding, sender, envid, ret,
-/* stats, recipient, relay, dsn)
+/* int bounce_one_intern(flags, queue, id, encoding, smtputf8, sender,
+/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* This information is used for syslogging only.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
+/* .IP smtputf8
+/* The level of SMTPUTF8 support (to be defined).
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
* DSN filter (Postfix 2.12).
*/
if (delivery_status_filter != 0
- && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
+ && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
if (dsn_res->status[0] == '4')
return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
my_dsn = *dsn_res;
/* bounce_flush - flush the bounce log and deliver to the sender */
int bounce_flush(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret)
{
/*
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
/* bounce_flush_verp - verpified notification */
int bounce_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- const char *verp_delims)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, const char *verp_delims)
{
/*
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
/* bounce_one - send notice for one recipient */
int bounce_one(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- MSG_STATS *stats, RECIPIENT *rcpt,
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
const char *relay, DSN *dsn)
{
DSN my_dsn = *dsn;
* DSN filter (Postfix 2.12).
*/
if (delivery_status_filter != 0
- && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
+ && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
if (dsn_res->status[0] == '4')
return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
my_dsn = *dsn_res;
}
- return (bounce_one_intern(flags, queue, id, encoding, sender, dsn_envid,
- dsn_ret, stats, rcpt, relay, &my_dsn));
+ return (bounce_one_intern(flags, queue, id, encoding, smtputf8, sender,
+ dsn_envid, dsn_ret, stats, rcpt, relay, &my_dsn));
}
/* bounce_one_intern - send notice for one recipient */
int bounce_one_intern(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- MSG_STATS *stats, RECIPIENT *rcpt,
- const char *relay, DSN *dsn)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, MSG_STATS *stats,
+ RECIPIENT *rcpt, const char *relay,
+ DSN *dsn)
{
DSN my_dsn = *dsn;
int status;
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
*/
extern int bounce_append(int, const char *, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
-extern int bounce_flush(int, const char *, const char *, const char *,
+extern int bounce_flush(int, const char *, const char *, const char *, int,
const char *, const char *, int);
-extern int bounce_flush_verp(int, const char *, const char *, const char *,
+extern int bounce_flush_verp(int, const char *, const char *, const char *, int,
const char *, const char *, int, const char *);
-extern int bounce_one(int, const char *, const char *, const char *,
+extern int bounce_one(int, const char *, const char *, const char *, int,
const char *, const char *,
int, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
extern int bounce_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
extern int bounce_one_intern(int, const char *, const char *, const char *,
- const char *, const char *,
+ int, const char *, const char *,
int, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
CLEANUP_FLAG_MAP_OK, "enable_address_mapping",
CLEANUP_FLAG_MILTER, "enable_milters",
CLEANUP_FLAG_SMTP_REPLY, "enable_smtp_reply",
+ CLEANUP_FLAG_SMTPUTF8, "smtputf8_requested",
};
/* cleanup_strflags - map flags code to printable string */
#define CLEANUP_FLAG_MAP_OK (1<<5) /* Ok to map addresses */
#define CLEANUP_FLAG_MILTER (1<<6) /* Enable Milter applications */
#define CLEANUP_FLAG_SMTP_REPLY (1<<7) /* Enable SMTP reply */
+#define CLEANUP_FLAG_SMTPUTF8 (1<<8) /* SMTPUTF8 requested */
+#define CLEANUP_FLAG_AUTOUTF8 (1<<9) /* Autodetect SMTPUTF8 */
#define CLEANUP_FLAG_FILTER_ALL (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_MILTER)
/*
/* const char *relay;
/* DSN *dsn;
/*
-/* int defer_flush(flags, queue, id, encoding, sender,
+/* int defer_flush(flags, queue, id, encoding, smtputf8, sender,
/* dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int defer_warn(flags, queue, id, encoding, sender,
-/* dsn_envid, dsn_ret)
+/* int defer_warn(flags, queue, id, encoding, smtputf8, sender,
+ dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int defer_one(flags, queue, id, encoding, sender, envid, ret,
-/* stats, recipient, relay, dsn)
+/* int defer_one(flags, queue, id, encoding, smtputf8, sender,
+/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
+/* int smtputf8;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* Delivery status. See dsn(3). The specified action is ignored.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
+/* .IP smtputf8
+/* The level of SMTPUTF8 support (to be defined).
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
/* defer_flush - flush the defer log and deliver to the sender */
int defer_flush(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret)
{
flags |= BOUNCE_FLAG_DELRCPT;
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
* do not flush the log */
int defer_warn(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *envid, int dsn_ret)
+ const char *encoding, int smtputf8,
+ const char *sender, const char *envid, int dsn_ret)
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
/* defer_one - defer mail for one recipient */
int defer_one(int flags, const char *queue, const char *id,
- const char *encoding, const char *sender,
- const char *dsn_envid, int dsn_ret,
- MSG_STATS *stats, RECIPIENT *rcpt,
+ const char *encoding, int smtputf8,
+ const char *sender, const char *dsn_envid,
+ int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
const char *relay, DSN *dsn)
{
DSN my_dsn = *dsn;
if (delivery_status_filter != 0
&& (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
if (dsn_res->status[0] == '5')
- return (bounce_one_intern(flags, queue, id, encoding, sender,
- dsn_envid, dsn_ret, stats, rcpt,
- relay, dsn_res));
+ return (bounce_one_intern(flags, queue, id, encoding, smtputf8,
+ sender, dsn_envid, dsn_ret, stats,
+ rcpt, relay, dsn_res));
my_dsn = *dsn_res;
}
return (defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
*/
extern int defer_append(int, const char *, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
-extern int defer_flush(int, const char *, const char *, const char *,
+extern int defer_flush(int, const char *, const char *, const char *, int,
const char *, const char *, int);
-extern int defer_warn(int, const char *, const char *, const char *,
+extern int defer_warn(int, const char *, const char *, const char *, int,
const char *, const char *, int);
-extern int defer_one(int, const char *, const char *, const char *,
+extern int defer_one(int, const char *, const char *, const char *, int,
const char *, const char *,
int, MSG_STATS *, RECIPIENT *,
const char *, DSN *);
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, request->data_size,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, request->encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, request->smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, request->sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, request->dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, request->dsn_ret,
static VSTRING *dsn_envid;
static RCPT_BUF *rcpt_buf;
int rcpt_count;
+ int smtputf8;
int dsn_ret;
/*
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, &request->data_size,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, &smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, address,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, &dsn_ret,
ATTR_TYPE_STR, MAIL_ATTR_LOG_IDENT, log_ident,
ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, rewrite_context,
ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, &rcpt_count,
- ATTR_TYPE_END) != 22) {
+ ATTR_TYPE_END) != 23) {
msg_warn("%s: error receiving common attributes", myname);
return (-1);
}
request->queue_id = mystrdup(vstring_str(queue_id));
request->nexthop = mystrdup(vstring_str(nexthop));
request->encoding = mystrdup(vstring_str(encoding));
+ /* Fix 20140708: dedicated smtputf8 attribute with its own flags. */
+ request->smtputf8 = smtputf8;
request->sender = mystrdup(vstring_str(address));
request->client_name = mystrdup(vstring_str(client_name));
request->client_addr = mystrdup(vstring_str(client_addr));
long data_size; /* message size */
char *nexthop; /* next hop name */
char *encoding; /* content encoding */
+ int smtputf8; /* SMTPUTF8 level */
char *sender; /* envelope sender */
MSG_STATS msg_stats; /* time profile */
RECIPIENT_LIST rcpt_list; /* envelope recipients */
/*
* Don't frustrate future attempts to make Postfix UTF-8 transparent.
*/
- if (!valid_utf_8(name, strlen(name))) {
+ if (!valid_utf8_string(name, strlen(name))) {
if (msg_verbose)
msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'",
myname, dict_ldap->parser->name, name);
/*
* Don't frustrate future attempts to make Postfix UTF-8 transparent.
*/
- if (!valid_utf_8(name, strlen(name))) {
+ if (!valid_utf8_string(name, strlen(name))) {
if (msg_verbose)
msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'",
myname, dict_sqlite->parser->name, name);
/* #define EHLO_MASK_XFORWARD (1<<9)
/* #define EHLO_MASK_ENHANCEDSTATUSCODES (1<<10)
/* #define EHLO_MASK_DSN (1<<11)
+/* #define EHLO_MASK_SMTPUTF8 (1<<12)
/* #define EHLO_MASK_SILENT (1<<15)
/*
/* int ehlo_mask(keyword_list)
"STARTTLS", EHLO_MASK_STARTTLS,
"ENHANCEDSTATUSCODES", EHLO_MASK_ENHANCEDSTATUSCODES,
"DSN", EHLO_MASK_DSN,
+ "EHLO_MASK_SMTPUTF8", EHLO_MASK_SMTPUTF8,
"SILENT-DISCARD", EHLO_MASK_SILENT, /* XXX In-band signaling */
0,
};
#define EHLO_MASK_XFORWARD (1<<9)
#define EHLO_MASK_ENHANCEDSTATUSCODES (1<<10)
#define EHLO_MASK_DSN (1<<11)
+#define EHLO_MASK_SMTPUTF8 (1<<12)
#define EHLO_MASK_SILENT (1<<15)
extern int ehlo_mask(const char *);
/* the internal_mail_filter_classes configuration parameter.
/*
/* Specify one of the following:
-/* .IP INT_FILT_MASK_NONE
-/* Mail that must be excluded from inspection (address probes, etc.).
-/* .IP INT_FILT_MASK_NOTIFY
+/* .IP MAIL_SRC_MASK_NOTIFY
/* Postmaster notifications from the smtpd(8) and smtp(8)
/* protocol adapters.
-/* .IP INT_FILT_MASK_BOUNCE
+/* .IP MAIL_SRC_MASK_BOUNCE
/* Delivery status notifications from the bounce(8) server.
+/* .PP
+/* Other MAIL_SRC_MASK_XXX arguments are permited but will
+/* have no effect.
/* DIAGNOSTICS
/* Fatal: invalid mail category name.
/* LICENSE
#include <mail_params.h>
#include <cleanup_user.h>
+#include <mail_proto.h>
#include <int_filt.h>
/* int_filt_flags - map mail class to submission flags */
int int_filt_flags(int class)
{
static const NAME_MASK table[] = {
- INT_FILT_CLASS_NOTIFY, INT_FILT_MASK_NOTIFY,
- INT_FILT_CLASS_BOUNCE, INT_FILT_MASK_BOUNCE,
+ MAIL_SRC_NAME_NOTIFY, MAIL_SRC_MASK_NOTIFY,
+ MAIL_SRC_NAME_BOUNCE, MAIL_SRC_MASK_BOUNCE,
+ MAIL_SRC_NAME_SENDMAIL, 0,
+ MAIL_SRC_NAME_SMTPD, 0,
+ MAIL_SRC_NAME_QMQPD, 0,
+ MAIL_SRC_NAME_FORWARD, 0,
+ MAIL_SRC_NAME_VERIFY, 0,
0,
};
int filtered_classes = 0;
/* bool var_long_queue_ids;
/* bool var_daemon_open_fatal;
/* char *var_dsn_filter;
+/* int var_smtputf8_enable
+/* int var_strict_smtputf8;
+/* char *var_smtputf8_autoclass;
/*
/* void mail_params_init()
/*
bool var_long_queue_ids;
bool var_daemon_open_fatal;
char *var_dsn_filter;
+int var_smtputf8_enable;
+int var_strict_smtputf8;
+char *var_smtputf8_autoclass;
const char null_format_string[1] = "";
/* multi_instance_wrapper may have dependencies but not dependents. */
VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
VAR_DSN_FILTER, DEF_DSN_FILTER, &var_dsn_filter, 0, 0,
+ VAR_SMTPUTF8_AUTOCLASS, DEF_SMTPUTF8_AUTOCLASS, &var_smtputf8_autoclass, 1, 0,
0,
};
static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid,
VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable,
VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids,
+ VAR_SMTPUTF8_ENABLE, DEF_SMTPUTF8_ENABLE, &var_smtputf8_enable,
+ VAR_STRICT_SMTPUTF8, DEF_STRICT_SMTPUTF8, &var_strict_smtputf8,
0,
};
const char *cp;
dict_db_cache_size = var_db_read_buf;
dict_lmdb_map_size = var_lmdb_map_size;
inet_windowsize = var_inet_windowsize;
+ temp_utf8_kludge = var_smtputf8_enable;
+
+ /*
+ * Report run-time versus compile-time discrepancies.
+ */
+#ifdef NO_IDNA
+ if (var_smtputf8_enable)
+ msg_warn("%s is true, but EAI support is not compiled in",
+ VAR_SMTPUTF8_ENABLE);
+#endif
/*
* Variables whose defaults are determined at runtime, after other
#endif
extern char *var_meta_dir;
+ /*
+ * SMTPUTF8 support.
+ */
+#define VAR_SMTPUTF8_ENABLE "smtputf8_enable"
+#define DEF_SMTPUTF8_ENABLE 0
+extern int var_smtputf8_enable;
+
+#define VAR_STRICT_SMTPUTF8 "strict_smtputf8"
+#define DEF_STRICT_SMTPUTF8 0
+extern int var_strict_smtputf8;
+
+#define VAR_SMTPUTF8_AUTOCLASS "smtputf8_autodetect_classes"
+#define DEF_SMTPUTF8_AUTOCLASS MAIL_SRC_NAME_SENDMAIL ", " \
+ MAIL_SRC_NAME_VERIFY
+extern char *var_smtputf8_autoclass;
+
/* LICENSE
/* .ad
/* .fi
#define MAIL_SERVICE_DNSBLOG "dnsblog"
#define MAIL_SERVICE_TLSPROXY "tlsproxy"
+ /*
+ * Mail source classes. Used to specify policy decisions for content
+ * inspection and SMTPUTF8 detection.
+ */
+#define MAIL_SRC_NAME_SENDMAIL "sendmail" /* sendmail(1) */
+#define MAIL_SRC_NAME_SMTPD "smtpd" /* smtpd(8) */
+#define MAIL_SRC_NAME_QMQPD "qmqpd" /* qmqpd(8) */
+#define MAIL_SRC_NAME_FORWARD "forward" /* local(8) forward/alias */
+#define MAIL_SRC_NAME_BOUNCE "bounce"/* bounce(8) */
+#define MAIL_SRC_NAME_NOTIFY "notify"/* protocol etc. errors */
+#define MAIL_SRC_NAME_VERIFY "verify"/* protocol etc. errors */
+#define MAIL_SRC_NAME_ALL "all" /* all sources */
+
+#define MAIL_SRC_MASK_SENDMAIL (1<<0) /* sendmail(1) */
+#define MAIL_SRC_MASK_SMTPD (1<<1) /* smtpd(8) */
+#define MAIL_SRC_MASK_QMQPD (1<<2) /* qmqpd(8) */
+#define MAIL_SRC_MASK_FORWARD (1<<3) /* local(8) forward/alias */
+#define MAIL_SRC_MASK_BOUNCE (1<<4) /* bounce(8) */
+#define MAIL_SRC_MASK_NOTIFY (1<<5) /* protocol etc. errors */
+#define MAIL_SRC_MASK_VERIFY (1<<6) /* protocol etc. errors */
+
+#define MAIL_SRC_MASK_ALL \
+ ( MAIL_SRC_MASK_SENDMAIL | MAIL_SRC_MASK_SMTPD \
+ | MAIL_SRC_MASK_QMQPD | MAIL_SRC_MASK_FORWARD \
+ | MAIL_SRC_MASK_BOUNCE | MAIL_SRC_MASK_NOTIFY)
+
/*
* Well-known socket or FIFO directories. The main difference is in file
* access permissions.
#define MAIL_ATTR_DSN_RET "ret_flags" /* dsn full/headers */
#define MAIL_ATTR_DSN_NOTIFY "notify_flags" /* dsn notify flags */
#define MAIL_ATTR_DSN_ORCPT "dsn_orig_rcpt" /* dsn original recipient */
+#define MAIL_ATTR_SMTPUTF8 "smtputf8" /* RFC6531 support */
/*
* TLSPROXY support.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20140709"
+#define MAIL_RELEASE_DATE "20140713"
#define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT
/* .IP MIME_OPT_REPORT_NESTING
/* Report errors that set the MIME_ERR_NESTING error flag
/* (see above).
-/* .IP MIME_OPT_RECURSE_ALL_MESSAGE
-/* Recurse into message/anything types other than message/rfc822.
-/* This feature can detect "bad" information in headers of
-/* message/partial and message/external-body types. It must
-/* not be used with 8-bit -> 7-bit MIME transformations.
/* .IP MIME_OPT_DOWNGRADE
/* Transform content that claims to be 8-bit into quoted-printable.
/* Where appropriate, update Content-Transfer-Encoding: message
#define MIME_STYPE_RFC822 2
#define MIME_STYPE_PARTIAL 3
#define MIME_STYPE_EXTERN_BODY 4
+#define MIME_STYPE_GLOBAL 5
/*
* MIME parser states. We steal from the public interface.
state->curr_stype = MIME_STYPE_PARTIAL;
else if (TOKEN_MATCH(state->token[2], "external-body"))
state->curr_stype = MIME_STYPE_EXTERN_BODY;
+ else if (TOKEN_MATCH(state->token[2], "global"))
+ state->curr_stype = MIME_STYPE_GLOBAL;
}
return;
}
if (len == 0) {
state->body_offset = 0; /* XXX */
if (state->curr_ctype == MIME_CTYPE_MESSAGE) {
- if (state->curr_stype == MIME_STYPE_RFC822
- || (state->static_flags & MIME_OPT_RECURSE_ALL_MESSAGE))
+ if (state->curr_stype == MIME_STYPE_RFC822)
+ SET_MIME_STATE(state, MIME_STATE_NESTED,
+ MIME_CTYPE_TEXT, MIME_STYPE_PLAIN,
+ MIME_ENC_7BIT, MIME_ENC_7BIT);
+ else if (state->curr_stype == MIME_STYPE_GLOBAL
+ && ((state->static_flags & MIME_OPT_DOWNGRADE) == 0
+ || state->curr_domain == MIME_ENC_7BIT))
+ /* XXX EAI: inspect encoded message/global. */
SET_MIME_STATE(state, MIME_STATE_NESTED,
MIME_CTYPE_TEXT, MIME_STYPE_PLAIN,
MIME_ENC_7BIT, MIME_ENC_7BIT);
/* SYNOPSIS
/* #include <post_mail.h>
/*
-/* VSTREAM *post_mail_fopen(sender, recipient, filter_class, trace_flags,
+/* VSTREAM *post_mail_fopen(sender, recipient, source_class, trace_flags,
/* queue_id)
/* const char *sender;
/* const char *recipient;
-/* int filter_class;
+/* int source_class;
/* int trace_flags;
/* VSTRING *queue_id;
/*
/* VSTREAM *post_mail_fopen_nowait(sender, recipient,
-/* filter_class, trace_flags, queue_id)
+/* source_class, trace_flags, queue_id)
/* const char *sender;
/* const char *recipient;
-/* int filter_class;
+/* int source_class;
/* int trace_flags;
/* VSTRING *queue_id;
/*
/* void post_mail_fopen_async(sender, recipient,
-/* filter_class, trace_flags,
+/* source_class, trace_flags,
/* queue_id, notify, context)
/* const char *sender;
/* const char *recipient;
-/* int filter_class;
+/* int source_class;
/* int trace_flags;
/* VSTRING *queue_id;
/* void (*notify)(VSTREAM *stream, char *context);
/* .IP recipient
/* The recipient envelope address. It is up to the application
/* to produce To: headers.
-/* .IP filter_class
-/* The internal mail filtering class, as defined in
-/* \fB<int_filt.h>\fR. Depending on the setting of the
-/* internal_mail_filter_classes parameter the message will or
-/* won't be subject to content inspection.
+/* .IP source_class
+/* The message source class, as defined in \fB<mail_proto.h>\fR.
+/* Depending on the setting of the internal_mail_source_classes
+/* and smtputf8_autodetect_classes parameters, the message
+/* will or won't be subject to content inspection or SMTPUTF8
+/* autodetection.
/* .IP trace_flags
/* Message tracing flags as specified in \fB<deliver_request.h>\fR.
/* .IP queue_id
typedef struct {
char *sender;
char *recipient;
- int filter_class;
+ int source_class;
int trace_flags;
POST_MAIL_NOTIFY notify;
void *context;
static void post_mail_init(VSTREAM *stream, const char *sender,
const char *recipient,
- int filter_class, int trace_flags,
+ int source_class, int trace_flags,
VSTRING *queue_id)
{
VSTRING *id = queue_id ? queue_id : vstring_alloc(100);
struct timeval now;
const char *date;
- int cleanup_flags =
- int_filt_flags(filter_class) | CLEANUP_FLAG_MASK_INTERNAL;
+ int cleanup_flags =
+ int_filt_flags(source_class) | CLEANUP_FLAG_MASK_INTERNAL
+ | smtputf8_autodetect(source_class);
GETTIMEOFDAY(&now);
date = mail_date(now.tv_sec);
/* post_mail_fopen - prepare for posting a message */
VSTREAM *post_mail_fopen(const char *sender, const char *recipient,
- int filter_class, int trace_flags,
+ int source_class, int trace_flags,
VSTRING *queue_id)
{
VSTREAM *stream;
stream = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
- post_mail_init(stream, sender, recipient, filter_class, trace_flags,
+ post_mail_init(stream, sender, recipient, source_class, trace_flags,
queue_id);
return (stream);
}
/* post_mail_fopen_nowait - prepare for posting a message */
VSTREAM *post_mail_fopen_nowait(const char *sender, const char *recipient,
- int filter_class, int trace_flags,
+ int source_class, int trace_flags,
VSTRING *queue_id)
{
VSTREAM *stream;
if ((stream = mail_connect(MAIL_CLASS_PUBLIC, var_cleanup_service,
BLOCKING)) != 0)
- post_mail_init(stream, sender, recipient, filter_class, trace_flags,
+ post_mail_init(stream, sender, recipient, source_class, trace_flags,
queue_id);
return (stream);
}
event_disable_readwrite(vstream_fileno(state->stream));
non_blocking(vstream_fileno(state->stream), BLOCKING);
post_mail_init(state->stream, state->sender,
- state->recipient, state->filter_class,
+ state->recipient, state->source_class,
state->trace_flags, state->queue_id);
myfree(state->sender);
myfree(state->recipient);
/* post_mail_fopen_async - prepare for posting a message */
void post_mail_fopen_async(const char *sender, const char *recipient,
- int filter_class, int trace_flags,
+ int source_class, int trace_flags,
VSTRING *queue_id,
void (*notify) (VSTREAM *, void *),
void *context)
state = (POST_MAIL_STATE *) mymalloc(sizeof(*state));
state->sender = mystrdup(sender);
state->recipient = mystrdup(recipient);
- state->filter_class = filter_class;
+ state->source_class = source_class;
state->trace_flags = trace_flags;
state->notify = notify;
state->context = context;
* Global library.
*/
#include <cleanup_user.h>
-#include <int_filt.h>
+#include <mail_proto.h>
/*
* External interface.
*
* See also: REC_TYPE_PTR_FORMAT below.
*/
-#define REC_TYPE_SIZE_FORMAT "%15ld %15ld %15ld %15ld %15ld"
+#define REC_TYPE_SIZE_FORMAT "%15ld %15ld %15ld %15ld %15ld %15ld"
#define REC_TYPE_SIZE_CAST1 long /* Vmailer extra offs - data offs */
#define REC_TYPE_SIZE_CAST2 long /* Postfix 1.0 data offset */
#define REC_TYPE_SIZE_CAST3 long /* Postfix 1.0 recipient count */
#define REC_TYPE_SIZE_CAST4 long /* Postfix 2.1 qmgr flags */
#define REC_TYPE_SIZE_CAST5 long /* Postfix 2.4 content length */
+#define REC_TYPE_SIZE_CAST6 long /* Postfix 2.12 smtputf8 flags */
/*
* The warn record specifies when the next warning that the message was
--- /dev/null
+/*++
+/* NAME
+/* smtputf8 3
+/* SUMMARY
+/* SMTPUTF8 support
+/* SYNOPSIS
+/* #include <smtputf8.h>
+/*
+/* int smtputf8_autodetect(class)
+/* int class;
+/* DESCRIPTION
+/* smtputf8_autodetect() determines whether the cleanup server
+/* should perform SMTPUTF8 detection, depending on the declared
+/* source class and the setting of the smtputf8_autodetect_classes
+/* configuration parameter.
+/*
+/* Specify one of the following:
+/* .IP MAIL_SRC_MASK_SENDMAIL
+/* Submission with the Postfix sendmail(1) command.
+/* .IP MAIL_SRC_MASK_SMTPD
+/* Mail received with the smtpd(8) daemon.
+/* .IP MAIL_SRC_MASK_QMQPD
+/* Mail received with the qmqpd(8) daemon.
+/* .IP MAIL_SRC_MASK_FORWARD
+/* Local forwarding or aliasing.
+/* .IP MAIL_SRC_MASK_BOUNCE
+/* Submission by the bounce(8) daemon.
+/* .IP MAIL_SRC_MASK_NOTIFY
+/* Postmaster notification from the smtp(8) or smtpd(8) daemon.
+/* .IP MAIL_SRC_MASK_VERIFY
+/* Address verification probe.
+/* DIAGNOSTICS
+/* Panic: no valid class argument.
+/*
+/* Specify one of the following:
+/* Warning: the smtputf8_autodetect_classes parameter specifies
+/* an invalid source category name.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <name_mask.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <cleanup_user.h>
+#include <mail_proto.h>
+#include <smtputf8.h>
+
+/* smtputf8_autodetect - enable SMTPUTF8 autodetection */
+
+int smtputf8_autodetect(int class)
+{
+ const char myname[] = "smtputf8_autodetect";
+ static const NAME_MASK table[] = {
+ MAIL_SRC_NAME_SENDMAIL, MAIL_SRC_MASK_SENDMAIL,
+ MAIL_SRC_NAME_SMTPD, MAIL_SRC_MASK_SMTPD,
+ MAIL_SRC_NAME_QMQPD, MAIL_SRC_MASK_QMQPD,
+ MAIL_SRC_NAME_FORWARD, MAIL_SRC_MASK_FORWARD,
+ MAIL_SRC_NAME_BOUNCE, MAIL_SRC_MASK_BOUNCE,
+ MAIL_SRC_NAME_NOTIFY, MAIL_SRC_MASK_NOTIFY,
+ MAIL_SRC_NAME_VERIFY, MAIL_SRC_MASK_VERIFY,
+ MAIL_SRC_NAME_ALL, MAIL_SRC_MASK_ALL,
+ 0,
+ };
+ int autodetect_classes = 0;
+
+ if (class == 0 || (class & ~MAIL_SRC_MASK_ALL) != 0)
+ msg_panic("%s: bad source class: %d", myname, class);
+ if (*var_smtputf8_autoclass) {
+ autodetect_classes =
+ name_mask(VAR_SMTPUTF8_AUTOCLASS, table, var_smtputf8_autoclass);
+ if (autodetect_classes == 0)
+ msg_warn("%s: bad input: %s", VAR_SMTPUTF8_AUTOCLASS,
+ var_smtputf8_autoclass);
+ if (autodetect_classes & class)
+ return (CLEANUP_FLAG_AUTOUTF8);
+ }
+ return (0);
+}
--- /dev/null
+#ifndef _SMTPUTF8_H_INCLUDED_
+#define _SMTPUTF8_H_INCLUDED_
+
+/*++
+/* NAME
+/* smtputf8 3h
+/* SUMMARY
+/* SMTPUTF8 support
+/* SYNOPSIS
+/* #include <smtputf8.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Avoiding chicken-and-egg problems during the initial SMTPUTF8 roll-out in
+ * environments with pre-existing mail flows that contain UTF8.
+ *
+ * Prior to SMTPUTF8, mail flows that contain UTF8 worked because the vast
+ * majority of MTAs is perfectly capable of handling UTF8 in addres
+ * localparts (and in headers), even if pre-SMTPUTF8 standards do not
+ * support this practice.
+ *
+ * When turning on Postfix SMTPUTF8 support for the first time, we don't want
+ * to suddenly break pre-existing mail flows that contain UTF8 because 1) a
+ * client does not request SMTPUTF8 support, and because 2) a down-stream
+ * MTA does not announce SMTPUTF8 support.
+ *
+ * While 1) is easy enough to avoid (keep accepting UTF8 in addres localparts
+ * just like Postfix has always done), 2) presents a thornier problem. The
+ * root cause of that problem is the need for SMTPUTF8 autodetection.
+ *
+ * What is SMTPUTF8 autodetection? Postfix cannot rely solely on the sender's
+ * declaration that a message requires SMTPUTF8 support, because UTF8 may be
+ * introduced during local processing (for example, the client hostname in
+ * Postfix's Received: header, adding @$myorigin or .$mydomain to an
+ * incomplete address, address rewriting, alias expansion, automatic BCC
+ * recipients, local forwarding, and changes made by header checks or Milter
+ * applications).
+ *
+ * In summary, after local processing has happened, Postfix may decide that a
+ * message requires SMTPUTF8 support, even when that message initially did
+ * not require SMTPUTF8 support. This could make the message undeliverable
+ * to destinations that do not support SMTPUTF8. In an environment with
+ * pre-existing mail flows that contain UTF8, we want to avoid disrupting
+ * those mail flows when rolling out SMTPUTF8 support.
+ *
+ * For the vast majority of sites, the simplest solution is to autodetect
+ * SMTPUTF8 support only for Postfix sendmail command-line submissions, at
+ * least as long as SMTPUTF8 support has not yet achieved wold domination.
+ *
+ * However, sites that add UTF8 content via local processing (see above) should
+ * autodetect SMTPUTF8 support for all email.
+ *
+ * smtputf8_autodetect() uses the setting of the smtputf8_autodetect_classes
+ * parameter, and the mail source classes defined in mail_params.h.
+ */
+extern int smtputf8_autodetect(int);
+
+ /*
+ * The flag SMTPUTF8_FLAG_REQUESTED is raised on request by the sender, or
+ * when a queue file contains at least one UTF8 envelope recipient.
+ *
+ * The flag SMTPUTF8_FLAG_HEADER is raised when a queue file contains at least
+ * one UTF8 message header.
+ *
+ * The flag SMTPUTF8_FLAG_SENDER is raised when a queue file contains an UTF8
+ * envelope sender.
+ *
+ * The three flags SMTPUTF8_FLAG_REQUESTED/HEADER/SENDER are stored in the
+ * queue file, the three flags are sent with delivery requests to Postfix
+ * delivery agents, and the three flags are sent with "flush" requests to
+ * the bounce daemon to ensure that the resulting notification message will
+ * have a content-transfer-encoding of 8bit.
+ *
+ * In the near future, mailing lists will have a mix of UTF8 and non-UTF8
+ * subscribers. With the following flag, Postfix can require SMTPUTF8
+ * delivery only when it is really required.
+ *
+ * The flag SMTPUTF8_FLAG_RECIPIENT is raised when a delivery request (NOT:
+ * message) contains at least one UTF8 envelope recipient. The flag is NOT
+ * stored in the queue file, and the flag sent in requests to the bounce
+ * daemon ONLY when bouncing a single recipient. The flag is used ONLY in
+ * requests to Postfix delivery agents, to give Postfix flexibility when
+ * delivering messages to non-SMTPUTF8 servers.
+ *
+ * If a delivery request has none of the flags SMTPUTF8_FLAG_RECIPIENT,
+ * SMTPUTF8_FLAG_SENDER, or SMTPUTF8_FLAG_HEADER, then the message can
+ * safely be delivered to a non-SMTPUTF8 server.
+ *
+ * To relax this requirement, implement RFC2047 header encoding in the Postfix
+ * SMTP client, and adjust the SMTPUTF8_MASK_ALWAYS macro.
+ */
+#define SMTPUTF8_FLAG_REQUESTED (1<<0) /* queue file/delivery/bounce request */
+#define SMTPUTF8_FLAG_HEADER (1<<1) /* queue file/delivery/bounce request */
+#define SMTPUTF8_FLAG_SENDER (1<<2) /* queue file/delivery/bounce request */
+#define SMTPUTF8_FLAG_RECIPIENT (1<<3) /* delivery request only */
+
+#define SMTPUTF8_MASK_ALWAYS (SMTPUTF8_FLAG_HEADER | SMTPUTF8_FLAG_SENDER)
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* uxtext 3
+/* SUMMARY
+/* quote/unquote text, xtext style.
+/* SYNOPSIS
+/* #include <uxtext.h>
+/*
+/* VSTRING *uxtext_quote(quoted, unquoted, special)
+/* VSTRING *quoted;
+/* const char *unquoted;
+/* const char *special;
+/*
+/* VSTRING *uxtext_quote_append(unquoted, quoted, special)
+/* VSTRING *unquoted;
+/* const char *quoted;
+/* const char *special;
+/*
+/* VSTRING *uxtext_unquote(unquoted, quoted)
+/* VSTRING *unquoted;
+/* const char *quoted;
+/*
+/* VSTRING *uxtext_unquote_append(unquoted, quoted)
+/* VSTRING *unquoted;
+/* const char *quoted;
+/* DESCRIPTION
+/* uxtext_quote() takes a null-terminated UTF8 string and
+/* replaces characters \, <33(10) and >126(10), as well as
+/* characters specified with "special" with \x{XX}, XX being
+/* a 2-6-digit uppercase hexadecimal equivalent.
+/*
+/* uxtext_quote_append() is like uxtext_quote(), but appends
+/* the conversion result to the result buffer.
+/*
+/* uxtext_unquote() performs the opposite transformation. This
+/* function understands lowercase, uppercase, and mixed case
+/* \x{XX...} sequences. The result value is the unquoted
+/* argument in case of success, a null pointer otherwise.
+/*
+/* uxtext_unquote_append() is like uxtext_unquote(), but appends
+/* the conversion result to the result buffer.
+/* BUGS
+/* This module cannot process null characters in data.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Arnt Gulbrandsen
+/*
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Utility library. */
+
+#include "msg.h"
+#include "vstring.h"
+#include "uxtext.h"
+
+/* Application-specific. */
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/* uxtext_quote_append - append unquoted data to quoted data */
+
+VSTRING *uxtext_quote_append(VSTRING *quoted, const char *unquoted,
+ const char *special)
+{
+ unsigned const char *cp;
+ int ch;
+
+ for (cp = (unsigned const char *) unquoted; (ch = *cp) != 0; cp++) {
+ /* Fix 20140709: the '\' character must always be quoted. */
+ if (ch != '\\' && ch > 32 && ch < 127
+ && (*special == 0 || strchr(special, ch) == 0)) {
+ VSTRING_ADDCH(quoted, ch);
+ } else {
+
+ /*
+ * had RFC6533 been written like 6531 and 6532, this else clause
+ * would be one line long.
+ */
+ int unicode = 0;
+ int pick = 0;
+
+ if (ch < 0x80) {
+ //0000 0000 - 0000 007 F 0x xxxxxx
+ unicode = ch;
+ } else if ((ch & 0xe0) == 0xc0) {
+ //0000 0080 - 0000 07 FF 110 xxxxx 10 xxxxxx
+ unicode = (ch & 0x1f);
+ pick = 1;
+ } else if ((ch & 0xf0) == 0xe0) {
+ //0000 0800 - 0000 FFFF 1110 xxxx 10 xxxxxx 10 xxxxxx
+ unicode = (ch & 0x0f);
+ pick = 2;
+ } else if ((ch & 0xf8) == 0xf0) {
+ //0001 0000 - 001 F FFFF 11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
+ unicode = (ch & 0x07);
+ pick = 3;
+ } else if ((ch & 0xfc) == 0xf8) {
+ //0020 0000 - 03 FF FFFF 111110 xx 10 xxxxxx 10 xxxxxx...10 xxxxxx
+ unicode = (ch & 0x03);
+ pick = 4;
+ } else if ((ch & 0xfe) == 0xfc) {
+ //0400 0000 - 7 FFF FFFF 1111110 x 10 xxxxxx...10 xxxxxx
+ unicode = (ch & 0x01);
+ pick = 5;
+ } else {
+ return (0);
+ }
+ while (pick > 0) {
+ ch = *++cp;
+ if ((ch & 0xc0) != 0x80)
+ return (0);
+ unicode = unicode << 6 | (ch & 0x3f);
+ pick--;
+ }
+ vstring_sprintf_append(quoted, "\\x{%02X}", unicode);
+ }
+ }
+ VSTRING_TERMINATE(quoted);
+ return (quoted);
+}
+
+/* uxtext_quote - unquoted data to quoted */
+
+VSTRING *uxtext_quote(VSTRING *quoted, const char *unquoted, const char *special)
+{
+ VSTRING_RESET(quoted);
+ uxtext_quote_append(quoted, unquoted, special);
+ return (quoted);
+}
+
+/* uxtext_unquote_append - quoted data to unquoted */
+
+VSTRING *uxtext_unquote_append(VSTRING *unquoted, const char *quoted)
+{
+ const char *cp;
+ int ch;
+
+ for (cp = quoted; (ch = *cp) != 0; cp++) {
+ if (ch == '\\' && cp[1] == 'x' && cp[2] == '{') {
+ cp += 2;
+ int unicode = 0;
+
+ while ((ch = *++cp) != '}') {
+ if (ISDIGIT(ch))
+ unicode = (unicode << 4) + (ch - '0');
+ else if (ch >= 'a' && ch <= 'f')
+ unicode = (unicode << 4) + (ch - 'a' + 10);
+ else if (ch >= 'A' && ch <= 'F')
+ unicode = (unicode << 4) + (ch - 'A' + 10);
+ else
+ return (0); /* also covers the null
+ * terminator */
+ if (unicode > 0x10ffff)
+ return (0);
+ }
+
+ /*
+ * the following block is from
+ * https://github.com/aox/aox/blob/master/encodings/utf.cpp, with
+ * permission by the authors.
+ */
+ if (unicode < 0x80) {
+ VSTRING_ADDCH(unquoted, (char) unicode);
+ } else if (unicode < 0x800) {
+ VSTRING_ADDCH(unquoted, 0xc0 | ((char) (unicode >> 6)));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode & 0x3f)));
+ } else if (unicode < 0x10000) {
+ VSTRING_ADDCH(unquoted, 0xe0 | ((char) (unicode >> 12)));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 6) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode & 0x3f)));
+ } else if (unicode < 0x200000) {
+ VSTRING_ADDCH(unquoted, 0xf0 | ((char) (unicode >> 18)));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 12) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 6) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode & 0x3f)));
+ } else if (unicode < 0x4000000) {
+ VSTRING_ADDCH(unquoted, 0xf8 | ((char) (unicode >> 24)));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 18) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 12) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 6) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode & 0x3f)));
+ } else {
+ VSTRING_ADDCH(unquoted, 0xfc | ((char) (unicode >> 30)));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 24) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 18) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 12) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode >> 6) & 0x3f));
+ VSTRING_ADDCH(unquoted, 0x80 | ((char) (unicode & 0x3f)));
+ }
+ } else {
+ VSTRING_ADDCH(unquoted, ch);
+ }
+ }
+ VSTRING_TERMINATE(unquoted);
+ return (unquoted);
+}
+
+/* uxtext_unquote - quoted data to unquoted */
+
+VSTRING *uxtext_unquote(VSTRING *unquoted, const char *quoted)
+{
+ VSTRING_RESET(unquoted);
+ uxtext_unquote_append(unquoted, quoted);
+ return (unquoted);
+}
+
+#ifdef TEST
+
+ /*
+ * Proof-of-concept test program: convert to quoted and back.
+ */
+#include <vstream.h>
+
+#define BUFLEN 1024
+
+static ssize_t read_buf(VSTREAM *fp, VSTRING *buf)
+{
+ ssize_t len;
+
+ VSTRING_RESET(buf);
+ len = vstream_fread(fp, STR(buf), vstring_avail(buf));
+ VSTRING_AT_OFFSET(buf, len); /* XXX */
+ VSTRING_TERMINATE(buf);
+ return (len);
+}
+
+int main(int unused_argc, char **unused_argv)
+{
+ VSTRING *unquoted = vstring_alloc(BUFLEN);
+ VSTRING *quoted = vstring_alloc(100);
+ ssize_t len;
+
+ while ((len = read_buf(VSTREAM_IN, unquoted)) > 0) {
+ uxtext_quote(quoted, STR(unquoted), "+=");
+ if (uxtext_unquote(unquoted, STR(quoted)) == 0)
+ msg_fatal("bad input: %.100s", STR(quoted));
+ if (LEN(unquoted) != len)
+ msg_fatal("len %ld != unquoted len %ld",
+ (long) len, (long) LEN(unquoted));
+ if (vstream_fwrite(VSTREAM_OUT, STR(unquoted), LEN(unquoted)) != LEN(unquoted))
+ msg_fatal("write error: %m");
+ }
+ vstream_fflush(VSTREAM_OUT);
+ vstring_free(unquoted);
+ vstring_free(quoted);
+ return (0);
+}
+
+#endif
--- /dev/null
+#ifndef _UXTEXT_H_INCLUDED_
+#define _UXTEXT_H_INCLUDED_
+
+/*++
+/* NAME
+/* uxtext 3h
+/* SUMMARY
+/* quote/unquote text, RFC 6533 style.
+/* SYNOPSIS
+/* #include <uxtext.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <vstring.h>
+
+ /*
+ * External interface.
+ */
+extern VSTRING *uxtext_quote(VSTRING *, const char *, const char *);
+extern VSTRING *uxtext_quote_append(VSTRING *, const char *, const char *);
+extern VSTRING *uxtext_unquote(VSTRING *, const char *);
+extern VSTRING *uxtext_unquote_append(VSTRING *, const char *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
forward.o: ../../include/record.h
forward.o: ../../include/resolve_clnt.h
forward.o: ../../include/sent.h
+forward.o: ../../include/smtputf8.h
forward.o: ../../include/stringops.h
forward.o: ../../include/sys_defs.h
forward.o: ../../include/tok822.h
#include <mail_date.h>
#include <mail_params.h>
#include <dsn_mask.h>
+#include <smtputf8.h>
/* Application-specific. */
info->queue_id = mystrdup(STR(buffer));
GETTIMEOFDAY(&info->posting_time);
-#define FORWARD_CLEANUP_FLAGS (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_INTERNAL)
+#define FORWARD_CLEANUP_FLAGS \
+ (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_INTERNAL \
+ | smtputf8_autodetect(MAIL_SRC_MASK_FORWARD))
attr_print(cleanup, ATTR_FLAG_NONE,
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, FORWARD_CLEANUP_FLAGS,
state.msg_attr.fp = rqst->fp;
state.msg_attr.offset = rqst->data_offset;
state.msg_attr.encoding = rqst->encoding;
+ state.msg_attr.smtputf8 = rqst->smtputf8;
state.msg_attr.sender = rqst->sender;
state.msg_attr.dsn_envid = rqst->dsn_envid;
state.msg_attr.dsn_ret = rqst->dsn_ret;
char *queue_id; /* mail queue id */
long offset; /* data offset */
char *encoding; /* MIME encoding */
+ int smtputf8; /* from delivery request */
const char *sender; /* taken from envelope */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
DSN_FROM_DSN_BUF(attr.why)
#define BOUNCE_ONE_ATTR(attr) \
- attr.queue_name, attr.queue_id, attr.encoding, \
+ attr.queue_name, attr.queue_id, attr.encoding, attr.smtputf8, \
attr.sender, attr.dsn_envid, attr.dsn_ret, \
&attr.msg_stats, &attr.rcpt, attr.relay, \
DSN_FROM_DSN_BUF(attr.why)
event_server.o: ../../include/dict.h
event_server.o: ../../include/dsn.h
event_server.o: ../../include/dsn_buf.h
-event_server.o: ../../include/dsn_filter.h
event_server.o: ../../include/events.h
event_server.o: ../../include/htable.h
event_server.o: ../../include/iostuff.h
multi_server.o: ../../include/dict.h
multi_server.o: ../../include/dsn.h
multi_server.o: ../../include/dsn_buf.h
-multi_server.o: ../../include/dsn_filter.h
multi_server.o: ../../include/events.h
multi_server.o: ../../include/htable.h
multi_server.o: ../../include/iostuff.h
single_server.o: ../../include/dict.h
single_server.o: ../../include/dsn.h
single_server.o: ../../include/dsn_buf.h
-single_server.o: ../../include/dsn_filter.h
single_server.o: ../../include/events.h
single_server.o: ../../include/htable.h
single_server.o: ../../include/iostuff.h
trigger_server.o: ../../include/dict.h
trigger_server.o: ../../include/dsn.h
trigger_server.o: ../../include/dsn_buf.h
-trigger_server.o: ../../include/dsn_filter.h
trigger_server.o: ../../include/events.h
trigger_server.o: ../../include/htable.h
trigger_server.o: ../../include/iostuff.h
qmgr_deliver.o: ../../include/rcpt_print.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/scan_dir.h
+qmgr_deliver.o: ../../include/smtputf8.h
qmgr_deliver.o: ../../include/stringops.h
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_deliver.o: ../../include/vbuf.h
char *sender; /* complete address */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
+ int smtputf8; /* requires unicode */
char *verp_delims; /* VERP delimiters */
char *filter_xport; /* filtering transport */
char *inspect_xport; /* inspecting transport */
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
#include <dsn_buf.h>
#include <dsb_scan.h>
#include <rcpt_print.h>
+#include <smtputf8.h>
/* Application-specific. */
MSG_STATS stats;
char *sender;
int flags;
+ int smtputf8 = message->smtputf8;
+ const char *addr;
+
+ /*
+ * Todo: integrate with code up-stream that builds the delivery request.
+ */
+ for (recipient = list.info; recipient < list.info + list.len; recipient++)
+ if (var_smtputf8_enable && (addr = recipient->address)[0]
+ && !allascii(addr) && valid_utf8_string(addr, strlen(addr)))
+ smtputf8 |= SMTPUTF8_FLAG_RECIPIENT;
/*
* If variable envelope return path is requested, change prefix+@origin
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->cont_length,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, entry->queue->nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, message->smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, message->dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, message->dsn_ret,
message->sender = 0;
message->dsn_envid = 0;
message->dsn_ret = 0;
+ message->smtputf8 = 0;
message->filter_xport = 0;
message->inspect_xport = 0;
message->redirect_addr = 0;
continue;
if (rec_type == REC_TYPE_SIZE) {
if (message->data_offset == 0) {
- if ((count = sscanf(start, "%ld %ld %d %d %ld",
+ if ((count = sscanf(start, "%ld %ld %d %d %ld %d",
&message->data_size, &message->data_offset,
&nrcpt, &message->rflags,
- &message->cont_length)) >= 3) {
+ &message->cont_length,
+ &message->smtputf8)) >= 3) {
/* Postfix >= 1.0 (a.k.a. 20010228). */
if (message->data_offset <= 0 || message->data_size <= 0) {
msg_warn("%s: invalid size record: %.100s",
pickup.o: ../../include/safe_open.h
pickup.o: ../../include/scan_dir.h
pickup.o: ../../include/set_ugid.h
+pickup.o: ../../include/smtputf8.h
pickup.o: ../../include/stringops.h
pickup.o: ../../include/sys_defs.h
pickup.o: ../../include/vbuf.h
#include <input_transp.h>
#include <rec_attr_map.h>
#include <mail_version.h>
+#include <smtputf8.h>
/* Single-threaded server skeleton. */
*/
if (reason == 0 || *reason == 0)
msg_warn("%s: error writing %s: %s",
- info->path, info->id, cleanup_strerror(status));
+ info->path, info->id, cleanup_strerror(status));
return ((status & (CLEANUP_STAT_BAD | CLEANUP_STAT_RCPT)) ?
REMOVE_MESSAGE_FILE : KEEP_MESSAGE_FILE);
}
/* As documented in postsuper(1). */
if (MAIL_IS_REQUEUED(info))
cleanup_flags &= ~CLEANUP_FLAG_MILTER;
+ else
+ cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_SENDMAIL);
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
postscreen_smtpd.o: ../../include/attr.h
postscreen_smtpd.o: ../../include/dict.h
postscreen_smtpd.o: ../../include/dict_cache.h
+postscreen_smtpd.o: ../../include/dns.h
postscreen_smtpd.o: ../../include/ehlo_mask.h
postscreen_smtpd.o: ../../include/events.h
postscreen_smtpd.o: ../../include/htable.h
postscreen_smtpd.o: ../../include/name_code.h
postscreen_smtpd.o: ../../include/name_mask.h
postscreen_smtpd.o: ../../include/server_acl.h
+postscreen_smtpd.o: ../../include/sock_addr.h
postscreen_smtpd.o: ../../include/string_list.h
postscreen_smtpd.o: ../../include/stringops.h
postscreen_smtpd.o: ../../include/sys_defs.h
postscreen_starttls.o: ../../include/connect.h
postscreen_starttls.o: ../../include/dict.h
postscreen_starttls.o: ../../include/dict_cache.h
+postscreen_starttls.o: ../../include/dns.h
postscreen_starttls.o: ../../include/events.h
postscreen_starttls.o: ../../include/htable.h
postscreen_starttls.o: ../../include/iostuff.h
postscreen_starttls.o: ../../include/name_code.h
postscreen_starttls.o: ../../include/name_mask.h
postscreen_starttls.o: ../../include/server_acl.h
+postscreen_starttls.o: ../../include/sock_addr.h
postscreen_starttls.o: ../../include/string_list.h
postscreen_starttls.o: ../../include/stringops.h
postscreen_starttls.o: ../../include/sys_defs.h
PSC_EHLO_APPEND(saved_len, psc_temp, "250-8BITMIME\r\n");
if ((discard_mask & EHLO_MASK_DSN) == 0)
PSC_EHLO_APPEND(saved_len, psc_temp, "250-DSN\r\n");
+ /* Fix 20140708: announce SMTPUTF8. */
+ if (var_smtputf8_enable && (discard_mask & EHLO_MASK_SMTPUTF8) == 0)
+ PSC_EHLO_APPEND(saved_len, psc_temp, "250-SMTPUTF8\r\n");
STR(psc_temp)[saved_len + 3] = ' ';
}
qmgr_deliver.o: ../../include/rcpt_print.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/scan_dir.h
+qmgr_deliver.o: ../../include/smtputf8.h
qmgr_deliver.o: ../../include/stringops.h
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_deliver.o: ../../include/vbuf.h
char *sender; /* complete address */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
+ int smtputf8; /* requires unicode */
char *verp_delims; /* VERP delimiters */
char *filter_xport; /* filtering transport */
char *inspect_xport; /* inspecting transport */
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
+ message->smtputf8,
message->sender,
message->dsn_envid,
message->dsn_ret,
#include <dsn_buf.h>
#include <dsb_scan.h>
#include <rcpt_print.h>
+#include <smtputf8.h>
/* Application-specific. */
MSG_STATS stats;
char *sender;
int flags;
+ int smtputf8 = message->smtputf8;
+ const char *addr;
+
+ /*
+ * Todo: integrate with code up-stream that builds the delivery request.
+ */
+ for (recipient = list.info; recipient < list.info + list.len; recipient++)
+ if (var_smtputf8_enable && (addr = recipient->address)[0]
+ && !allascii(addr) && valid_utf8_string(addr, strlen(addr)))
+ smtputf8 |= SMTPUTF8_FLAG_RECIPIENT;
/*
* If variable envelope return path is requested, change prefix+@origin
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->cont_length,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, entry->queue->nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
+ ATTR_TYPE_INT, MAIL_ATTR_SMTPUTF8, smtputf8,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, message->dsn_envid,
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, message->dsn_ret,
message->sender = 0;
message->dsn_envid = 0;
message->dsn_ret = 0;
+ message->smtputf8 = 0;
message->filter_xport = 0;
message->inspect_xport = 0;
message->redirect_addr = 0;
continue;
if (rec_type == REC_TYPE_SIZE) {
if (message->data_offset == 0) {
- if ((count = sscanf(start, "%ld %ld %d %d %ld",
+ if ((count = sscanf(start, "%ld %ld %d %d %ld %d",
&message->data_size, &message->data_offset,
&message->rcpt_unread, &message->rflags,
- &message->cont_length)) >= 3) {
+ &message->cont_length,
+ &message->smtputf8)) >= 3) {
/* Postfix >= 1.0 (a.k.a. 20010228). */
if (message->data_offset <= 0 || message->data_size <= 0) {
msg_warn("%s: invalid size record: %.100s",
qmqpd.o: ../../include/rec_type.h
qmqpd.o: ../../include/recipient_list.h
qmqpd.o: ../../include/record.h
+qmqpd.o: ../../include/smtputf8.h
qmqpd.o: ../../include/sys_defs.h
qmqpd.o: ../../include/vbuf.h
qmqpd.o: ../../include/verp_sender.h
/* .IP "\fBreceive_override_options (empty)\fR"
/* Enable or disable recipient validation, built-in content
/* filtering, or address mapping.
+/* SMTPUTF8 CONTROLS
+/* .ad
+/* .fi
+/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+/* Detect that a message requires SMTPUTF8 support for the specified
+/* mail origin classes.
/* RESOURCE AND RATE CONTROLS
/* .ad
/* .fi
#include <lex_822.h>
#include <verp_sender.h>
#include <input_transp.h>
+#include <smtputf8.h>
/* Single-threaded server skeleton. */
*/
cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
qmqpd_input_transp_mask);
+ cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_QMQPD);
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (state->dest == 0
|| attr_print(state->dest->stream, ATTR_FLAG_NONE,
/* .IP "\fBdelay_warning_time (0h)\fR"
/* The time after which the sender receives a copy of the message
/* headers of mail that is still queued.
-/* .IP "\fBenable_errors_to (no)\fR"
-/* Report mail delivery errors to the address specified with the
-/* non-standard Errors-To: message header, instead of the envelope
-/* sender address (this feature is removed with Postfix version 2.2, is
-/* turned off by default with Postfix version 2.1, and is always turned on
-/* with older Postfix versions).
/* .IP "\fBmail_owner (postfix)\fR"
/* The UNIX system account that owns the Postfix queue and most Postfix
/* daemon processes.
smtp_addr.o: ../../include/mail_params.h
smtp_addr.o: ../../include/maps.h
smtp_addr.o: ../../include/match_list.h
+smtp_addr.o: ../../include/midna.h
smtp_addr.o: ../../include/mime_state.h
smtp_addr.o: ../../include/msg.h
smtp_addr.o: ../../include/msg_stats.h
smtp_chat.o: ../../include/header_body_checks.h
smtp_chat.o: ../../include/header_opts.h
smtp_chat.o: ../../include/htable.h
-smtp_chat.o: ../../include/int_filt.h
+smtp_chat.o: ../../include/iostuff.h
smtp_chat.o: ../../include/line_wrap.h
smtp_chat.o: ../../include/mail_addr.h
smtp_chat.o: ../../include/mail_error.h
smtp_chat.o: ../../include/mail_params.h
+smtp_chat.o: ../../include/mail_proto.h
smtp_chat.o: ../../include/maps.h
smtp_chat.o: ../../include/match_list.h
smtp_chat.o: ../../include/mime_state.h
smtp_map11.o: ../../include/sys_defs.h
smtp_map11.o: ../../include/tls.h
smtp_map11.o: ../../include/tok822.h
-smtp_map11.o: ../../include/valid_hostname.h
smtp_map11.o: ../../include/vbuf.h
smtp_map11.o: ../../include/vstream.h
smtp_map11.o: ../../include/vstring.h
smtp_proto.o: ../../include/resolve_clnt.h
smtp_proto.o: ../../include/scache.h
smtp_proto.o: ../../include/smtp_stream.h
+smtp_proto.o: ../../include/smtputf8.h
smtp_proto.o: ../../include/sock_addr.h
smtp_proto.o: ../../include/split_at.h
smtp_proto.o: ../../include/string_list.h
smtp_proto.o: ../../include/sys_defs.h
smtp_proto.o: ../../include/tls.h
smtp_proto.o: ../../include/tok822.h
+smtp_proto.o: ../../include/uxtext.h
smtp_proto.o: ../../include/vbuf.h
smtp_proto.o: ../../include/vstream.h
smtp_proto.o: ../../include/vstring.h
smtp_tls_policy.o: ../../include/tls.h
smtp_tls_policy.o: ../../include/tok822.h
smtp_tls_policy.o: ../../include/valid_hostname.h
+smtp_tls_policy.o: ../../include/valid_utf8_hostname.h
smtp_tls_policy.o: ../../include/vbuf.h
smtp_tls_policy.o: ../../include/vstream.h
smtp_tls_policy.o: ../../include/vstring.h
/* RFC 3463 (Enhanced Status Codes)
/* RFC 4954 (AUTH command)
/* RFC 5321 (SMTP protocol)
+/* RFC 6531 (Internationalized SMTP)
+/* RFC 6533 (Internationalized Delivery Status Notifications)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* Corrupted message files are marked so that the queue manager can
/* When SMTP connection caching is enabled, the number of times
/* that an SMTP session may be reused before it is closed, or zero (no
/* limit).
+/* SMTPUTF8 CONTROLS
+/* .ad
+/* .fi
+/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+/* .IP "\fBsmtputf8_enable (no)\fR"
+/* Enable experimental SMTPUTF8 support for the protocols described
+/* in RFC 6531..6533.
+/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+/* Enable SMTPUTF8 autodetection for the specified mail origin
+/* classes.
/* TROUBLE SHOOTING CONTROLS
/* .ad
/* .fi
#define SMTP_FEATURE_XFORWARD_PORT (1<<18)
#define SMTP_FEATURE_EARLY_TLS_MAIL_REPLY (1<<19) /* CVE-2009-3555 */
#define SMTP_FEATURE_XFORWARD_IDENT (1<<20)
+#define SMTP_FEATURE_SMTPUTF8 (1<<21) /* RFC 6531 */
/*
* Features that passivate under the endpoint.
#include <stringops.h>
#include <myaddrinfo.h>
#include <inet_proto.h>
+#include <midna.h>
/* Global library. */
/* smtp_domain_addr - mail exchanger address lookup */
-DNS_RR *smtp_domain_addr(char *name, DNS_RR **mxrr, int misc_flags,
+DNS_RR *smtp_domain_addr(const char *name, DNS_RR **mxrr, int misc_flags,
DSN_BUF *why, int *found_myself)
{
DNS_RR *mx_names;
unsigned best_pref;
unsigned best_found;
int r = 0; /* Resolver flags */
+ const char *aname;
dsb_reset(why); /* Paranoia */
if (smtp_dns_support == SMTP_DNS_DNSSEC)
r |= RES_USE_DNSSEC;
+ /*
+ * IDNA support.
+ */
+#ifndef NO_EAI
+ if (!allascii(name) && (aname = midna_utf8_to_ascii(name)) != 0) {
+ if (msg_verbose)
+ msg_info("%s asciified to %s", name, aname);
+ } else
+#endif
+ aname = name;
+
/*
* Look up the mail exchanger hosts listed for this name. Sort the
* results by preference. Look up the corresponding host addresses, and
* at hostnames provides a partial solution for MX hosts behind a NAT
* gateway.
*/
- switch (dns_lookup(name, T_MX, r, &mx_names, (VSTRING *) 0, why->reason)) {
+ switch (dns_lookup(aname, T_MX, r, &mx_names, (VSTRING *) 0, why->reason)) {
default:
dsb_status(why, "4.4.3");
if (var_ign_mx_lookup_err)
- addr_list = smtp_host_addr(name, misc_flags, why);
+ addr_list = smtp_host_addr(aname, misc_flags, why);
break;
case DNS_INVAL:
dsb_status(why, "5.4.4");
if (var_ign_mx_lookup_err)
- addr_list = smtp_host_addr(name, misc_flags, why);
+ addr_list = smtp_host_addr(aname, misc_flags, why);
break;
case DNS_FAIL:
dsb_status(why, "5.4.3");
if (var_ign_mx_lookup_err)
- addr_list = smtp_host_addr(name, misc_flags, why);
+ addr_list = smtp_host_addr(aname, misc_flags, why);
break;
case DNS_OK:
mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref_any);
}
break;
case DNS_NOTFOUND:
- addr_list = smtp_host_addr(name, misc_flags, why);
+ addr_list = smtp_host_addr(aname, misc_flags, why);
break;
}
{
DNS_RR *addr_list;
int res_opt = 0;
+ const char *ahost;
dsb_reset(why); /* Paranoia */
if (smtp_dns_support == SMTP_DNS_DNSSEC)
res_opt |= RES_USE_DNSSEC;
+ /*
+ * IDNA support.
+ */
+#ifndef NO_EAI
+ if (!allascii(host) && (ahost = midna_utf8_to_ascii(host)) != 0) {
+ if (msg_verbose)
+ msg_info("%s asciified to %s", host, ahost);
+ } else
+#endif
+ ahost = host;
+
/*
* If the host is specified by numerical address, just convert the
* address to internal form. Otherwise, the host is specified by name.
*/
#define PREF0 0
- addr_list = smtp_addr_one((DNS_RR *) 0, host, res_opt, PREF0, why);
+ addr_list = smtp_addr_one((DNS_RR *) 0, ahost, res_opt, PREF0, why);
if (addr_list
&& (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
&& smtp_find_self(addr_list) != 0) {
* Internal interfaces.
*/
extern DNS_RR *smtp_host_addr(const char *, int, DSN_BUF *);
-extern DNS_RR *smtp_domain_addr(char *, DNS_RR **, int, DSN_BUF *, int *);
+extern DNS_RR *smtp_domain_addr(const char *, DNS_RR **, int, DSN_BUF *, int *);
/* LICENSE
/* .ad
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- INT_FILT_MASK_NOTIFY,
+ MAIL_SRC_MASK_NOTIFY,
NULL_TRACE_FLAGS, NO_QUEUE_ID);
if (notice == 0) {
msg_warn("postmaster notify: %m");
session->state = state;
#ifdef USE_TLS
session->tls = state->tls; /* TEMPORARY */
+ /* XXX: EAI: Convert to A-label here or in TLS library */
session->tls_nexthop = domain; /* for TLS_LEV_SECURE */
#endif
if (addr->pref == domain_best_pref)
#include <dict.h>
#include <argv.h>
#include <tok822.h>
-#include <valid_hostname.h>
/* Global library. */
#include <lex_822.h>
#include <dsn_mask.h>
#include <xtext.h>
+#include <uxtext.h>
+#include <smtputf8.h>
/* Application-specific. */
"QUIT command",
};
+ /*
+ * Note: MIME downgrade never happens for mail that must be delivered with
+ * SMTPUTF8 (the sender requested SMTPUTF8, AND the delivery request
+ * involves at least one UTF-8 envelope address or header value.
+ */
#define SMTP_MIME_DOWNGRADE(session, request) \
(var_disable_mime_oconv == 0 \
&& (session->features & SMTP_FEATURE_8BITMIME) == 0 \
} else if (strcasecmp(word, "DSN") == 0) {
if ((discard_mask & EHLO_MASK_DSN) == 0)
session->features |= SMTP_FEATURE_DSN;
+ } else if (strcasecmp(word, "SMTPUTF8") == 0) {
+ if ((discard_mask & EHLO_MASK_SMTPUTF8) == 0)
+ session->features |= SMTP_FEATURE_SMTPUTF8;
}
n++;
}
msg_info("server features: 0x%x size %.0f",
session->features, (double) session->size_limit);
+ /*
+ * Decide if this delivery requires SMTPUTF8 server support.
+ *
+ * For now, we require that the remote SMTP server supports SMTPUTF8 when
+ * the sender requested SMTPUTF8 support.
+ *
+ * XXX EAI Refine this to: the sender requested SMTPUTF8 support AND the
+ * delivery request involves at least one UTF-8 envelope address or
+ * header value.
+ *
+ * If the sender requested SMTPUTF8 support but the delivery request
+ * involves no UTF-8 envelope address or header value, then we could
+ * still deliver such mail to a non-SMTPUTF8 server, except that we must
+ * either uxtext-encode ORCPT parameters or not send them. We cannot
+ * encode the ORCPT in xtext, because legacy SMTP requires that the
+ * unencoded address consist entirely of printable (graphic and white
+ * space) characters from the US-ASCII repertoire (RFC 3461 section 4). A
+ * correct uxtext encoder will produce a result that an xtext decoder
+ * will pass through unchanged.
+ *
+ * XXX Should we try to encode headers with RFC 2047 when delivering to a
+ * non-SMTPUTF8 server? That could make life easier for mailing lists.
+ */
+#define DELIVERY_REQUIRES_SMTPUTF8 \
+ ((request->smtputf8 & SMTPUTF8_FLAG_REQUESTED) \
+ && (request->smtputf8 & ~SMTPUTF8_FLAG_REQUESTED))
+
+ /*
+ * Require that the server supports SMTPUTF8 when delivery requires
+ * SMTPUTF8.
+ *
+ * Fix 20140706: moved this before negotiating TLS, AUTH, and so on.
+ */
+ if ((session->features & SMTP_FEATURE_SMTPUTF8) == 0
+ && DELIVERY_REQUIRES_SMTPUTF8)
+ return (smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "5.6.7"),
+ "SMTPUTF8 is required, "
+ "but was not offered by host %s",
+ session->namaddr));
+
+ /*
+ * Fix 20140706: don't do silly things when the remote server announces
+ * SMTPUTF8 but not 8BITMIME support. Our primary mission is to deliver
+ * mail, not to force people into compliance.
+ */
+ if ((session->features & SMTP_FEATURE_SMTPUTF8) != 0
+ && (session->features & SMTP_FEATURE_8BITMIME) == 0) {
+ msg_info("host %s offers SMTPUTF8 support, but not 8BITMIME",
+ session->namaddr);
+ session->features |= SMTP_FEATURE_8BITMIME;
+ }
+
/*
* We use SMTP command pipelining if the server said it supported it.
* Since we use blocking I/O, RFC 2197 says that we should inspect the
dsn_ret_str(request->dsn_ret));
}
+ /*
+ * Request SMTPUTF8 when the remote SMTP server supports
+ * SMTPUTF8.
+ *
+ * If the sender requested SMTPUTF8 but the remote SMTP server does
+ * not support SMTPUTF8, then we have already determined earlier
+ * that delivering this message without SMTPUTF8 will not break
+ * the SMTPUTF8 promise that was made to the sender.
+ */
+ if ((session->features & SMTP_FEATURE_SMTPUTF8) != 0)
+ vstring_strcat(next_command, " SMTPUTF8");
+
/*
* We authenticate the local MTA only, but not the sender.
*/
vstring_str(session->scratch));
if (session->features & SMTP_FEATURE_DSN) {
/* XXX DSN xtext encode address value not type. */
- if (rcpt->dsn_orcpt[0]) {
- xtext_quote(session->scratch, rcpt->dsn_orcpt, "+=");
- vstring_sprintf_append(next_command, " ORCPT=%s",
- vstring_str(session->scratch));
- } else if (rcpt->orig_addr[0]) {
+ const char *orcpt_type_addr = rcpt->dsn_orcpt;
+
+ /* Fix 20140706: don't use empty rcpt->orig_addr. */
+ if (orcpt_type_addr[0] == 0 && rcpt->orig_addr[0] != 0) {
quote_822_local(session->scratch, rcpt->orig_addr);
- vstring_sprintf(session->scratch2, "rfc822;%s",
+ vstring_sprintf(session->scratch2, "%s;%s",
+ /* Fix 20140707: sender must request SMTPUTF8. */
+ (request->smtputf8 != 0
+ && !allascii(vstring_str(session->scratch))) ?
+ "utf-8" : "rfc822",
vstring_str(session->scratch));
- xtext_quote(session->scratch, vstring_str(session->scratch2), "+=");
- vstring_sprintf_append(next_command, " ORCPT=%s",
- vstring_str(session->scratch));
+ orcpt_type_addr = vstring_str(session->scratch2);
+ }
+ if (orcpt_type_addr[0] != 0) {
+ /* Fix 20140706: don't send unquoted ORCPT. */
+ /* Fix 20140707: quoting method must match orcpt type. */
+ /* Fix 20140707: handle uxtext encoder errors. */
+ if (strncasecmp(orcpt_type_addr, "utf-8;", 6) == 0) {
+ if (uxtext_quote(session->scratch,
+ orcpt_type_addr, "+=") != 0)
+ vstring_sprintf_append(next_command, " ORCPT=%s",
+ vstring_str(session->scratch));
+ } else {
+ xtext_quote(session->scratch, orcpt_type_addr, "=");
+ vstring_sprintf_append(next_command, " ORCPT=%s",
+ vstring_str(session->scratch));
+ }
}
if (rcpt->dsn_notify)
vstring_sprintf_append(next_command, " NOTIFY=%s",
#include <mymalloc.h>
#include <vstring.h>
#include <stringops.h>
-#include <valid_hostname.h>
+#include <valid_utf8_hostname.h>
#include <ctable.h>
/* Global library. */
*
* XXX UNIX-domain connections query with the pathname as destination.
*/
- if (!valid_hostname(site_name, DONT_GRIPE)) {
+ if (!valid_utf8_hostname(var_smtputf8_enable, site_name, DONT_GRIPE)) {
tls_policy_lookup_one(tls, site_level, site_name, site_class);
return;
}
smtpd.o: ../../include/record.h
smtpd.o: ../../include/resolve_clnt.h
smtpd.o: ../../include/smtp_stream.h
+smtpd.o: ../../include/smtputf8.h
smtpd.o: ../../include/sock_addr.h
smtpd.o: ../../include/split_at.h
smtpd.o: ../../include/string_list.h
smtpd.o: ../../include/tls.h
smtpd.o: ../../include/tls_proxy.h
smtpd.o: ../../include/tok822.h
+smtpd.o: ../../include/uxtext.h
smtpd.o: ../../include/valid_hostname.h
smtpd.o: ../../include/valid_mailhost_addr.h
smtpd.o: ../../include/vbuf.h
smtpd_chat.o: ../../include/attr.h
smtpd_chat.o: ../../include/cleanup_user.h
smtpd_chat.o: ../../include/dns.h
-smtpd_chat.o: ../../include/int_filt.h
smtpd_chat.o: ../../include/iostuff.h
smtpd_chat.o: ../../include/line_wrap.h
smtpd_chat.o: ../../include/mac_expand.h
smtpd_check.o: ../../include/maps.h
smtpd_check.o: ../../include/match_list.h
smtpd_check.o: ../../include/match_parent_style.h
+smtpd_check.o: ../../include/midna.h
smtpd_check.o: ../../include/milter.h
smtpd_check.o: ../../include/msg.h
smtpd_check.o: ../../include/msg_stats.h
smtpd_check.o: ../../include/tls.h
smtpd_check.o: ../../include/valid_hostname.h
smtpd_check.o: ../../include/valid_mailhost_addr.h
+smtpd_check.o: ../../include/valid_utf8_hostname.h
smtpd_check.o: ../../include/vbuf.h
smtpd_check.o: ../../include/verify_clnt.h
smtpd_check.o: ../../include/vstream.h
/* RFC 4409 (Message submission)
/* RFC 4954 (AUTH command)
/* RFC 5321 (SMTP protocol)
+/* RFC 6531 (Internationalized SMTP)
+/* RFC 6533 (Internationalized Delivery Status Notifications)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/*
/* .IP "\fBsmtpd_tls_cipherlist (empty)\fR"
/* Obsolete Postfix < 2.3 control for the Postfix SMTP server TLS
/* cipher list.
+/* SMTPUTF8 CONTROLS
+/* .ad
+/* .fi
+/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+/* .IP "\fBsmtputf8_enable (no)\fR"
+/* Enable experimental SMTPUTF8 support for the protocols described
+/* in RFC 6531..6533.
+/* .IP "\fBstrict_smtputf8 (no)\fR"
+/* Enable stricter enforcement of the SMTPUTF8 protocol.
+/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+/* Detect that a message requires SMTPUTF8 support for the specified
+/* mail origin classes.
/* VERP SUPPORT CONTROLS
/* .ad
/* .fi
#include <valid_mailhost_addr.h>
#include <dsn_mask.h>
#include <xtext.h>
+#include <uxtext.h>
#include <tls_proxy.h>
#include <verify_sender_addr.h>
+#include <smtputf8.h>
/* Single-threaded server skeleton. */
EHLO_APPEND(state, "8BITMIME");
if ((discard_mask & EHLO_MASK_DSN) == 0)
EHLO_APPEND(state, "DSN");
+ if (var_smtputf8_enable && (discard_mask & EHLO_MASK_SMTPUTF8) == 0)
+ EHLO_APPEND(state, "SMTPUTF8");
/*
* Send the reply.
cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
smtpd_input_transp_mask)
| CLEANUP_FLAG_SMTP_REPLY;
+ if (state->flags & SMTPD_FLAG_SMTPUTF8)
+ cleanup_flags |= CLEANUP_FLAG_SMTPUTF8;
+ else
+ cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_SMTPD);
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
var_cleanup_service);
if (state->dest == 0
if ((STR(state->addr_buf)[0] == 0 && !allow_empty_addr)
|| (strict_rfc821 && STR(state->addr_buf)[0] == '@')
|| (SMTPD_STAND_ALONE(state) == 0
- && smtpd_check_addr(STR(state->addr_buf)) != 0)) {
+ && smtpd_check_addr(state, STR(state->addr_buf)) != 0)) {
msg_warn("Illegal address syntax from %s in %s command: %s",
state->namaddr, state->where,
printable(STR(arg->vstrval), '?'));
smtpd_chat_reply(state, "552 5.3.4 Message size exceeds file system imposed limit");
return (-1);
}
+ } else if (var_smtputf8_enable
+ && (state->ehlo_discard_mask & EHLO_MASK_SMTPUTF8) == 0
+ && strcasecmp(arg, "SMTPUTF8") == 0) { /* RFC 6531 */
+ state->flags |= SMTPD_FLAG_SMTPUTF8;
#ifdef USE_SASL_AUTH
} else if (strncasecmp(arg, "AUTH=", 5) == 0) {
if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
}
}
+ /*
+ * Historically, Postfix does not forbid 8-bit envelope addresses.
+ * Changing this would be a compatibility break. That can't happen in the
+ * forseeable future.
+ */
+ if (var_strict_smtputf8 && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0) {
+ if (*STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
+ mail_reset(state);
+ smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to send unicode address");
+ return (-1);
+ }
+ }
+
/*
* Check the queue file space, if applicable. The optional before-filter
* speed-adjust buffers use disk space. However, we don't know if they
vstring_strcpy(state->dsn_orcpt_buf, arg + 6);
if (dsn_orcpt_addr
|| (coded_addr = split_at(STR(state->dsn_orcpt_buf), ';')) == 0
- || xtext_unquote(state->dsn_buf, coded_addr) == 0
- || *(dsn_orcpt_type = STR(state->dsn_orcpt_buf)) == 0) {
+ || *(dsn_orcpt_type = STR(state->dsn_orcpt_buf)) == 0
+ || (strcasecmp(dsn_orcpt_type, "utf-8") == 0 ?
+ uxtext_unquote(state->dsn_buf, coded_addr) == 0 :
+ xtext_unquote(state->dsn_buf, coded_addr) == 0)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state,
"501 5.5.4 Error: Bad ORCPT parameter syntax");
state->error_mask |= MAIL_ERROR_POLICY;
return (-1);
}
+
+ /*
+ * Historically, Postfix does not forbid 8-bit envelope addresses.
+ * Changing this would be a compatibility break. That can't happen in the
+ * forseeable future.
+ */
+ if (var_strict_smtputf8 && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0) {
+ if (*STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
+ mail_reset(state);
+ smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to send unicode address");
+ return (-1);
+ }
+ }
if (SMTPD_STAND_ALONE(state) == 0) {
const char *verify_sender;
const CLEANUP_STAT_DETAIL *detail;
const char *rfc3848_sess;
const char *rfc3848_auth;
+ const char *with_protocol = (state->flags & SMTPD_FLAG_SMTPUTF8) ?
+ "UTF8SMTP" : state->protocol;
#ifdef USE_TLS
VSTRING *peer_CN;
state->cleanup ? "\tby %s (%s) with %s%s%s id %s" :
"\tby %s (%s) with %s%s%s",
var_myhostname, var_mail_name,
- state->protocol, rfc3848_sess,
+ with_protocol, rfc3848_sess,
rfc3848_auth, state->queue_id);
quote_822_local(state->buffer, state->recipient);
out_fprintf(out_stream, REC_TYPE_NORM,
state->cleanup ? "\tby %s (%s) with %s%s%s id %s;" :
"\tby %s (%s) with %s%s%s;",
var_myhostname, var_mail_name,
- state->protocol, rfc3848_sess,
+ with_protocol, rfc3848_sess,
rfc3848_auth, state->queue_id);
out_fprintf(out_stream, REC_TYPE_NORM,
"\t%s", mail_date(state->arrival_time.tv_sec));
{
const char *err = 0;
int rate;
+ int smtputf8 = 0;
/*
* The SMTP standard (RFC 821) disallows unquoted special characters in
smtpd_chat_reply(state, "502 5.5.1 VRFY command is disabled");
return (-1);
}
+ /* Fix 20140707: handle missing address. */
+ if (var_smtputf8_enable
+ && (state->ehlo_discard_mask & EHLO_MASK_SMTPUTF8) == 0
+ && argc > 1 && strcasecmp(argv[argc - 1].strval, "SMTPUTF8") == 0) {
+ argc--; /* RFC 6531 */
+ smtputf8 = 1;
+ }
if (argc < 2) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "501 5.5.4 Syntax: VRFY address");
+ smtpd_chat_reply(state, "501 5.5.4 Syntax: VRFY address%s",
+ var_smtputf8_enable ? " [SMTPUTF8]" : "");
return (-1);
}
smtpd_chat_reply(state, "501 5.1.3 Bad recipient address syntax");
return (-1);
}
+ /* Fix 20140707: Check the VRFY command. */
+ if (smtputf8 == 0 && var_strict_smtputf8) {
+ if (*STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
+ mail_reset(state);
+ smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to send unicode address");
+ return (-1);
+ }
+ }
/* Use state->addr_buf, with the unquoted result from extract_addr() */
if (SMTPD_STAND_ALONE(state) == 0
&& (err = smtpd_check_rcpt(state, STR(state->addr_buf))) != 0) {
/*
* As an extension to RFC 1985 we also allow an RFC 2821 address literal
* enclosed in [].
+ *
+ * XXX EAI: Convert to ASCII and use that form internally.
*/
if (!valid_hostname(argv[1].strval, DONT_GRIPE)
&& !valid_mailhost_literal(argv[1].strval, DONT_GRIPE)) {
if (name_status != SMTPD_PEER_CODE_OK) {
attr_value = CLIENT_NAME_UNKNOWN;
} else {
+ /* XXX EAI */
if (!valid_hostname(attr_value, DONT_GRIPE)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
if (name_status != SMTPD_PEER_CODE_OK) {
attr_value = CLIENT_NAME_UNKNOWN;
} else {
+ /* XXX EAI */
if (!valid_hostname(attr_value, DONT_GRIPE)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
if (STREQ(attr_value, XFORWARD_UNAVAILABLE)) {
attr_value = CLIENT_NAME_UNKNOWN;
} else {
+ /* XXX EAI */
neuter(attr_value, NEUTER_CHARACTERS, '?');
if (!valid_hostname(attr_value, DONT_GRIPE)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
#endif
VAR_SMTPD_ACL_PERM_LOG, DEF_SMTPD_ACL_PERM_LOG, &var_smtpd_acl_perm_log, 0, 0,
VAR_SMTPD_UPROXY_PROTO, DEF_SMTPD_UPROXY_PROTO, &var_smtpd_uproxy_proto, 0, 0,
- VAR_SMTPD_POLICY_DEF_ACTION, DEF_SMTPD_POLICY_DEF_ACTION, &var_smtpd_policy_def_action, 1, 0,
+ VAR_SMTPD_POLICY_DEF_ACTION, DEF_SMTPD_POLICY_DEF_ACTION, &var_smtpd_policy_def_action, 1, 0,
0,
};
static const CONFIG_RAW_TABLE raw_table[] = {
#define SMTPD_FLAG_HANGUP (1<<0) /* 421/521 disconnect */
#define SMTPD_FLAG_ILL_PIPELINING (1<<1) /* inappropriate pipelining */
#define SMTPD_FLAG_AUTH_USED (1<<2) /* don't reuse SASL state */
+#define SMTPD_FLAG_SMTPUTF8 (1<<3) /* RFC 6531/2 transaction */
/* Security: don't reset SMTPD_FLAG_AUTH_USED. */
-#define SMTPD_MASK_MAIL_KEEP ~0 /* keep all after MAIL reset */
+#define SMTPD_MASK_MAIL_KEEP \
+ ~(SMTPD_FLAG_SMTPUTF8) /* Fix 20140706 */
#define SMTPD_STATE_XFORWARD_INIT (1<<0) /* xforward preset done */
#define SMTPD_STATE_XFORWARD_NAME (1<<1) /* client name received */
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- INT_FILT_MASK_NOTIFY,
+ MAIL_SRC_MASK_NOTIFY,
NULL_TRACE_FLAGS, NO_QUEUE_ID);
if (notice == 0) {
msg_warn("postmaster notify: %m");
/*
/* void smtpd_check_init()
/*
-/* int smtpd_check_addr(address)
+/* int smtpd_check_addr(state, address)
+/* SMTPD_STATE *state;
/* const char *address;
/*
/* char *smtpd_check_rewrite(state)
#include <myaddrinfo.h>
#include <inet_proto.h>
#include <ip_match.h>
+#include <valid_utf8_hostname.h>
+#include <midna.h>
/* DNS library. */
test_name = dup_if_truncate(name);
/*
- * Validate the hostname.
+ * Validate the HELO/EHLO hostname. Fix 20140706: EAI not allowed here.
*/
if (!valid_hostname(test_name, DONT_GRIPE)
&& !valid_hostaddr(test_name, DONT_GRIPE)) /* XXX back compat */
test_name = dup_if_truncate(name);
/*
- * Validate the hostname.
+ * Validate the hostname. For backwards compatibility, permit non-ASCII
+ * names only when the client requested SMTPUTF8 support.
*/
- if (!valid_hostname(test_name, DONT_GRIPE) || !strchr(test_name, '.'))
+ if (valid_utf8_hostname(state->flags & SMTPD_FLAG_SMTPUTF8,
+ test_name, DONT_GRIPE) == 0 || strchr(test_name, '.') == 0)
stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
var_non_fqdn_code, "5.5.2",
"<%s>: %s rejected: need fully-qualified hostname",
test_dom = dup_if_truncate(domain);
/*
- * Validate the domain.
+ * Validate the domain. For backwards compatibility, permit non-ASCII
+ * names only when the client requested SMTPUTF8 support.
*/
- if (!*test_dom || !valid_hostname(test_dom, DONT_GRIPE) || !strchr(test_dom, '.'))
+ if (!*test_dom || !valid_utf8_hostname(state->flags & SMTPD_FLAG_SMTPUTF8,
+ test_dom, DONT_GRIPE) || !strchr(test_dom, '.'))
stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
var_non_fqdn_code, "4.5.2",
"<%s>: %s rejected: need fully-qualified address",
const char *reply_addr;
const char *byte_codes;
const char *suffix;
+ const char *adomain;
/*
* Extract the domain, tack on the RBL domain name and query the DNS for
* the name has an alphanumerical prefix. We play safe, and skip both
* RHSBL and RHSWL queries for names ending in a numerical suffix.
*/
- if (domain[0] == 0 || valid_hostname(domain, DONT_GRIPE) == 0)
+ if (domain[0] == 0)
return (SMTPD_CHECK_DUNNO);
suffix = strrchr(domain, '.');
if (alldig(suffix == 0 ? domain : suffix + 1))
return (SMTPD_CHECK_DUNNO);
- query = vstring_alloc(100);
+ /*
+ * Fix 20140706: convert domain to ASCII.
+ *
+ * Caution: early returns must not leak adomain.
+ */
+#ifndef NO_EAI
+ if (!allascii(domain) && (adomain = midna_utf8_to_ascii(domain)) != 0) {
+ if (msg_verbose)
+ msg_info("%s asciified to %s", domain, adomain);
+ } else
+#endif
+ adomain = domain;
+
+ if (valid_hostname(domain, DONT_GRIPE) == 0)
+ query = vstring_alloc(100);
vstring_sprintf(query, "%s.%s", domain, rbl_domain);
reply_addr = split_at(STR(query), '=');
rbl = (SMTPD_RBL_STATE *) ctable_locate(smtpd_rbl_cache, STR(query));
/* smtpd_check_addr - address sanity check */
-int smtpd_check_addr(const char *addr)
+int smtpd_check_addr(SMTPD_STATE *state, const char *addr)
{
const RESOLVE_REPLY *resolve_reply;
const char *myname = "smtpd_check_addr";
+ const char *domain;
if (msg_verbose)
msg_info("%s: addr=%s", myname, addr);
resolve_reply = smtpd_resolve_addr(addr);
if (resolve_reply->flags & RESOLVE_FLAG_ERROR)
return (-1);
+
+ /*
+ * Backwards compatibility: if the client does not request SMTPUTF8
+ * support, then behave like Postfix < 2.12 trivial-rewrite, and don't
+ * allow non-ASCII email domains. Historically, Postfix does not reject
+ * UTF8 etc. in the address localpart.
+ */
+ if ((state->flags & SMTPD_FLAG_SMTPUTF8) == 0
+ && (domain = strrchr(STR(resolve_reply->recipient), '@')) != 0
+ && *(domain += 1) != 0 && !allascii(domain))
+ return (-1);
+
return (0);
}
* External interface.
*/
extern void smtpd_check_init(void);
-extern int smtpd_check_addr(const char *);
+extern int smtpd_check_addr(SMTPD_STATE *, const char *);
extern char *smtpd_check_rewrite(SMTPD_STATE *);
extern char *smtpd_check_client(SMTPD_STATE *);
extern char *smtpd_check_helo(SMTPD_STATE *, char *);
$(LIB): $(OBJS)
$(AR) $(ARFL) $(LIB) $?
$(RANLIB) $(LIB)
- $(SHLIB_LD) -o $(LIB) $(OBJS)
+ $(SHLIB_LD) -o $(LIB) $(OBJS) $(SHLIB_SYSLIBS)
$(LIB_DIR)/$(LIB): $(LIB)
cp $(LIB) $(LIB_DIR)
resolve.o: ../../include/tok822.h
resolve.o: ../../include/valid_hostname.h
resolve.o: ../../include/valid_mailhost_addr.h
+resolve.o: ../../include/valid_utf8_hostname.h
resolve.o: ../../include/vbuf.h
resolve.o: ../../include/vstream.h
resolve.o: ../../include/vstring.h
#include <vstream.h>
#include <vstring_vstream.h>
#include <split_at.h>
-#include <valid_hostname.h>
+#include <valid_utf8_hostname.h>
#include <stringops.h>
#include <mymalloc.h>
tree->head = tok822_scan(var_empty_addr, &tree->tail);
continue;
}
-
/* XXX Re-resolve with @$myhostname for backwards compatibility. */
if (domain == 0 && saved_domain == 0) {
tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
if (*rcpt_domain == '[') {
if (!valid_mailhost_literal(rcpt_domain, DONT_GRIPE))
*flags |= RESOLVE_FLAG_ERROR;
- } else if (!valid_hostname(rcpt_domain, DONT_GRIPE)) {
+ } else if (!valid_utf8_hostname(var_smtputf8_enable, rcpt_domain,
+ DONT_GRIPE)) {
if (var_resolve_num_dom && valid_hostaddr(rcpt_domain, DONT_GRIPE)) {
vstring_insert(nextrcpt, rcpt_domain - STR(nextrcpt), "[", 1);
vstring_strcat(nextrcpt, "]");
write_buf.c sane_basename.c format_tv.c allspace.c \
allascii.c load_file.c killme_after.c vstream_tweak.c \
pass_trigger.c edit_file.c inet_windowsize.c \
- unix_pass_fd_fix.c dict_cache.c valid_utf_8.c dict_thash.c \
+ unix_pass_fd_fix.c dict_cache.c valid_utf8_string.c dict_thash.c \
ip_match.c nbbio.c base32_code.c dict_test.c \
dict_fail.c msg_rate_delay.c dict_surrogate.c warn_stat.c \
dict_sockmap.c line_number.c recv_pass_attr.c pass_accept.c \
- poll_fd.c timecmp.c slmdb.c dict_pipe.c dict_random.c
+ poll_fd.c timecmp.c slmdb.c dict_pipe.c dict_random.c \
+ valid_utf8_hostname.c midna.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
write_buf.o sane_basename.o format_tv.o allspace.o \
allascii.o load_file.o killme_after.o vstream_tweak.o \
pass_trigger.o edit_file.o inet_windowsize.o \
- unix_pass_fd_fix.o dict_cache.o valid_utf_8.o dict_thash.o \
+ unix_pass_fd_fix.o dict_cache.o valid_utf8_string.o dict_thash.o \
ip_match.o nbbio.o base32_code.o dict_test.o \
dict_fail.o msg_rate_delay.o dict_surrogate.o warn_stat.o \
dict_sockmap.o line_number.o recv_pass_attr.o pass_accept.o \
- poll_fd.o timecmp.o $(NON_PLUGIN_MAP_OBJ) dict_pipe.o dict_random.o
+ poll_fd.o timecmp.o $(NON_PLUGIN_MAP_OBJ) dict_pipe.o dict_random.o \
+ valid_utf8_hostname.o midna.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
edit_file.h dict_cache.h dict_thash.h ip_match.h nbbio.h base32_code.h \
dict_fail.h warn_stat.h dict_sockmap.h line_number.h timecmp.h \
- slmdb.h compat_va_copy.h dict_pipe.h dict_random.h
+ slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
+ valid_utf8_hostname.h midna.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE)
attr_scan0 host_port attr_scan_plain attr_print_plain htable \
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
- valid_utf_8 ip_match base32_code msg_rate_delay netstring \
- vstream timecmp dict_cache
+ valid_utf8_string ip_match base32_code msg_rate_delay netstring \
+ vstream timecmp dict_cache midna
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX)
LIB_DIR = ../../lib
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
-valid_utf_8: $(LIB)
+valid_utf8_string: $(LIB)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
+midna: $(LIB)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+ mv junk $@.o
+
tests: valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
dict_open.o: dict_nisplus.h
dict_open.o: dict_open.c
dict_open.o: dict_pcre.h
+dict_open.o: dict_pipe.h
dict_open.o: dict_random.h
dict_open.o: dict_regexp.h
dict_open.o: dict_sdbm.h
dict_open.o: dict_sockmap.h
-dict_open.o: dict_pipe.h
dict_open.o: dict_static.h
dict_open.o: dict_tcp.h
dict_open.o: dict_thash.h
dict_pcre.o: vstream.h
dict_pcre.o: vstring.h
dict_pcre.o: warn_stat.h
+dict_pipe.o: argv.h
+dict_pipe.o: dict.h
+dict_pipe.o: dict_pipe.c
+dict_pipe.o: dict_pipe.h
+dict_pipe.o: htable.h
+dict_pipe.o: msg.h
+dict_pipe.o: myflock.h
+dict_pipe.o: mymalloc.h
+dict_pipe.o: stringops.h
+dict_pipe.o: sys_defs.h
+dict_pipe.o: vbuf.h
+dict_pipe.o: vstream.h
+dict_pipe.o: vstring.h
dict_random.o: argv.h
dict_random.o: dict.h
dict_random.o: dict_random.c
dict_sockmap.o: vbuf.h
dict_sockmap.o: vstream.h
dict_sockmap.o: vstring.h
-dict_pipe.o: argv.h
-dict_pipe.o: dict.h
-dict_pipe.o: dict_pipe.c
-dict_pipe.o: dict_pipe.h
-dict_pipe.o: htable.h
-dict_pipe.o: msg.h
-dict_pipe.o: myflock.h
-dict_pipe.o: mymalloc.h
-dict_pipe.o: stringops.h
-dict_pipe.o: sys_defs.h
-dict_pipe.o: vbuf.h
-dict_pipe.o: vstream.h
-dict_pipe.o: vstring.h
dict_static.o: argv.h
dict_static.o: dict.h
dict_static.o: dict_static.c
dict_tcp.o: vstring_vstream.h
dict_test.o: argv.h
dict_test.o: dict.h
+dict_test.o: dict_db.h
dict_test.o: dict_lmdb.h
dict_test.o: dict_test.c
dict_test.o: msg.h
host_port.o: stringops.h
host_port.o: sys_defs.h
host_port.o: valid_hostname.h
+host_port.o: valid_utf8_hostname.h
host_port.o: vbuf.h
host_port.o: vstring.h
htable.o: htable.c
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
match_ops.o: vbuf.h
match_ops.o: vstream.h
match_ops.o: vstring.h
+midna.o: ctable.h
+midna.o: midna.c
+midna.o: midna.h
+midna.o: msg.h
+midna.o: mymalloc.h
+midna.o: sys_defs.h
msg.o: msg.c
msg.o: msg.h
msg.o: msg_output.h
valid_hostname.o: valid_hostname.h
valid_hostname.o: vbuf.h
valid_hostname.o: vstring.h
-valid_utf_8.o: stringops.h
-valid_utf_8.o: sys_defs.h
-valid_utf_8.o: valid_utf_8.c
-valid_utf_8.o: vbuf.h
-valid_utf_8.o: vstring.h
+valid_utf8_hostname.o: midna.h
+valid_utf8_hostname.o: msg.h
+valid_utf8_hostname.o: mymalloc.h
+valid_utf8_hostname.o: stringops.h
+valid_utf8_hostname.o: sys_defs.h
+valid_utf8_hostname.o: valid_hostname.h
+valid_utf8_hostname.o: valid_utf8_hostname.c
+valid_utf8_hostname.o: valid_utf8_hostname.h
+valid_utf8_hostname.o: vbuf.h
+valid_utf8_hostname.o: vstring.h
+valid_utf8_string.o: stringops.h
+valid_utf8_string.o: sys_defs.h
+valid_utf8_string.o: valid_utf8_string.c
+valid_utf8_string.o: vbuf.h
+valid_utf8_string.o: vstring.h
vbuf.o: sys_defs.h
vbuf.o: vbuf.c
vbuf.o: vbuf.h
/* name or address, and the service name or port number.
/* The input string is modified.
/*
+/* Host/domain names are validated with valid_utf8_hostname(),
+/* and host addresses are validated with valid_hostaddr().
+/*
/* The following input formats are understood (null means
/* a null pointer argument):
/*
#include <msg.h>
#include <split_at.h>
-#include <stringops.h>
-#include <valid_hostname.h>
+#include <stringops.h> /* XXX temp_utf8_kludge */
+#include <valid_utf8_hostname.h>
/* Global library. */
* Final sanity checks. We're still sloppy, allowing bare numerical
* network addresses instead of requiring proper [ipaddress] forms.
*/
- if (*host != def_host && !valid_hostname(*host, DONT_GRIPE)
+ if (*host != def_host
+ && !valid_utf8_hostname(temp_utf8_kludge, *host, DONT_GRIPE)
&& !valid_hostaddr(*host, DONT_GRIPE))
return ("valid hostname or network address required");
if (*port != def_service && ISDIGIT(**port) && !alldig(*port))
--- /dev/null
+/*++
+/* NAME
+/* midna 3
+/* SUMMARY
+/* Postfix domain name conversion
+/* SYNOPSIS
+/* #include <midna.h>
+/*
+/* int midna_cache_size;
+/*
+/* const char *midna_utf8_to_ascii(
+/* const char *name)
+/* DESCRIPTION
+/* The functions in this module transform domain names from
+/* or to IDNA form. The result is cached to avoid repeated
+/* conversion of the same name.
+/*
+/* midna_utf8_to_ascii() converts an UTF-8 domain name to
+/* ASCII. 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.
+/* SEE ALSO
+/* msg(3) diagnostics interface
+/* DIAGNOSTICS
+/* Fatal errors: memory allocation problem.
+/* Warnings: conversion error.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Arnt Gulbrandsen
+/*
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <string.h>
+
+#ifndef NO_EAI
+#include <unicode/uidna.h>
+
+ /*
+ * Utility library.
+ */
+#include <mymalloc.h>
+#include <msg.h>
+#include <ctable.h>
+#include <midna.h>
+
+ /*
+ * Application-specific.
+ */
+#define DEF_MIDNA_CACHE_SIZE 100
+
+int midna_cache_size = DEF_MIDNA_CACHE_SIZE;
+
+/* midna_utf8_to_ascii_create - convert UTF8 domain to ASCII */
+
+static void *midna_utf8_to_ascii_create(const char *name, void *unused_context)
+{
+ const char myname[] = "midna_utf8_to_ascii_create";
+ char buf[1024]; /* XXX */
+ UErrorCode error = U_ZERO_ERROR;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UIDNA *idna;
+ int anl;
+
+ idna = uidna_openUTS46(UIDNA_DEFAULT, &error);
+ anl = uidna_nameToASCII_UTF8(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_utf8_to_ascii_free - cache element destructor */
+
+static void midna_utf8_to_ascii_free(void *value, void *unused_context)
+{
+ if (value)
+ myfree(value);
+}
+
+/* midna_utf8_to_ascii - convert UTF8 hostname to ASCII */
+
+const char *midna_utf8_to_ascii(const char *name)
+{
+ static CTABLE *midna_utf8_to_ascii_cache = 0;
+
+ 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,
+ (void *) 0);
+ return (ctable_locate(midna_utf8_to_ascii_cache, name));
+}
+
+#ifdef TEST
+
+ /*
+ * Test program - reads hostnames from stdin, reports invalid hostnames to
+ * stderr.
+ */
+#include <stdlib.h>
+
+#include <stringops.h> /* XXX temp_utf8_kludge */
+#include <vstring.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+#include <msg_vstream.h>
+
+int main(int argc, char **argv)
+{
+ VSTRING *buffer = vstring_alloc(1);
+ const char *res;
+
+ 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);
+ }
+ exit(0);
+}
+
+#endif
+
+#endif
--- /dev/null
+#ifndef _MIDNA_H_INCLUDED_
+#define _MIDNA_H_INCLUDED_
+
+/*++
+/* NAME
+/* mail_idna 3h
+/* SUMMARY
+/* domain name conversion
+/* SYNOPSIS
+/* #include <mail_idna.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+extern const char *midna_utf8_to_ascii(const char *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
/* SYNOPSIS
/* #include <stringops.h>
/*
+/* int temp_utf8_kludge;
+/*
/* char *printable(buffer, replacement)
/* char *buffer;
/* int replacement;
/* DESCRIPTION
-/* printable() replaces non-ASCII or non-printable characters in its input
-/* by the given replacement.
+/* printable() replaces non-printable characters
+/* in its input with the given replacement.
+/*
+/* temp_utf8_kludge controls whether UTF8 is considered printable.
+/* By default, non-ASCII text is replaced.
/*
/* Arguments:
/* .IP buffer
/* The null-terminated input string.
/* .IP replacement
/* Replacement value for characters in \fIbuffer\fR that do not
-/* pass the isprint(3) test.
+/* pass the ASCII isprint(3) test or that are not valid UTF8.
/* LICENSE
/* .ad
/* .fi
#include "stringops.h"
+int temp_utf8_kludge = 0;
+
char *printable(char *string, int replacement)
{
- char *cp;
+ unsigned char *cp;
int ch;
- for (cp = string; (ch = *(unsigned char *) cp) != 0; cp++)
- if (!ISASCII(ch) || !ISPRINT(ch))
+ /*
+ * XXX Replace invalid UTF8 sequences (too short, over-long encodings,
+ * out-of-range code points, etc). See valid_utf8_string.c.
+ */
+ cp = (unsigned char *) string;
+ while ((ch = *cp) != 0) {
+ if (ISASCII(ch) && ISPRINT(ch)) {
+ /* ok */
+ } else if (temp_utf8_kludge && ch >= 194 && ch <= 254
+ && cp[1] >= 128 && cp[1] < 192) {
+ /* UTF8; skip the rest of the bytes in the character. */
+ while (cp[1] >= 128 && cp[1] < 192)
+ cp++;
+ } else {
+ /* Not ASCII and not UTF8. */
*cp = replacement;
+ }
+ cp++;
+ }
return (string);
}
/*
* External interface.
*/
+extern int temp_utf8_kludge;
extern char *printable(char *, int);
extern char *neuter(char *, const char *, int);
extern char *lowercase(char *);
extern int allspace(const char *);
extern int allascii(const char *);
extern const char *split_nameval(char *, char **, char **);
-extern int valid_utf_8(const char *, ssize_t);
+extern int valid_utf8_string(const char *, ssize_t);
/* LICENSE
/* .ad
--- /dev/null
+/*++
+/* NAME
+/* valid_utf8_hostname 3
+/* SUMMARY
+/* validate (maybe UTF-8) domain name
+/* SYNOPSIS
+/* #include <valid_utf8_hostname.h>
+/*
+/* int valid_utf8_hostname(
+/* int enable_utf8,
+/* const char *domain,
+/* int gripe)
+/* DESCRIPTION
+/* valid_utf8_hostname() is a wrapper around valid_hostname().
+/* If EAI support is compiled in, and enable_utf8 is true, the
+/* name is converted from UTF-8 to ASCII per IDNA rules, before
+/* invoking valid_hostname().
+/* SEE ALSO
+/* valid_hostname(3) STD3 hostname validation.
+/* DIAGNOSTICS
+/* Fatal errors: memory allocation problem.
+/* Warnings: malformed domain name.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+
+ /*
+ * Utility library.
+ */
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <valid_hostname.h>
+#include <midna.h>
+#include <valid_utf8_hostname.h>
+
+/* valid_utf8_hostname - validate internationalized domain name */
+
+int valid_utf8_hostname(int enable_utf8, const char *name, int gripe)
+{
+ const char myname[] = "valid_utf8_hostname";
+ const char *aname;
+ int ret;
+
+ /*
+ * Trivial cases first.
+ */
+ if (*name == 0) {
+ if (gripe)
+ msg_warn("%s: empty domain name", myname);
+ return (0);
+ }
+
+ /*
+ * Convert domain name to ASCII form.
+ */
+#ifndef NO_EAI
+ if (enable_utf8 && !allascii(name)) {
+ if ((aname = midna_utf8_to_ascii(name)) == 0) {
+ if (gripe)
+ msg_warn("%s: malformed UTF-8 domain name", myname);
+ return (0);
+ }
+ } else
+#endif
+ aname = name;
+
+ /*
+ * Validate the name per STD3 (if the IDNA routines didn't already).
+ */
+ ret = valid_hostname(aname, gripe);
+
+ return (ret);
+}
--- /dev/null
+#ifndef _VALID_UTF8_HOSTNAME_H_INCLUDED_
+#define _VALID_UTF8_HOSTNAME_H_INCLUDED_
+
+/*++
+/* NAME
+/* valid_utf8_hostname 3h
+/* SUMMARY
+/* validate (maybe UTF-8) domain name
+/* SYNOPSIS
+/* #include <valid_utf8_hostname.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <valid_hostname.h>
+
+ /*
+ * External interface
+ */
+extern int valid_utf8_hostname(int, const char *, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
/*++
/* NAME
-/* valid_utf_8 3
+/* valid_utf8_string 3
/* SUMMARY
/* predicate if string is valid UTF-8
/* SYNOPSIS
/* #include <stringops.h>
/*
-/* int valid_utf_8(str, len)
+/* int valid_utf8_string(str, len)
/* const char *str;
/* ssize_t len;
/* DESCRIPTION
-/* valid_utf_8() determines if a string satisfies the UTF-8
+/* valid_utf8_string() determines if a string satisfies the UTF-8
/* definition in RFC 3629. That is, it contains proper encodings
/* of code points U+0000..U+10FFFF, excluding over-long encodings
/* and excluding U+D800..U+DFFF surrogates.
#include <stringops.h>
-/* valid_utf_8 - validate string according to RFC 3629 */
+/* valid_utf8_string - validate string according to RFC 3629 */
-int valid_utf_8(const char *str, ssize_t len)
+int valid_utf8_string(const char *str, ssize_t len)
{
const unsigned char *end = (const unsigned char *) str + len;
const unsigned char *cp;
if (UNEXPECTED(c0 < 0xc2)
|| UNEXPECTED(cp + 1 >= end)
/* Require UTF-8 tail byte. */
- || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80))
return (0);
}
/* Three-byte encodings. */
/* Exclude U+D800..U+DFFF. */
|| UNEXPECTED(ch > (c0 == 0xed ? 0x9f : 0xbf))
/* Require UTF-8 tail byte. */
- || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80))
return (0);
}
/* Four-byte encodings. */
/* Exclude code points above U+10FFFF. */
|| UNEXPECTED(ch > (c0 == 0xf4 ? 0x8f : 0xbf))
/* Require UTF-8 tail byte. */
- || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf)
+ || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)
/* Require UTF-8 tail byte. */
- || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80))
return (0);
}
/* Invalid: c0 >= 0xf5 */
VSTRING *buf = vstring_alloc(1);
while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
- vstream_printf("%c", (LEN(buf) && !valid_utf_8(STR(buf), LEN(buf))) ?
+ vstream_printf("%c", (LEN(buf) && !valid_utf8_string(STR(buf), LEN(buf))) ?
'!' : ' ');
vstream_fwrite(VSTREAM_OUT, STR(buf), LEN(buf));
vstream_printf("\n");
verify.o: ../../include/dsn.h
verify.o: ../../include/events.h
verify.o: ../../include/htable.h
-verify.o: ../../include/int_filt.h
verify.o: ../../include/iostuff.h
verify.o: ../../include/mail_conf.h
verify.o: ../../include/mail_params.h
/* .IP "\fBaddress_verify_sender_dependent_default_transport_maps ($sender_dependent_default_transport_maps)\fR"
/* Overrides the sender_dependent_default_transport_maps parameter
/* setting for address verification probes.
+/* SMTPUTF8 CONTROLS
+/* .ad
+/* .fi
+/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
+/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
+/* Enable SMTPUTF8 autodetection for the specified mail origin
+/* classes.
/* MISCELLANEOUS CONTROLS
/* .ad
/* .fi
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
STR(addr), addr_status, now, updated);
post_mail_fopen_async(make_verify_sender_addr(), STR(addr),
- INT_FILT_MASK_NONE,
+ MAIL_SRC_MASK_VERIFY,
DEL_REQ_FLAG_MTA_VRFY,
(VSTRING *) 0,
verify_post_mail_action,
--- /dev/null
+To: jøran@blåbærsyltetøy.gulbrandsen.priv.no
+Subject: test
+
+Blah.
--- /dev/null
+To: jøran@blåbærsyltetøy.gulbrandsen.priv.no.
+Subject: test
+
+Blah.