This is the Postfix 3.5 (stable) release.

The stable Postfix release is called postfix-3.5.x where 3=major
release number, 5=minor release number, x=patchlevel.  The stable
release never changes except for patches that address bugs or
emergencies. Patches change the patchlevel and the release date.

New features are developed in snapshot releases. These are called
postfix-3.6-yyyymmdd where yyyymmdd is the release date (yyyy=year,
mm=month, dd=day).  Patches are never issued for snapshot releases;
instead, a new snapshot is released.

The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.

If you upgrade from Postfix 3.3 or earlier, read RELEASE_NOTES-3.4
before proceeding.

License change
---------------

This software is distributed with a dual license: in addition to the
historical IBM Public License 1.0, it is now also distributed with the
more recent Eclipse Public License 2.0. Recipients can choose to take
the software under the license of their choice. Those who are more
comfortable with the IPL can continue with that license.
  
Incompatibility with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
==============================================================

Improvements for outbound SMTP smuggling defense:

- With "cleanup_replace_stray_cr_lf = yes" (the default), the cleanup
  daemon replaces each stray <CR> or <LF> character in message
  content with a space character. The replacement happens before
  any other content management (header/body_checks, Milters, etc).

  This prevents outbound SMTP smuggling, where an attacker uses
  Postfix to send email containing a non-standard End-of-DATA
  sequence, to exploit inbound SMTP smuggling at a vulnerable remote
  SMTP server.

  This also improves the remote evaluation of Postfix-added DKIM
  and other signatures, as the evaluation result will not depend
  on how a remote email server handles stray <CR> or <LF> characters.

This feature applies to all email that Postfix locally or remotely
sends out. It is not allowlisted based on client identity.

Major changes with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
============================================================

Improvements for inbound SMTP smuggling defense:

- Better compatibility: the recommended setting "smtpd_forbid_bare_newline
  = normalize" requires the standard End-of-DATA sequence
  <CR><LF>.<CR><LF>, but allows bare newlines from SMTP clients,
  maintaining more compatibility with existing infrastructure.

- Improved logging for rejected input (it now includes queue ID,
  helo, mail, and rcpt, if available).

- The setting "smtpd_forbid_bare_newline = reject" requires
  that input lines end in <CR><LF>, requires the standard End-of-DATA
  sequence <CR><LF>.<CR><LF>, and rejects a command or message that
  contains a bare newline. To disconnect the client, specify
  "smtpd_forbid_bare_newline_reject_code = 521".

- The Postfix SMTP server no longer strips extra <CR> as in
  <CR><LF>.<CR><CR><LF>, to silence false alarms from test tools
  that send attack sequences that real mail servers cannot send.
  Details at https://www.postfix.org/false-smuggling-claims.html

- The old setting "yes" has become an alias for "normalize".

- The old setting "no" has not changed, and allows SMTP smuggling.

The recommended settings are now:

    # Require the standard End-of-DATA sequence <CR><LF>.<CR><LF>.
    # Otherwise, allow bare <LF> and process it as if the client sent
    # <CR><LF>.
    #
    # This maintains compatibility with many legitimate SMTP client
    # applications that send a mix of standard and non-standard line
    # endings, but will fail to receive email from client implementations
    # that do not terminate DATA content with the standard End-of-DATA
    # sequence <CR><LF>.<CR><LF>.
    #
    # Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
    # The example below allowlists SMTP clients in trusted networks.
    #
    smtpd_forbid_bare_newline = normalize
    smtpd_forbid_bare_newline_exclusions = $mynetworks

Alternative settings:

    # Reject input lines that contain <LF> and log a "bare <LF> received"
    # error. Require that input lines end in <CR><LF>, and require the
    # standard End-of-DATA sequence <CR><LF>.<CR><LF>.
    #
    # This will reject email from SMTP clients that send any non-standard
    # line endings such as web applications, netcat, or load balancer
    # health checks.
    #
    # This will also reject email from services that use BDAT to send
    # MIME text containing a bare newline (RFC 3030 Section 3 requires
    # canonical MIME format for text message types, defined in RFC 2045
    # Sections 2.7 and 2.8).
    #
    # Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
    # The example below allowlists SMTP clients in trusted networks.
    #
    smtpd_forbid_bare_newline = reject
    smtpd_forbid_bare_newline_exclusions = $mynetworks
    #
    # Alternatively, in the case of BDAT violations, BDAT can be selectively
    # disabled with smtpd_discard_ehlo_keyword_address_maps, or globally
    # disabled with smtpd_discard_ehlo_keywords.
    #
    # smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file
    # /path/to/file:
    #     10.0.0.0/24 chunking, silent-discard
    # smtpd_discard_ehlo_keywords = chunking, silent-discard

Major changes with Postfix 3.5.20
=================================

Security: the Postfix SMTP server optionally disconnects remote
SMTP clients that violate RFC 2920 (or 5321) command pipelining
constraints. The server replies with "554 5.5.0 Error: SMTP protocol
synchronization" and logs the unexpected remote SMTP client input.
Specify "smtpd_forbid_unauth_pipelining = yes" to enable. This
feature is enabled by default in Postfix 3.9 and later.

Workaround to limit collateral damage from OS distributions that
crank up security to 11, increasing the number of plaintext email
deliveries. This introduces basic OpenSSL configuration file support,
with two new parameters "tls_config_file" and "tls_config_name".
Details are in the postconf(5) manpage under "tls_config_file" and
"tls_config_name".

Runtime detection of DNSSEC support
-----------------------------------

The Postfix build system will no longer automatically disable DNSSEC
support when it determines that Postfix will use libc-musl. This removes
the earlier libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12,
and 3.5.2.

