underlying problem more directly as described next. File:
smtp/smtp_proto.c.
- Safety: with plaintext fallback after failed TLS handshake,
- the Postfix SMTP client defers mail if the server does not
- support SASL over plaintext, while the Postfix SMTP client
- would have attempted to log in with SASL after successful
- TLS handshake. This prevents mail from being rejected with
- insufficient mail relay permission. Files: smtp/smtp_connect.c,
- smtp/smtp_session.c, smtp/smtp_proto.c.
+ Safety: don't fall back to plaintext delivery after failed
+ TLS handshake, when the Postfix SMTP client would have
+ attempted to log in with SASL after successful TLS handshake.
+ This avoids undesirable behavior regardless of whether the
+ server does support SASL over plaintext (unexpected password
+ disclosure) and whether the server doesn't support SASL
+ over plaintext (insufficient mail relay permission). Files:
+ smtp/smtp_connect.c, smtp/smtp_session.c, smtp/smtp_proto.c.
+
+20060720
+
+ Compatibility: replace %% in milter replies by %, and strip
+ single (i.e. invalid) % characters. File: milter/milter8.c.
Wish list:
This is simply the DNS name of the server that the Postfix SMTP client
connects to; this name may be obtained from other DNS lookups, such as
MX lookups or CNAME lookups. Use of the hostname lookup key is
- discouraged; always use the next-hop destination instead.
+ discouraged; always use the next-hop destination instead. The hostname
+ lookup key may not behave as you expect when SMTP connection caching is
+ enabled (with the smtp_connection_cache_destinations or
+ smtp_connection_cache_on_demand configuration parameter). Multiple
+ hostnames may resolve to the same IP address, and the hostname from the
+ SMTP connection cache overrides the hostname that Postfix uses for TLS
+ policy lookup or server certificate verification.
next-hop destination
This is normally the domain portion of the recipient address, but it
may be overridden by information from the transport(5) table, from the
no guarantee that Postfix is connected to the right server. To avoid this
loophole, take all of the following steps:
- 1. Use a dedicated transport for all secure-channel deliveries.
+ 1. Use a dedicated transport that does not cache SMTP connections. Otherwise,
+ the hostname from the SMTP connection cache overrides the hostname that
+ Postfix uses for TLS policy lookup and server certificate verification.
2. Eliminate MX lookups. Specify local transport(5) table entries for
- sensitive domains with explicit smtp:[mailhost] or smtp:[mailhost]:port
- destinations (you can assure security of this table unlike DNS); in the
- smtp_tls_per_site table, specify the value "MUST" for the key [mailhost] or
- smtp:[mailhost]:port. This prevents false hostname information in DNS MX
- records from changing Postfix's notion of the server hostname that is used
- for TLS policy lookup and server certificate verification.
+ sensitive domains with explicit securetls:[mailhost] or securetls:
+ [mailhost]:port destinations (you can assure security of this table unlike
+ DNS). This prevents false hostname information in DNS MX records from
+ changing Postfix's notion of the server hostname that is used for TLS
+ policy lookup and server certificate verification. The "securetls"
+ transport is configured to enforce TLS with peername verification, and to
+ disable the SMTP connection cache which could interfere with enforcement of
+ smtp_tls_per_site policies.
3. Disallow CNAME hostname overrides. In main.cf, specify
"smtp_cname_overrides_servername = no". This prevents false hostname
<dl>
<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS
-name of the server that the Postfix SMTP client connects to; this name
-may be obtained from other DNS lookups, such as MX lookups or CNAME
-lookups. Use of the hostname lookup key is discouraged; always use the
-next-hop destination instead. </dd>
+name of the server that the Postfix SMTP client connects to; this
+name may be obtained from other DNS lookups, such as MX lookups or
+CNAME lookups. Use of the hostname lookup key is discouraged; always
+use the next-hop destination instead. The hostname lookup key may
+not behave as you expect when SMTP connection caching is enabled
+(with the <a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> or
+<a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> configuration parameter). Multiple
+hostnames may resolve to the same IP address, and the hostname from
+the SMTP connection cache overrides the hostname that Postfix uses
+for TLS policy lookup or server certificate verification. </dd>
<dt> next-hop destination </dt> <dd> This is normally the domain portion
of the recipient address, but it may be overridden by information from
<ol>
-<li> <p> Use a dedicated transport for all secure-channel deliveries. </p>
+<li> <p> Use a dedicated transport that does not cache SMTP
+connections. Otherwise, the hostname from the SMTP connection cache
+overrides the hostname that Postfix uses for TLS policy lookup and
+server certificate verification. </p>
<li> <p> Eliminate MX lookups. Specify local <a href="transport.5.html">transport(5)</a> table
-entries for sensitive domains with explicit <a href="smtp.8.html">smtp</a>:[<i>mailhost</i>]
-or <a href="smtp.8.html">smtp</a>:[<i>mailhost</i>]:<i>port</i> destinations (you can assure
-security of this table unlike DNS); in the <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a>
-table, specify the value "MUST" for the key [<i>mailhost</i>] or
-<a href="smtp.8.html">smtp</a>:[<i>mailhost</i>]:<i>port</i>. This prevents false hostname
-information in DNS MX records from changing Postfix's notion of the
-server hostname that is used for TLS policy lookup and server certificate
-verification. </p>
+entries for sensitive domains with explicit securetls:[<i>mailhost</i>]
+or securetls:[<i>mailhost</i>]:<i>port</i> destinations (you can
+assure security of this table unlike DNS). This prevents false
+hostname information in DNS MX records from changing Postfix's
+notion of the server hostname that is used for TLS policy lookup
+and server certificate verification. The "securetls" transport is
+configured to enforce TLS with peername verification, and to disable
+the SMTP connection cache which could interfere with enforcement
+of <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> policies. </p>
<li> <p> Disallow CNAME hostname overrides. In <a href="postconf.5.html">main.cf</a>, specify
"<a href="postconf.5.html#smtp_cname_overrides_servername">smtp_cname_overrides_servername</a> = no". This prevents false hostname
discouraged. Always use the full destination nexthop (enclosed in
[] with a possible ":port" suffix). A recipient domain or MX-enabled
transport next-hop with no port suffix may look like a bare hostname,
-but is still a suitable <i>destination</i>. </p>
+but is still a suitable <i>destination</i>. The hostname lookup key
+may not behave as you expect when SMTP connection caching is enabled
+(see <a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> and
+<a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a>). Different hostnames may resolve
+to the same IP address, and the hostname from the SMTP connection
+cache overrides the hostname that Postfix uses for TLS policy lookup
+and server certificate verification. </p>
<p> Specify a next-hop destination or server hostname on the left-hand
side; no wildcards are allowed. The next-hop destination is either
discouraged. Always use the full destination nexthop (enclosed in
[] with a possible ":port" suffix). A recipient domain or MX-enabled
transport next-hop with no port suffix may look like a bare hostname,
-but is still a suitable \fIdestination\fR.
+but is still a suitable \fIdestination\fR. The hostname lookup key
+may not behave as you expect when SMTP connection caching is enabled
+(see smtp_connection_cache_destinations and
+smtp_connection_cache_on_demand). Different hostnames may resolve
+to the same IP address, and the hostname from the SMTP connection
+cache overrides the hostname that Postfix uses for TLS policy lookup
+and server certificate verification.
.PP
Specify a next-hop destination or server hostname on the left-hand
side; no wildcards are allowed. The next-hop destination is either
<dl>
<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS
-name of the server that the Postfix SMTP client connects to; this name
-may be obtained from other DNS lookups, such as MX lookups or CNAME
-lookups. Use of the hostname lookup key is discouraged; always use the
-next-hop destination instead. </dd>
+name of the server that the Postfix SMTP client connects to; this
+name may be obtained from other DNS lookups, such as MX lookups or
+CNAME lookups. Use of the hostname lookup key is discouraged; always
+use the next-hop destination instead. The hostname lookup key may
+not behave as you expect when SMTP connection caching is enabled
+(with the smtp_connection_cache_destinations or
+smtp_connection_cache_on_demand configuration parameter). Multiple
+hostnames may resolve to the same IP address, and the hostname from
+the SMTP connection cache overrides the hostname that Postfix uses
+for TLS policy lookup or server certificate verification. </dd>
<dt> next-hop destination </dt> <dd> This is normally the domain portion
of the recipient address, but it may be overridden by information from
<ol>
-<li> <p> Use a dedicated transport for all secure-channel deliveries. </p>
+<li> <p> Use a dedicated transport that does not cache SMTP
+connections. Otherwise, the hostname from the SMTP connection cache
+overrides the hostname that Postfix uses for TLS policy lookup and
+server certificate verification. </p>
<li> <p> Eliminate MX lookups. Specify local transport(5) table
-entries for sensitive domains with explicit smtp:[<i>mailhost</i>]
-or smtp:[<i>mailhost</i>]:<i>port</i> destinations (you can assure
-security of this table unlike DNS); in the smtp_tls_per_site
-table, specify the value "MUST" for the key [<i>mailhost</i>] or
-smtp:[<i>mailhost</i>]:<i>port</i>. This prevents false hostname
-information in DNS MX records from changing Postfix's notion of the
-server hostname that is used for TLS policy lookup and server certificate
-verification. </p>
+entries for sensitive domains with explicit securetls:[<i>mailhost</i>]
+or securetls:[<i>mailhost</i>]:<i>port</i> destinations (you can
+assure security of this table unlike DNS). This prevents false
+hostname information in DNS MX records from changing Postfix's
+notion of the server hostname that is used for TLS policy lookup
+and server certificate verification. The "securetls" transport is
+configured to enforce TLS with peername verification, and to disable
+the SMTP connection cache which could interfere with enforcement
+of smtp_tls_per_site policies. </p>
<li> <p> Disallow CNAME hostname overrides. In main.cf, specify
"smtp_cname_overrides_servername = no". This prevents false hostname
discouraged. Always use the full destination nexthop (enclosed in
[] with a possible ":port" suffix). A recipient domain or MX-enabled
transport next-hop with no port suffix may look like a bare hostname,
-but is still a suitable <i>destination</i>. </p>
+but is still a suitable <i>destination</i>. The hostname lookup key
+may not behave as you expect when SMTP connection caching is enabled
+(see smtp_connection_cache_destinations and
+smtp_connection_cache_on_demand). Different hostnames may resolve
+to the same IP address, and the hostname from the SMTP connection
+cache overrides the hostname that Postfix uses for TLS policy lookup
+and server certificate verification. </p>
<p> Specify a next-hop destination or server hostname on the left-hand
side; no wildcards are allowed. The next-hop destination is either
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20060719"
+#define MAIL_RELEASE_DATE "20060720"
#define MAIL_VERSION_NUMBER "2.4"
#ifdef SNAPSHOT
/* milter8_read_resp - receive command code now, receive data later */
static int milter8_read_resp(MILTER8 *milter, int event, unsigned char *command,
- ssize_t *data_len)
+ ssize_t *data_len)
{
UINT32_TYPE len;
ssize_t pkt_len;
#define IN_CONNECT_EVENT(e) ((e) == SMFIC_CONNECT || (e) == SMFIC_HELO)
for (;;) {
+ char *cp;
+ char *rp;
+ char ch;
+
if (milter8_read_resp(milter, event, &cmd, &data_size) != 0)
return (milter->def_reply);
if (msg_verbose)
* Decision: "ddd d.d+.d+ text". This decision is final (i.e.
* Sendmail 8 changes receiver state). Note: the reply may be in
* multi-line SMTP format.
+ *
+ * XXX Sendmail compatibility: sendmail 8 uses the reply as a format
+ * string; therefore any '%' characters in the reply are doubled.
+ * Postfix doesn't use replies as format strings; we replace '%%'
+ * by '%', and remove single (i.e. invalid) '%' characters.
*/
case SMFIR_REPLYCODE:
if (milter8_read_data(milter, data_size,
milter8_conf_error(milter);
return (milter->def_reply);
}
+ if ((rp = cp = strchr(STR(milter->buf), '%')) != 0) {
+ for (;;) {
+ if ((ch = *cp++) == '%')
+ ch = *cp++;
+ *rp++ = ch;
+ if (ch == 0)
+ break;
+ }
+ }
if (IN_CONNECT_EVENT(event)) {
#ifdef LIBMILTER_AUTO_DISCONNECT
milter8_close_stream(milter);
# Reject with text
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c connect -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c helo -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c mail -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c rcpt -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c header -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c eoh -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c body -p inet:9999@127.0.0.1
-./test-milter -C 1 -a "554 5.7.1 Rejected" -c eom -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c connect -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c helo -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c mail -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c rcpt -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c header -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c eoh -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c body -p inet:9999@127.0.0.1
+./test-milter -C 1 -a "554 5.7.1 1% 2%% 3%%%" -c eom -p inet:9999@127.0.0.1
# Tempfail tests
./test-milter -C 1 -a tempfail -c connect -p inet:9999@127.0.0.1
exit(1);
}
break;
-#ifdef SMFIR_INSHEADER
case 'i':
+#ifdef SMFIR_INSHEADER
if (ins_hdr) {
fprintf(stderr, "too many -i options\n");
exit(1);
}
parse_hdr_info(optarg, &ins_idx, &ins_hdr, &ins_val);
- break;
+#else
+ fprintf(stderr, "no libmilter support to insert header\n");
+ exit(1);
#endif
+ break;
case 'p':
if (smfi_setconn(optarg) == MI_FAILURE) {
fprintf(stderr, "smfi_setconn failed\n");
exit(1);
}
break;
-#ifdef SMFIR_CHGHEADER
case 'r':
+#ifdef SMFIR_CHGHEADER
if (chg_hdr) {
fprintf(stderr, "too many -r options\n");
exit(1);
}
parse_hdr_info(optarg, &chg_idx, &chg_hdr, &chg_val);
- break;
+#else
+ fprintf(stderr, "no libmilter support to change header\n");
+ exit(1);
#endif
+ break;
case 'v':
verbose++;
break;