Now, when a Postfix process requests DNSSEC support (typically, for
Postfix DANE support), the process may do a runtime test to determine if
DNSSEC validation is available. DNSSEC support may be broken because of
local configuration, libc incompatibility, or other infrastructure issues.

Background: DNSSEC validation is needed for Postfix DANE support;
this ensures that Postfix receives TLSA records with secure TLS
server certificate info. When DNSSEC validation is unavailable,
mail deliveries using opportunistic DANE will not be protected by
server certificate info in TLSA records, and mail deliveries using
mandatory DANE will not be made at all.

The dnssec_probe parameter specifies the DNS query type (default:
"ns") and DNS query name (default: ".") that Postfix may use to
determine whether DNSSEC validation is available. Specify an empty
value to disable this feature.

By default, a Postfix process will send a DNSSEC probe after 1) the
process made a DNS query that requested DNSSEC validation, 2) the
process did not receive a DNSSEC validated response to this query
or to an earlier query, and 3) the process did not already send a
DNSSEC probe.

When the DNSSEC probe has no response, or when the response is not
DNSSEC validated, Postfix logs a warning that DNSSEC validation may
be unavailable. Examples:

warning: DNSSEC validation may be unavailable
warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
warning: reason: dnssec_probe 'ns:.' received no response: Server failure

This feature was backported from Postfix 3.6.

libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2
------------------------------------------------------------------
 
Security: this release disables DANE support on Linux systems with
libc-musl, because libc-musl provides no indication whether DNS
responses are authentic. This broke DANE support without a clear
explanation.

Major changes - multiple relayhost in SMTP
------------------------------------------

[Feature 20200111] the Postfix SMTP and LMTP client support a list
of nexthop destinations separated by comma or whitespace. These
destinations will be tried in the specified order.

The list form can be specified in relayhost, transport_maps,
default_transport, and sender_dependent_default_transport_maps.

Examples:
/etc/postfix/main.cf:
    relayhost = foo.example, bar.example
    default_transport = smtp:foo.example, bar.example.

NOTE: this is an SMTP and LMTP client feature. It does not work for
other Postfix delivery agents.

Major changes - certificate access
----------------------------------

[Feature 20190517] Search order support for check_ccert_access.
Search order support for other tables is in design (canonical_maps,
virtual_alias_maps, transport_maps, etc.).

The following check_ccert_access setting uses the built-in search
order: it first looks up the client certificate fingerprint, then
the client certificate public-key fingerprint, and it stops when a
decision is made.

/etc/postfix/main.cf:
    smtpd_mumble_restrictions =
        ...
        check_ccert_access hash:/etc/postfix/ccert-access
        ...

The following setting, with explicit search order, produces the
exact same result:

/etc/postfix/main.cf:
    smtpd_mumble_restrictions =
        ...
        check_ccert_access {
            hash:/etc/postfix/ccert-access {
                search_order = cert_fingerprint, pubkey_fingerprint } }
        ...

Support is planned for other certificate features.

Major changes - dovecot usability
---------------------------------

[Feature 20190615] The SMTP+LMTP delivery agent can now prepend
Delivered-To, X-Original-To and Return-Path headers, just like the
pipe(8) and local(8) delivery agents. 

This uses the "flags=DORX" command-line flags in master.cf. See the
smtp(8) manpage for details.

This obsoletes the "lmtp_assume_final = yes" setting, and replaces
it with "flags=...X...", for consistency with the pipe(8) delivery
agent.

Major changes - forced expiration
---------------------------------

[Feature 20200202] Support to force-expire email messages. This
introduces new postsuper(1) command-line options to request expiration,
and additional information in mailq(1) or postqueue(1) output.

The forced-to-expire status is stored in a queue file attribute.
An expired message is returned to the sender when the queue manager
attempts to deliver that message (note that Postfix will never
deliver messages in the hold queue).

The postsuper(1) -e and -f options both set the forced-to-expire
queue file attribute. The difference is that -f will also release
a message if it is in the hold queue. With -e, such a message would
not be returned to the sender until it is released with -f or -H.

In the mailq(1) or postqueue(1) -p output, a forced-to-expire message
is indicated with # after the queue file name. In postqueue(1) JSON
output, there is a new per-message field "forced_expire" (with value
true or false) that shows the forced-to-expire status.

Major changes - haproxy2 protocol
---------------------------------

[Feature 20200112] Support for the haproxy v2 protocol. The Postfix
implementation supports TCP over IPv4 and IPv6, as well as non-proxied
connections; the latter are typically used for heartbeat tests.

The haproxy v2 protocol introduces no additional Postfix configuration.
The Postfix smtpd(8) and postscreen(8) daemons accept both v1 and
v2 protocol versions.

Major changes - logging
-----------------------

[Incompat 20191109] Postfix daemon processes now log the from= and
to= addresses in external (quoted) form in non-debug logging (info,
warning, etc.).  This means that when an address localpart contains
spaces or other special characters, the localpart will be quoted,
for example:

    from=<"name with spaces"@example.com>

Older Postfix versions would log the internal (unquoted) form:

    from=<name with spaces@example.com>

The external and internal forms are identical for the vast majority
of email addresses that contain no spaces or other special characters
in the localpart.

Specify "info_log_address_format = internal" for backwards
compatibility.

The logging in external form is consistent with the address form
that Postfix 3.2 and later prefer for table lookups. It is therefore
the more useful form for non-debug logging.

Major changes - IP address normalization
----------------------------------------

[Incompat 20190427] Postfix now normalizes IP addresses received
with XCLIENT, XFORWARD, or with the HaProxy protocol, for consistency
with direct connections to Postfix. This may change the appearance
of logging, and the way that check_client_access will match subnets
of an IPv6 address.
