2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 09:57:34 +00:00

postfix-2.8-20110108

This commit is contained in:
Wietse Venema 2011-01-08 00:00:00 -05:00 committed by Viktor Dukhovni
parent f1d5ce4f05
commit 2d9e8a9da5
43 changed files with 1121 additions and 409 deletions

View File

@ -16326,6 +16326,10 @@ Apologies for any names omitted.
stress-dependent. Files: global/mail_params.h,
proto/postconf.proto.
Compatibility: postscreen_discard_ehlo_keyword(s|maps)
support for compatibility with smtpd_discard_ehlo_keyword(s|maps).
Files: postscreen/postscreen_smtpd.c.
20110102
Feature: STARTTLS support for the postscreen(8) daemon.
@ -16353,7 +16357,7 @@ Apologies for any names omitted.
20110104
Feature: add contact information to each SMTP server reject
message. For example, "smtpd_reject_contact_information =
message. For example, "smtpd_reject_footer =
call 800-555-0101 for assistance", with macro expansion and
with multi-line support. Files: global/mail_params.h,
mantools/postlink, proto/postconf.proto, smtpd/smtpd.c,
@ -16370,3 +16374,35 @@ Apologies for any names omitted.
Seen from outside, Postfix works just as if it has TLS
support built into in smtpd(8). Files: smtpd/smtpd.c,
tls/tls_proxy*.[hc], tlsproxy/tlsproxy.c, util/vstream.[hc].
Bugfix (introduced with the Postfix TLS patch): discard
plaintext following the STARTTLS command or response. This
matters only for the minority of SMTP clients that actually
verify server certificates. Files: smtpd/smtpd.c,
smtp/smtp_proto.c.
20110106:
Non-production: cleaned up the tlsproxy support in the
Postfix SMTP server for stress testing of the tlsproxy
daemon (still #ifdef TLSPROXY). File: smtpd/smtpd.c.
20110107
Cleanup: smtpd_reject_contact_information is renamed to
smtpd_reject_footer, because it can be used for non-contact
information.
Compatibility: postscreen_reject_footer support for
compatibility with smtpd_reject_footer. Files:
global/smtp_reply_footer.[hc], global/mail_conf.[hc],
postscreen/postscreen_expand.c, postscreen/postscreen_send.c,
postscreen/postscreen.c, smtpd/smtpd_chat.c.
Compatibility: postscreen_command_filter support for
compatibility with smtpd_command_filter. Files:
postscreen/postscreen_dict.c, postscreen/postscreen_smtpd.c
Cleanup: postscreen(8) now displays control characters in
PREGREET responses as C-style \letter escapes, instead of
"?". File: postscreen/postscreen_early.c.

View File

@ -197,7 +197,8 @@ elapsed, postscreen(8) logs this as:
Translation: the client at [address]:port sent count bytes before its turn to
speak. This happened time seconds after the postscreen_greet_wait timer was
started. The text is what the client sent (truncated to 100 bytes, and with
non-printable characters replaced with "?").
non-printable characters replaced with C-style escapes such as \r for carriage-
return and \n for newline).
The postscreen_greet_action parameter specifies the action that is taken next.
See "When tests fail before the 220 SMTP server greeting" below.

View File

@ -43,7 +43,7 @@ aren't logged to the maillog file, such as responses to syntax
errors, or unsupported commands.
Example:
smtpd_reject_contact_information = For assistance, call 800-555-0101.
smtpd_reject_footer = For assistance, call 800-555-0101.
Server response:
550-5.5.1 <user@example> Recipient address rejected: User unknown
@ -52,6 +52,10 @@ Server response:
This feature supports macro expansion ($client_address, $localtime,
etc.), as documented in the postconf(5) manpage.
This feature is also supported as postscreen_reject_footer
using the same setting as smtpd_reject_footer by
default.
Incompatibility with snapshot 20110102
======================================

View File

@ -4,6 +4,21 @@ Wish list:
Re-run "make depend" with all plugins enabled.
Make very clear in postscreen manpage and readme that this
program is not to be used against your own mail clients.
Test postscreen on Solaris.
match_list support that does not recompile CIDR patterns
on every call.
tlsproxy(8) should receive TLS preferences from postscreen(8)
and smtpd(8), instead of reading them from main.cf. This
means that many tlsproxy_ parameters become postscreen_
parameters. This also means that tls_server_init() must not
"validate" preferences that are supplied later at
tls_server_start() time, which was dubious design anyway.
anvil rate limit for sasl_username.
Encapsulate nbbio buffer access and update by tlsproxy.
@ -29,9 +44,6 @@ Wish list:
This would apply to postmaster notices and bounce messages
(DKIM), and address verification (BATV).
Replace sscanf() numerical conversions by strto[dl]()
for better error reporting.
As postscreen implements more ESMTP keywords, need to copy
inter-operability features from smtpd to filter keywords
and command syntax.
@ -65,7 +77,7 @@ Wish list:
the same cleanup_service value for receiving remote mail
and for submitting postmaster problem reports. Do we need
separate mumble_cleanup_service_name parameters for "inject",
"notify" and "forward" (with backwards compatinble defaults)?
"notify" and "forward" (with backwards compatible defaults)?
IF/ENDIF support for CIDR tables.

View File

@ -269,7 +269,8 @@ an empty teaser banner: </p>
bytes before its turn to speak. This happened <i>time</i> seconds
after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started. The <i>text</i>
is what the client sent (truncated to 100 bytes, and with non-printable
characters replaced with "?"). </p>
characters replaced with C-style escapes such as \r for carriage-return
and \n for newline). </p>
<p> The <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> parameter specifies the action that
is taken next. See "<a href="#fail_before_220">When tests fail

View File

@ -6811,6 +6811,17 @@ and error commands. </p>
<p> This feature is available in Postfix 2.8. </p>
</DD>
<DT><b><a name="postscreen_command_filter">postscreen_command_filter</a>
(default: $<a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a>)</b></DT><DD>
<p> A mechanism to transform commands from remote SMTP clients.
See <a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a> for further details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
</DD>
<DT><b><a name="postscreen_command_time_limit">postscreen_command_time_limit</a>
@ -7032,6 +7043,18 @@ for details. </p>
Preferably, use <a href="postconf.5.html#postscreen_tls_security_level">postscreen_tls_security_level</a> instead. </p>
</DD>
<DT><b><a name="postscreen_expansion_filter">postscreen_expansion_filter</a>
(default: see "postconf -d" output)</b></DT><DD>
<p> List of characters that are permitted in <a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a>
attribute expansions. See <a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> for further
details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
</DD>
<DT><b><a name="postscreen_forbidden_commands">postscreen_forbidden_commands</a>
@ -7302,6 +7325,17 @@ receive a 421 reponse. </p>
<p> This feature is available in Postfix 2.8. </p>
</DD>
<DT><b><a name="postscreen_reject_footer">postscreen_reject_footer</a>
(default: $<a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a>)</b></DT><DD>
<p> Optional information that is appended after a 4XX or 5XX server
response. See <a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> for further details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
</DD>
<DT><b><a name="postscreen_tls_security_level">postscreen_tls_security_level</a>
@ -13002,64 +13036,79 @@ Example:
</DD>
<DT><b><a name="smtpd_reject_contact_information">smtpd_reject_contact_information</a>
<DT><b><a name="smtpd_reject_footer">smtpd_reject_footer</a>
(default: empty)</b></DT><DD>
<p> Optional contact information that is appended after each SMTP
server 4XX or 5XX response. </p>
<p> Optional information that is appended after each SMTP server
4XX or 5XX response. </p>
<p> Example: </p>
<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
<a href="postconf.5.html#smtpd_reject_contact_information">smtpd_reject_contact_information</a> = For assistance, call 800-555-0101.
<a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> = For assistance, call 800-555-0101.
Please provide the following information in your problem report:
time ($localtime) and client address ($client_address).
time ($localtime), client ($client_address) and server
($server_name).
</pre>
<p> Server response: </p>
<pre>
550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00)
and client address (192.168.1.248).
550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00),
client (192.168.1.248) and server (mail1.example.com).
</pre>
<p> Note: this text is meant to make it easier to find the Postfix
logfile records for a failed SMTP session. The text itself is not
logged to the Postfix server's maillog file. </p>
<p> Note: the above text is meant to make it easier to find the
Postfix logfile records for a failed SMTP session. The text itself
is not logged to the Postfix SMTP server's maillog file. </p>
<p> Be sure to keep the text as short as possible. Long text may
be truncated before it is logged in the senders maillog file, or
before it is returned to the sender in a delivery status notification.
</p>
be truncated before it is logged in the Postfix SMTP server's maillog
file, or before it is returned to the sender in a delivery status
notification. </p>
<p> This feature supports a limited number of $name attributes in
the contact text. These are replaced by their current value for the
the footer text. These are replaced by their current value for the
SMTP session: </p>
<dl>
<dt> client_address </dt> <dd> Client IP address </dd>
<dt> <b>client_address</b> </dt> <dd> The Client IP address that
is logged in the maillog file. </dd>
<dt> client_port </dt> <dd> Client TCP port </dd>
<dt> <b>client_port</b> </dt> <dd> The client TCP port that is
logged in the maillog file. </dd>
<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd
hh:mm:ss) that is logged in the maillog file. </dd>
<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
<dt> sender </dt> <dd> The address in the MAIL FROM command </dd>
<dt> <b>server_name</b> </dt> <dd> The server's <a href="postconf.5.html#myhostname">myhostname</a> value.
This attribute is made available for sites with multiple MTAs
(perhaps behind a load-balancer), where the server name can help
the server support team to quickly find the right log files. </dd>
</dl>
<p> For safety reasons, text that does not match $<a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a>
is censored. </p>
<p> Notes: </p>
<p> This feature supports \n as a request for a line break in the
contact text. Postfix automatically inserts after each line break
the three-digit SMTP reply code (and optional enhanced status code)
from the original Postfix reject message. </p>
<ul>
<li> <p> NOT SUPPORTED are other attributes such as sender, recipient,
or <a href="postconf.5.html">main.cf</a> parameters. </p>
<li> <p> For safety reasons, text that does not match
$<a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> is censored. </p>
</ul>
<p> This feature supports the two-character sequence \n as a request
for a line break in the footer text. Postfix automatically inserts
after each line break the three-digit SMTP reply code (and optional
enhanced status code) from the original Postfix reject message.
</p>
<p> This feature is available in Postfix 2.8 and later. </p>

View File

@ -106,55 +106,59 @@ POSTSCREEN(8) POSTSCREEN(8)
ter value is the empty string.
<b>COMPATIBILITY CONTROLS</b>
<b><a href="postconf.5.html#postscreen_command_filter">postscreen_command_filter</a> ($<a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a>)</b>
A mechanism to transform commands from remote SMTP
clients.
<b><a href="postconf.5.html#postscreen_discard_ehlo_keyword_address_maps">postscreen_discard_ehlo_keyword_address_maps</a> ($<a href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_dis</a>-</b>
<b><a href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">card_ehlo_keyword_address_maps</a>)</b>
Lookup tables, indexed by the remote SMTP client
address, with case insensitive lists of EHLO key-
words (pipelining, starttls, auth, etc.) that the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server will not send in the EHLO
Lookup tables, indexed by the remote SMTP client
address, with case insensitive lists of EHLO key-
words (pipelining, starttls, auth, etc.) that the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server will not send in the EHLO
response to a remote SMTP client.
<b><a href="postconf.5.html#postscreen_discard_ehlo_keywords">postscreen_discard_ehlo_keywords</a> ($<a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_key</a>-</b>
<b><a href="postconf.5.html#smtpd_discard_ehlo_keywords">words</a>)</b>
A case insensitive list of EHLO keywords (pipelin-
ing, starttls, auth, etc.) that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
server will not send in the EHLO response to a
A case insensitive list of EHLO keywords (pipelin-
ing, starttls, auth, etc.) that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
server will not send in the EHLO response to a
remote SMTP client.
<b>TRIAGE PARAMETERS</b>
<b><a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> (ignore)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends a bare newline character, that is, a
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends a bare newline character, that is, a
newline not preceded by carriage return.
<b><a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> (no)</b>
Enable "bare newline" SMTP protocol tests in the
Enable "bare newline" SMTP protocol tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b><a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> (ignore)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client is permanently blacklisted with the
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client is permanently blacklisted with the
<a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter.
<b><a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> (empty)</b>
Network addresses that are permanently blacklisted;
see the <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter for
see the <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter for
possible actions.
<b><a href="postconf.5.html#postscreen_disable_vrfy_command">postscreen_disable_vrfy_command</a> ($<a href="postconf.5.html#disable_vrfy_command">disable_vrfy_command</a>)</b>
Disable the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
Disable the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
daemon.
<b><a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> (ignore)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client's combined DNSBL score is equal to or
greater than a threshold (as defined with the
greater than a threshold (as defined with the
<a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> and <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_thresh</a>-
<a href="postconf.5.html#postscreen_dnsbl_threshold">old</a> parameters).
<b><a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> (empty)</b>
A mapping from actual DNSBL domain name which
includes a secret password, to the DNSBL domain
A mapping from actual DNSBL domain name which
includes a secret password, to the DNSBL domain
name that postscreen will reply with when it
rejects mail.
@ -163,16 +167,16 @@ POSTSCREEN(8) POSTSCREEN(8)
weight factors.
<b><a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a> (1)</b>
The inclusive lower bound for blocking an SMTP
The inclusive lower bound for blocking an SMTP
client, based on its combined DNSBL score as
defined with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter.
defined with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter.
<b><a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> ($<a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>)</b>
List of commands that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server con-
siders in violation of the SMTP protocol.
<b><a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> (ignore)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client speaks before its turn within the time spec-
ified with the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> parameter.
@ -180,157 +184,162 @@ POSTSCREEN(8) POSTSCREEN(8)
The <i>text</i> in the optional "220-<i>text</i>..." server
response that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> sends ahead of the real
Postfix SMTP server's "220 text..." response, in an
attempt to confuse bad SMTP clients so that they
attempt to confuse bad SMTP clients so that they
speak before their turn (pre-greet).
<b><a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> (${stress?2}${stress:6}s)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will wait for
an SMTP client to send a command before its turn,
and for DNS blocklist lookup results to arrive
(default: up to 2 seconds under stress, up to 6
an SMTP client to send a command before its turn,
and for DNS blocklist lookup results to arrive
(default: up to 2 seconds under stress, up to 6
seconds otherwise).
<b><a href="postconf.5.html#postscreen_helo_required">postscreen_helo_required</a> ($<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a>)</b>
Require that a remote SMTP client sends HELO or
Require that a remote SMTP client sends HELO or
EHLO before commencing a MAIL transaction.
<b><a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> (drop)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends non-SMTP commands as specified with
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends non-SMTP commands as specified with
the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> parameter.
<b><a href="postconf.5.html#postscreen_non_smtp_command_enable">postscreen_non_smtp_command_enable</a> (no)</b>
Enable "non-SMTP command" tests in the
Enable "non-SMTP command" tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b><a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a> (enforce)</b>
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends multiple commands instead of sending
one command and waiting for the server to respond.
The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
client sends multiple commands instead of sending
one command and waiting for the server to respond.
<b><a href="postconf.5.html#postscreen_pipelining_enable">postscreen_pipelining_enable</a> (no)</b>
Enable "pipelining" SMTP protocol tests in the
Enable "pipelining" SMTP protocol tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b><a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
Network addresses that are permanently whitelisted,
and that will not be subjected to <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
and that will not be subjected to <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
checks.
<b><a href="postconf.5.html#smtpd_service_name">smtpd_service_name</a> (smtpd)</b>
The internal service that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> forwards
The internal service that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> forwards
allowed connections to.
<b>CACHE CONTROLS</b>
<b><a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> (12h)</b>
The amount of time between <a href="postscreen.8.html"><b>postscreen</b>(8)</a> cache
The amount of time between <a href="postscreen.8.html"><b>postscreen</b>(8)</a> cache
cleanup runs.
<b><a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> (btree:$<a href="postconf.5.html#data_directory">data_directory</a>/ps_cache)</b>
Persistent storage for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server
Persistent storage for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server
decisions.
<b><a href="postconf.5.html#postscreen_cache_retention_time">postscreen_cache_retention_time</a> (7d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache an
expired temporary whitelist entry before it is
expired temporary whitelist entry before it is
removed.
<b><a href="postconf.5.html#postscreen_bare_newline_ttl">postscreen_bare_newline_ttl</a> (30d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "bare newline" SMTP pro-
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "bare newline" SMTP pro-
tocol test.
<b><a href="postconf.5.html#postscreen_dnsbl_ttl">postscreen_dnsbl_ttl</a> (1h)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful DNS blocklist test.
<b><a href="postconf.5.html#postscreen_greet_ttl">postscreen_greet_ttl</a> (1d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful PREGREET test.
<b><a href="postconf.5.html#postscreen_non_smtp_command_ttl">postscreen_non_smtp_command_ttl</a> (30d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "non_smtp_command" SMTP
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "non_smtp_command" SMTP
protocol test.
<b><a href="postconf.5.html#postscreen_pipelining_ttl">postscreen_pipelining_ttl</a> (30d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "pipelining" SMTP proto-
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
results from a successful "pipelining" SMTP proto-
col test.
<b>RESOURCE 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 this length; upon delivery, long lines
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#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a></b>
<b>($<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b>
How many simultaneous connections any client is
How many simultaneous connections any client is
allowed to have with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> daemon.
<b><a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> (20)</b>
The limit on the total number of commands per SMTP
session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol
The limit on the total number of commands per SMTP
session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol
engine.
<b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (${stress?10}${stress:300}s)</b>
The command "read" time limit for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
The command "read" time limit for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
built-in SMTP protocol engine.
<b><a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
The number of clients that can be waiting for ser-
The number of clients that can be waiting for ser-
vice from a real SMTP server process.
<b><a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
The number of non-whitelisted clients that can be
waiting for a decision whether they will receive
The number of non-whitelisted clients that can be
waiting for a decision whether they will receive
service from a real SMTP server process.
<b><a href="postconf.5.html#postscreen_watchdog_timeout">postscreen_watchdog_timeout</a> (10s)</b>
How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
respond to an SMTP client command or to perform a
How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
respond to an SMTP client command or to perform a
cache operation before it is terminated by a built-
in watchdog timer.
<b>STARTTLS CONTROLS</b>
<b><a href="postconf.5.html#postscreen_tls_security_level">postscreen_tls_security_level</a> ($<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a>)</b>
The SMTP TLS security level for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
server; when a non-empty value is specified, this
The SMTP TLS security level for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
server; when a non-empty value is specified, this
overrides the obsolete parameters
<a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> and <a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a>.
<b>OBSOLETE STARTTLS SUPPORT CONTROLS</b>
These parameters are supported for compatibility with
These parameters are supported for compatibility with
<a href="smtpd.8.html"><b>smtpd</b>(8)</a> legacy parameters.
<b><a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> ($<a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a>)</b>
Opportunistic TLS: announce STARTTLS support to
SMTP clients, but do not require that clients use
Opportunistic TLS: announce STARTTLS support to
SMTP clients, but do not require that clients use
TLS encryption.
<b><a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a> ($<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>)</b>
Mandatory TLS: announce STARTTLS support to SMTP
clients, and require that clients use TLS encryp-
Mandatory TLS: announce STARTTLS support to SMTP
clients, and require that clients use TLS encryp-
tion.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#postscreen_expansion_filter">postscreen_expansion_filter</a> (see 'postconf -d' output)</b>
List of characters that are permitted in
<a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a> attribute expansions.
<b><a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a> ($<a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a>)</b>
Optional information that is appended after a 4XX
or 5XX server response.
<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
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
<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
The maximal number of digits after the decimal
point when logging sub-second delay values.
<b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
The location of all postfix administrative com-
The location of all postfix administrative com-
mands.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
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 waits for an incoming connection

View File

@ -647,9 +647,9 @@ SMTPD(8) SMTPD(8)
The list of error classes that are reported to the
postmaster.
<b><a href="postconf.5.html#smtpd_reject_contact_information">smtpd_reject_contact_information</a> (empty)</b>
Optional contact information that is appended after
each SMTP server 4XX or 5XX response.
<b><a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> (empty)</b>
Optional information that is appended after each
SMTP server 4XX or 5XX response.
<b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
Safety net to keep mail queued that would otherwise

View File

@ -3835,6 +3835,11 @@ no need to enforce separate limits on the number of junk commands
and error commands.
.PP
This feature is available in Postfix 2.8.
.SH postscreen_command_filter (default: $smtpd_command_filter)
A mechanism to transform commands from remote SMTP clients.
See smtpd_command_filter for further details.
.PP
This feature is available in Postfix 2.8 and later.
.SH postscreen_command_time_limit (default: ${stress?10}${stress:300}s)
The command "read" time limit for \fBpostscreen\fR(8)'s built-in SMTP
protocol engine. This bounds the time to receive an entire command.
@ -3994,6 +3999,12 @@ for details.
.PP
This feature is available in Postfix 2.8 and later.
Preferably, use postscreen_tls_security_level instead.
.SH postscreen_expansion_filter (default: see "postconf -d" output)
List of characters that are permitted in postscreen_reject_footer
attribute expansions. See smtpd_expansion_filter for further
details.
.PP
This feature is available in Postfix 2.8 and later.
.SH postscreen_forbidden_commands (default: $smtpd_forbidden_commands)
List of commands that the \fBpostscreen\fR(8) server considers in
violation of the SMTP protocol. See smtpd_forbidden_commands for
@ -4149,6 +4160,11 @@ process. When this queue is full, all non-whitelisted clients will
receive a 421 reponse.
.PP
This feature is available in Postfix 2.8.
.SH postscreen_reject_footer (default: $smtpd_reject_footer)
Optional information that is appended after a 4XX or 5XX server
response. See smtpd_reject_footer for further details.
.PP
This feature is available in Postfix 2.8 and later.
.SH postscreen_tls_security_level (default: $smtpd_tls_security_level)
The SMTP TLS security level for the \fBpostscreen\fR(8) server; when
a non-empty value is specified, this overrides the obsolete parameters
@ -8094,9 +8110,9 @@ smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
.fi
.ad
.ft R
.SH smtpd_reject_contact_information (default: empty)
Optional contact information that is appended after each SMTP
server 4XX or 5XX response.
.SH smtpd_reject_footer (default: empty)
Optional information that is appended after each SMTP server
4XX or 5XX response.
.PP
Example:
.PP
@ -8104,9 +8120,10 @@ Example:
.na
.ft C
/etc/postfix/main.cf:
smtpd_reject_contact_information = For assistance, call 800-555-0101.
smtpd_reject_footer = For assistance, call 800-555-0101.
Please provide the following information in your problem report:
time ($localtime) and client address ($client_address).
time ($localtime), client ($client_address) and server
($server_name).
.fi
.ad
.ft R
@ -8116,43 +8133,53 @@ Server response:
.nf
.na
.ft C
550-5.5.1 <user@example> Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00)
and client address (192.168.1.248).
550-5.5.1 <user@example> Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00),
client (192.168.1.248) and server (mail1.example.com).
.fi
.ad
.ft R
.PP
Note: this text is meant to make it easier to find the Postfix
logfile records for a failed SMTP session. The text itself is not
logged to the Postfix server's maillog file.
Note: the above text is meant to make it easier to find the
Postfix logfile records for a failed SMTP session. The text itself
is not logged to the Postfix SMTP server's maillog file.
.PP
Be sure to keep the text as short as possible. Long text may
be truncated before it is logged in the senders maillog file, or
before it is returned to the sender in a delivery status notification.
be truncated before it is logged in the Postfix SMTP server's maillog
file, or before it is returned to the sender in a delivery status
notification.
.PP
This feature supports a limited number of $name attributes in
the contact text. These are replaced by their current value for the
the footer text. These are replaced by their current value for the
SMTP session:
.IP "client_address"
Client IP address
.IP "client_port"
Client TCP port
.IP "localtime"
Server local time (Mmm dd hh:mm:ss)
.IP "recipient"
The address in the RCPT TO command
.IP "sender"
The address in the MAIL FROM command
.IP "\fBclient_address\fR"
The Client IP address that
is logged in the maillog file.
.IP "\fBclient_port\fR"
The client TCP port that is
logged in the maillog file.
.IP "\fBlocaltime\fR"
The server local time (Mmm dd
hh:mm:ss) that is logged in the maillog file.
.IP "\fBserver_name\fR"
The server's myhostname value.
This attribute is made available for sites with multiple MTAs
(perhaps behind a load-balancer), where the server name can help
the server support team to quickly find the right log files.
.PP
For safety reasons, text that does not match $smtpd_expansion_filter
is censored.
Notes:
.IP \(bu
NOT SUPPORTED are other attributes such as sender, recipient,
or main.cf parameters.
.IP \(bu
For safety reasons, text that does not match
$smtpd_expansion_filter is censored.
.PP
This feature supports \en as a request for a line break in the
contact text. Postfix automatically inserts after each line break
the three-digit SMTP reply code (and optional enhanced status code)
from the original Postfix reject message.
This feature supports the two-character sequence \en as a request
for a line break in the footer text. Postfix automatically inserts
after each line break the three-digit SMTP reply code (and optional
enhanced status code) from the original Postfix reject message.
.PP
This feature is available in Postfix 2.8 and later.
.SH smtpd_reject_unlisted_recipient (default: yes)

View File

@ -119,6 +119,8 @@ parameter value is the empty string.
.nf
.ad
.fi
.IP "\fBpostscreen_command_filter ($smtpd_command_filter)\fR"
A mechanism to transform commands from remote SMTP clients.
.IP "\fBpostscreen_discard_ehlo_keyword_address_maps ($smtpd_discard_ehlo_keyword_address_maps)\fR"
Lookup tables, indexed by the remote SMTP client address, with
case insensitive lists of EHLO keywords (pipelining, starttls, auth,
@ -282,6 +284,17 @@ but do not require that clients use TLS encryption.
.IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
Mandatory TLS: announce STARTTLS support to SMTP clients, and
require that clients use TLS encryption.
.SH "TROUBLE SHOOTING CONTROLS"
.na
.nf
.ad
.fi
.IP "\fBpostscreen_expansion_filter (see 'postconf -d' output)\fR"
List of characters that are permitted in postscreen_reject_footer
attribute expansions.
.IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR"
Optional information that is appended after a 4XX or 5XX server
response.
.SH "MISCELLANEOUS CONTROLS"
.na
.nf
@ -295,9 +308,6 @@ The maximal number of digits after the decimal point when logging
sub-second delay values.
.IP "\fBcommand_directory (see 'postconf -d' output)\fR"
The location of all postfix administrative commands.
.IP "\fBipc_timeout (3600s)\fR"
The time limit for sending or receiving information over an internal
communication channel.
.IP "\fBmax_idle (100s)\fR"
The maximum amount of time that an idle Postfix daemon process waits
for an incoming connection before terminating voluntarily.

View File

@ -527,9 +527,9 @@ before-queue content inspection by non_smtpd_milters, header_checks
and body_checks.
.IP "\fBnotify_classes (resource, software)\fR"
The list of error classes that are reported to the postmaster.
.IP "\fBsmtpd_reject_contact_information (empty)\fR"
Optional contact information that is appended after each SMTP
server 4XX or 5XX response.
.IP "\fBsmtpd_reject_footer (empty)\fR"
Optional information that is appended after each SMTP server
4XX or 5XX response.
.IP "\fBsoft_bounce (no)\fR"
Safety net to keep mail queued that would otherwise be returned to
the sender.

View File

@ -666,7 +666,7 @@ while (<>) {
s;\bsmtpd_tls_always_issue_session_ids\b;<a href="postconf.5.html#smtpd_tls_always_issue_session_ids">$&</a>;g;
s;\bsmtpd_tls_wrappermode\b;<a href="postconf.5.html#smtpd_tls_wrappermode">$&</a>;g;
s;\bsmtpd_use_tls\b;<a href="postconf.5.html#smtpd_use_tls">$&</a>;g;
s;\bsmtpd_reject_contact_information\b;<a href="postconf.5.html#smtpd_reject_contact_information">$&</a>;g;
s;\bsmtpd_reject_footer\b;<a href="postconf.5.html#smtpd_reject_footer">$&</a>;g;
s;\btls_daemon_random_bytes\b;<a href="postconf.5.html#tls_daemon_random_bytes">$&</a>;g;
s;\btls_daemon_random_source\b;<a href="postconf.5.html#tls_daemon_random_source">$&</a>;g;
s;\btls_ran[-</Bb>]*\n* *[<Bb>]*dom_bytes\b;<a href="postconf.5.html#tls_random_bytes">$&</a>;g;
@ -954,6 +954,9 @@ while (<>) {
s;\bpostscreen_use_tls\b;<a href="postconf.5.html#postscreen_use_tls">$&</a>;g;
s;\bpostscreen_discard_ehlo_keyword_address_maps\b;<a href="postconf.5.html#postscreen_discard_ehlo_keyword_address_maps">$&</a>;g;
s;\bpostscreen_discard_ehlo_keywords\b;<a href="postconf.5.html#postscreen_discard_ehlo_keywords">$&</a>;g;
s;\bpostscreen_expansion_filter\b;<a href="postconf.5.html#postscreen_expansion_filter">$&</a>;g;
s;\bpostscreen_reject_footer\b;<a href="postconf.5.html#postscreen_reject_footer">$&</a>;g;
s;\bpostscreen_command_filter\b;<a href="postconf.5.html#postscreen_command_filter">$&</a>;g;
s;\btlsproxy_watchdog_timeout\b;<a href="postconf.5.html#tlsproxy_watchdog_timeout">$&</a>;g;
s;\btlsproxy_enforce_tls\b;<a href="postconf.5.html#tlsproxy_enforce_tls">$&</a>;g;

View File

@ -269,7 +269,8 @@ postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
bytes before its turn to speak. This happened <i>time</i> seconds
after the postscreen_greet_wait timer was started. The <i>text</i>
is what the client sent (truncated to 100 bytes, and with non-printable
characters replaced with "?"). </p>
characters replaced with C-style escapes such as \r for carriage-return
and \n for newline). </p>
<p> The postscreen_greet_action parameter specifies the action that
is taken next. See "<a href="#fail_before_220">When tests fail

View File

@ -13822,62 +13822,99 @@ for further details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
%PARAM smtpd_reject_contact_information
%PARAM smtpd_reject_footer
<p> Optional contact information that is appended after each SMTP
server 4XX or 5XX response. </p>
<p> Optional information that is appended after each SMTP server
4XX or 5XX response. </p>
<p> Example: </p>
<pre>
/etc/postfix/main.cf:
smtpd_reject_contact_information = For assistance, call 800-555-0101.
smtpd_reject_footer = For assistance, call 800-555-0101.
Please provide the following information in your problem report:
time ($localtime) and client address ($client_address).
time ($localtime), client ($client_address) and server
($server_name).
</pre>
<p> Server response: </p>
<pre>
550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00)
and client address (192.168.1.248).
550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
550 5.5.1 For assistance, call 800-555-0101. Please provide the
following information in your problem report: time (Jan 4 15:42:00),
client (192.168.1.248) and server (mail1.example.com).
</pre>
<p> Note: this text is meant to make it easier to find the Postfix
logfile records for a failed SMTP session. The text itself is not
logged to the Postfix server's maillog file. </p>
<p> Note: the above text is meant to make it easier to find the
Postfix logfile records for a failed SMTP session. The text itself
is not logged to the Postfix SMTP server's maillog file. </p>
<p> Be sure to keep the text as short as possible. Long text may
be truncated before it is logged in the senders maillog file, or
before it is returned to the sender in a delivery status notification.
</p>
be truncated before it is logged in the Postfix SMTP server's maillog
file, or before it is returned to the sender in a delivery status
notification. </p>
<p> This feature supports a limited number of $name attributes in
the contact text. These are replaced by their current value for the
the footer text. These are replaced by their current value for the
SMTP session: </p>
<dl>
<dt> client_address </dt> <dd> Client IP address </dd>
<dt> <b>client_address</b> </dt> <dd> The Client IP address that
is logged in the maillog file. </dd>
<dt> client_port </dt> <dd> Client TCP port </dd>
<dt> <b>client_port</b> </dt> <dd> The client TCP port that is
logged in the maillog file. </dd>
<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd
hh:mm:ss) that is logged in the maillog file. </dd>
<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
<dt> sender </dt> <dd> The address in the MAIL FROM command </dd>
<dt> <b>server_name</b> </dt> <dd> The server's myhostname value.
This attribute is made available for sites with multiple MTAs
(perhaps behind a load-balancer), where the server name can help
the server support team to quickly find the right log files. </dd>
</dl>
<p> For safety reasons, text that does not match $smtpd_expansion_filter
is censored. </p>
<p> Notes: </p>
<p> This feature supports \n as a request for a line break in the
contact text. Postfix automatically inserts after each line break
the three-digit SMTP reply code (and optional enhanced status code)
from the original Postfix reject message. </p>
<ul>
<li> <p> NOT SUPPORTED are other attributes such as sender, recipient,
or main.cf parameters. </p>
<li> <p> For safety reasons, text that does not match
$smtpd_expansion_filter is censored. </p>
</ul>
<p> This feature supports the two-character sequence \n as a request
for a line break in the footer text. Postfix automatically inserts
after each line break the three-digit SMTP reply code (and optional
enhanced status code) from the original Postfix reject message.
</p>
<p> This feature is available in Postfix 2.8 and later. </p>
%PARAM postscreen_expansion_filter see "postconf -d" output
<p> List of characters that are permitted in postscreen_reject_footer
attribute expansions. See smtpd_expansion_filter for further
details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
%PARAM postscreen_reject_footer $smtpd_reject_footer
<p> Optional information that is appended after a 4XX or 5XX server
response. See smtpd_reject_footer for further details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
%PARAM postscreen_command_filter $smtpd_command_filter
<p> A mechanism to transform commands from remote SMTP clients.
See smtpd_command_filter for further details. </p>
<p> This feature is available in Postfix 2.8 and later. </p>

View File

@ -29,7 +29,8 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \
verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c
match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
smtp_reply_footer.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 \
@ -60,7 +61,8 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \
verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o
match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
smtp_reply_footer.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@ -85,7 +87,7 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
trace.h user_acl.h valid_mailhost_addr.h verify.h verify_clnt.h \
verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \
fold_addr.h header_body_checks.h data_redirect.h match_service.h \
addr_match_list.h
addr_match_list.h smtp_reply_footer.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@ -795,25 +797,8 @@ delivered_hdr.o: quote_822_local.h
delivered_hdr.o: quote_flags.h
delivered_hdr.o: rec_type.h
delivered_hdr.o: record.h
dict_ldap.o: ../../include/argv.h
dict_ldap.o: ../../include/binhash.h
dict_ldap.o: ../../include/dict.h
dict_ldap.o: ../../include/match_list.h
dict_ldap.o: ../../include/match_ops.h
dict_ldap.o: ../../include/msg.h
dict_ldap.o: ../../include/mymalloc.h
dict_ldap.o: ../../include/name_code.h
dict_ldap.o: ../../include/stringops.h
dict_ldap.o: ../../include/sys_defs.h
dict_ldap.o: ../../include/vbuf.h
dict_ldap.o: ../../include/vstream.h
dict_ldap.o: ../../include/vstring.h
dict_ldap.o: cfg_parser.h
dict_ldap.o: db_common.h
dict_ldap.o: dict_ldap.c
dict_ldap.o: dict_ldap.h
dict_ldap.o: mail_conf.h
dict_ldap.o: string_list.h
dict_mysql.o: ../../include/sys_defs.h
dict_mysql.o: dict_mysql.c
dict_pgsql.o: ../../include/sys_defs.h
@ -1444,15 +1429,7 @@ mime_state.o: mail_params.h
mime_state.o: mime_state.c
mime_state.o: mime_state.h
mime_state.o: rec_type.h
mkmap_cdb.o: ../../include/argv.h
mkmap_cdb.o: ../../include/dict.h
mkmap_cdb.o: ../../include/dict_cdb.h
mkmap_cdb.o: ../../include/mymalloc.h
mkmap_cdb.o: ../../include/sys_defs.h
mkmap_cdb.o: ../../include/vbuf.h
mkmap_cdb.o: ../../include/vstream.h
mkmap_cdb.o: ../../include/vstring.h
mkmap_cdb.o: mkmap.h
mkmap_cdb.o: mkmap_cdb.c
mkmap_db.o: ../../include/argv.h
mkmap_db.o: ../../include/dict.h
@ -1829,6 +1806,15 @@ sent.o: sent.c
sent.o: sent.h
sent.o: trace.h
sent.o: verify.h
smtp_reply_footer.o: ../../include/mac_expand.h
smtp_reply_footer.o: ../../include/mac_parse.h
smtp_reply_footer.o: ../../include/msg.h
smtp_reply_footer.o: ../../include/sys_defs.h
smtp_reply_footer.o: ../../include/vbuf.h
smtp_reply_footer.o: ../../include/vstring.h
smtp_reply_footer.o: dsn_util.h
smtp_reply_footer.o: smtp_reply_footer.c
smtp_reply_footer.o: smtp_reply_footer.h
smtp_stream.o: ../../include/iostuff.h
smtp_stream.o: ../../include/msg.h
smtp_stream.o: ../../include/sys_defs.h

View File

@ -22,6 +22,9 @@
/* const char *mail_conf_eval(string)
/* const char *string;
/*
/* const char *mail_conf_eval_once(string)
/* const char *string;
/*
/* const char *mail_conf_lookup_eval(name)
/* const char *name;
/* DESCRIPTION
@ -51,6 +54,11 @@
/* string argument. The result is volatile and should be copied
/* if it is to be used for any appreciable amount of time.
/*
/* mail_conf_eval_once() non-recursively expands any $parameters
/* in the string argument. The result is volatile and should
/* be copied if it is to be used for any appreciable amount
/* of time.
/*
/* mail_conf_lookup_eval() looks up the named parameter, and expands any
/* $parameters in the result. The result is volatile and should be
/* copied if it is to be used for any appreciable amount of time.
@ -201,6 +209,15 @@ const char *mail_conf_eval(const char *string)
return (dict_eval(CONFIG_DICT, string, RECURSIVE));
}
/* mail_conf_eval_once - expand one level of macros in string */
const char *mail_conf_eval_once(const char *string)
{
#define NONRECURSIVE 0
return (dict_eval(CONFIG_DICT, string, NONRECURSIVE));
}
/* mail_conf_lookup - lookup named variable */
const char *mail_conf_lookup(const char *name)

View File

@ -40,6 +40,7 @@ extern void mail_conf_flush(void);
extern void mail_conf_update(const char *, const char *);
extern const char *mail_conf_lookup(const char *);
extern const char *mail_conf_eval(const char *);
extern const char *mail_conf_eval_once(const char *);
extern const char *mail_conf_lookup_eval(const char *);
/*

View File

@ -3423,6 +3423,18 @@ extern bool var_psc_disable_vrfy;
#define DEF_PSC_CCONN_LIMIT "$" VAR_SMTPD_CCONN_LIMIT
extern int var_psc_cconn_limit;
#define VAR_PSC_REJ_FOOTER "postscreen_reject_footer"
#define DEF_PSC_REJ_FOOTER "$" VAR_SMTPD_REJ_FOOTER
extern char *var_psc_rej_footer;
#define VAR_PSC_EXP_FILTER "postscreen_expansion_filter"
#define DEF_PSC_EXP_FILTER "$" VAR_SMTPD_EXP_FILTER
extern char *var_psc_exp_filter;
#define VAR_PSC_CMD_FILTER "postscreen_command_filter"
#define DEF_PSC_CMD_FILTER ""
extern char *var_psc_cmd_filter;
#define VAR_DNSBLOG_DELAY "dnsblog_reply_delay"
#define DEF_DNSBLOG_DELAY "0s"
extern int var_dnsblog_delay;
@ -3557,9 +3569,9 @@ extern bool var_tlsp_tls_set_sessid;
/*
* SMTPD "reject" contact info.
*/
#define VAR_SMTPD_REJ_CONTACT "smtpd_reject_contact_information"
#define DEF_SMTPD_REJ_CONTACT ""
extern char *var_smtpd_rej_contact;
#define VAR_SMTPD_REJ_FOOTER "smtpd_reject_footer"
#define DEF_SMTPD_REJ_FOOTER ""
extern char *var_smtpd_rej_footer;
/* LICENSE
/* .ad

View File

@ -254,6 +254,11 @@ extern char *mail_pathname(const char *, const char *);
#define MAIL_ATTR_CIPHER_USEBITS "cipher_usebits"
#define MAIL_ATTR_CIPHER_ALGBITS "cipher_algbits"
/*
* SMTP reply footer support.
*/
#define MAIL_ATTR_SERVER_NAME "server_name"
/* LICENSE
/* .ad
/* .fi

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20110105"
#define MAIL_RELEASE_DATE "20110108"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT

View File

@ -0,0 +1,166 @@
/*++
/* NAME
/* smtp_reply_footer 3
/* SUMMARY
/* SMTP reply footer text support
/* SYNOPSIS
/* #include <smtp_reply_footer.h>
/*
/* int smtp_reply_footer(buffer, start, template, filter,
/* lookup, context)
/* VSTRING *buffer;
/* ssize_t start;
/* char *template;
/* const char *filter;
/* const char *(*lookup) (const char *name, char *context);
/* char *context;
/* DESCRIPTION
/* smtp_reply_footer() expands a reply template to an existing
/* reply text.
/*
/* Arguments:
/* .IP buffer
/* Result buffer. This should contain a properly formatted
/* one-line or multi-line SMTP reply, with or without the final
/* <CR><LF>. The reply code and optional enhanced status code
/* will be replicated in the footer text. One space character
/* after the SMTP reply code is replaced by '-'. If the existing
/* reply ends in <CR><LF>, the result text will also end in
/* <CR><LF>.
/* .IP start
/* The beginning of the SMTP reply that the footer will be
/* appended to. This supports applications that buffer up
/* multiple responses in one buffer.
/* .IP template
/* Template text, with optional $name attributes that will be
/* expanded. The two-character sequence "\n" is replaced by a
/* line break followed by a copy of the original SMTP reply
/* code and optional enhanced status code.
/* .IP filter
/* The set of characters that are allowed in attribute expansion.
/* .IP lookup
/* Attribute name/value lookup function. The result value must
/* be a null for a name that is not found, otherwise a pointer
/* to null-terminated string.
/* .IP context
/* Call-back context for the lookup function.
/* SEE ALSO
/* mac_expand(3) macro expansion
/* DIAGNOSTICS
/* smtp_reply_footer() returns 0 upon success, -1 if the
/* existing reply text is malformed.
/*
/* Fatal errors: memory allocation problem.
/* 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>
#include <string.h>
#include <ctype.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
/* Global library. */
#include <dsn_util.h>
#include <smtp_reply_footer.h>
/* SLMs. */
#define STR vstring_str
int smtp_reply_footer(VSTRING *buffer, ssize_t start,
char *template,
const char *filter,
MAC_EXP_LOOKUP_FN lookup,
char *context)
{
const char *myname = "smtp_reply_footer";
char *cp;
char *next;
char *end;
ssize_t dsn_len;
int crlf_at_end = 0;
/*
* Sanity check.
*/
if (start < 0 || start > VSTRING_LEN(buffer))
msg_panic("%s: bad start: %ld", myname, (long) start);
if (*template == 0)
msg_panic("%s: empty template", myname);
/*
* Scan and patch the original response. If the response is not what we
* expect, we stop making changes.
*/
for (cp = STR(buffer) + start, end = cp + strlen(cp);;) {
if (!ISDIGIT(cp[0]) || !ISDIGIT(cp[1]) || !ISDIGIT(cp[2])
|| (cp[3] != ' ' && cp[3] != '-'))
return (-1);
cp[3] = '-';
if ((next = strstr(cp, "\r\n")) == 0) {
next = end;
break;
}
cp = next + 2;
if (cp == end) {
crlf_at_end = 1;
break;
}
}
/*
* Truncate text after the first null, and truncate the trailing CRLF.
*/
if (next < vstring_end(buffer))
vstring_truncate(buffer, next - STR(buffer));
/*
* Append the footer text one line at a time. Caution: before we append
* parts from the buffer to itself, we must extend the buffer first,
* otherwise we would have a dangling pointer "read" bug.
*/
dsn_len = dsn_valid(STR(buffer) + start + 4);
for (cp = template, end = cp + strlen(cp);;) {
if ((next = strstr(cp, "\\n")) != 0) {
*next = 0;
} else {
next = end;
}
/* Append a clone of the SMTP reply code. */
vstring_strcat(buffer, "\r\n");
VSTRING_SPACE(buffer, 3);
vstring_strncat(buffer, STR(buffer) + start, 3);
vstring_strcat(buffer, next != end ? "-" : " ");
/* Append a clone of the optional enhanced status code. */
if (dsn_len > 0) {
VSTRING_SPACE(buffer, dsn_len);
vstring_strncat(buffer, STR(buffer) + start + 4, (int) dsn_len);
vstring_strcat(buffer, " ");
}
/* Append one line of footer text. */
mac_expand(buffer, cp, MAC_EXP_FLAG_APPEND, filter, lookup, context);
if (next < end) {
*next = '\\';
cp = next + 2;
} else
break;
}
if (crlf_at_end)
vstring_strcat(buffer, "\r\n");
return (0);
}

View File

@ -0,0 +1,37 @@
#ifndef _SMTP_REPLY_FOOTER_H_INCLUDED_
#define _SMTP_REPLY_FOOTER_H_INCLUDED_
/*++
/* NAME
/* smtp_reply_footer 3h
/* SUMMARY
/* SMTP reply footer text support
/* SYNOPSIS
/* #include <smtp_reply_footer.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <vstring.h>
#include <mac_expand.h>
/*
* External interface.
*/
extern int smtp_reply_footer(VSTRING *, ssize_t, char *, const char *,
MAC_EXP_LOOKUP_FN, 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

View File

@ -2,11 +2,11 @@ SHELL = /bin/sh
SRCS = postscreen.c postscreen_dict.c postscreen_dnsbl.c \
postscreen_early.c postscreen_smtpd.c postscreen_misc.c \
postscreen_state.c postscreen_tests.c postscreen_send.c \
postscreen_starttls.c
postscreen_starttls.c postscreen_expand.c
OBJS = postscreen.o postscreen_dict.o postscreen_dnsbl.o \
postscreen_early.o postscreen_smtpd.o postscreen_misc.o \
postscreen_state.o postscreen_tests.o postscreen_send.o \
postscreen_starttls.o
postscreen_starttls.o postscreen_expand.o
HDRS =
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
@ -78,6 +78,7 @@ postscreen.o: ../../include/mail_params.h
postscreen.o: ../../include/mail_proto.h
postscreen.o: ../../include/mail_server.h
postscreen.o: ../../include/mail_version.h
postscreen.o: ../../include/maps.h
postscreen.o: ../../include/match_list.h
postscreen.o: ../../include/match_ops.h
postscreen.o: ../../include/msg.h
@ -98,6 +99,7 @@ postscreen_dict.o: ../../include/dict.h
postscreen_dict.o: ../../include/dict_cache.h
postscreen_dict.o: ../../include/events.h
postscreen_dict.o: ../../include/htable.h
postscreen_dict.o: ../../include/maps.h
postscreen_dict.o: ../../include/match_list.h
postscreen_dict.o: ../../include/match_ops.h
postscreen_dict.o: ../../include/msg.h
@ -120,6 +122,7 @@ postscreen_dnsbl.o: ../../include/iostuff.h
postscreen_dnsbl.o: ../../include/ip_match.h
postscreen_dnsbl.o: ../../include/mail_params.h
postscreen_dnsbl.o: ../../include/mail_proto.h
postscreen_dnsbl.o: ../../include/maps.h
postscreen_dnsbl.o: ../../include/match_list.h
postscreen_dnsbl.o: ../../include/match_ops.h
postscreen_dnsbl.o: ../../include/msg.h
@ -141,6 +144,7 @@ postscreen_early.o: ../../include/dict_cache.h
postscreen_early.o: ../../include/events.h
postscreen_early.o: ../../include/htable.h
postscreen_early.o: ../../include/mail_params.h
postscreen_early.o: ../../include/maps.h
postscreen_early.o: ../../include/match_list.h
postscreen_early.o: ../../include/match_ops.h
postscreen_early.o: ../../include/msg.h
@ -153,6 +157,28 @@ postscreen_early.o: ../../include/vstream.h
postscreen_early.o: ../../include/vstring.h
postscreen_early.o: postscreen.h
postscreen_early.o: postscreen_early.c
postscreen_expand.o: ../../include/addr_match_list.h
postscreen_expand.o: ../../include/argv.h
postscreen_expand.o: ../../include/attr.h
postscreen_expand.o: ../../include/dict.h
postscreen_expand.o: ../../include/dict_cache.h
postscreen_expand.o: ../../include/events.h
postscreen_expand.o: ../../include/htable.h
postscreen_expand.o: ../../include/iostuff.h
postscreen_expand.o: ../../include/mail_params.h
postscreen_expand.o: ../../include/mail_proto.h
postscreen_expand.o: ../../include/maps.h
postscreen_expand.o: ../../include/match_list.h
postscreen_expand.o: ../../include/match_ops.h
postscreen_expand.o: ../../include/msg.h
postscreen_expand.o: ../../include/string_list.h
postscreen_expand.o: ../../include/stringops.h
postscreen_expand.o: ../../include/sys_defs.h
postscreen_expand.o: ../../include/vbuf.h
postscreen_expand.o: ../../include/vstream.h
postscreen_expand.o: ../../include/vstring.h
postscreen_expand.o: postscreen.h
postscreen_expand.o: postscreen_expand.c
postscreen_misc.o: ../../include/addr_match_list.h
postscreen_misc.o: ../../include/argv.h
postscreen_misc.o: ../../include/dict.h
@ -162,6 +188,7 @@ postscreen_misc.o: ../../include/format_tv.h
postscreen_misc.o: ../../include/htable.h
postscreen_misc.o: ../../include/iostuff.h
postscreen_misc.o: ../../include/mail_params.h
postscreen_misc.o: ../../include/maps.h
postscreen_misc.o: ../../include/match_list.h
postscreen_misc.o: ../../include/match_ops.h
postscreen_misc.o: ../../include/msg.h
@ -180,10 +207,14 @@ postscreen_send.o: ../../include/dict_cache.h
postscreen_send.o: ../../include/events.h
postscreen_send.o: ../../include/htable.h
postscreen_send.o: ../../include/iostuff.h
postscreen_send.o: ../../include/mac_expand.h
postscreen_send.o: ../../include/mac_parse.h
postscreen_send.o: ../../include/mail_params.h
postscreen_send.o: ../../include/maps.h
postscreen_send.o: ../../include/match_list.h
postscreen_send.o: ../../include/match_ops.h
postscreen_send.o: ../../include/msg.h
postscreen_send.o: ../../include/smtp_reply_footer.h
postscreen_send.o: ../../include/string_list.h
postscreen_send.o: ../../include/sys_defs.h
postscreen_send.o: ../../include/vbuf.h
@ -201,6 +232,7 @@ postscreen_smtpd.o: ../../include/events.h
postscreen_smtpd.o: ../../include/htable.h
postscreen_smtpd.o: ../../include/iostuff.h
postscreen_smtpd.o: ../../include/is_header.h
postscreen_smtpd.o: ../../include/lex_822.h
postscreen_smtpd.o: ../../include/mail_params.h
postscreen_smtpd.o: ../../include/mail_proto.h
postscreen_smtpd.o: ../../include/maps.h
@ -230,6 +262,7 @@ postscreen_starttls.o: ../../include/htable.h
postscreen_starttls.o: ../../include/iostuff.h
postscreen_starttls.o: ../../include/mail_params.h
postscreen_starttls.o: ../../include/mail_proto.h
postscreen_starttls.o: ../../include/maps.h
postscreen_starttls.o: ../../include/match_list.h
postscreen_starttls.o: ../../include/match_ops.h
postscreen_starttls.o: ../../include/msg.h
@ -256,6 +289,7 @@ postscreen_state.o: ../../include/htable.h
postscreen_state.o: ../../include/iostuff.h
postscreen_state.o: ../../include/mail_proto.h
postscreen_state.o: ../../include/mail_server.h
postscreen_state.o: ../../include/maps.h
postscreen_state.o: ../../include/match_list.h
postscreen_state.o: ../../include/match_ops.h
postscreen_state.o: ../../include/msg.h
@ -275,6 +309,7 @@ postscreen_tests.o: ../../include/dict_cache.h
postscreen_tests.o: ../../include/events.h
postscreen_tests.o: ../../include/htable.h
postscreen_tests.o: ../../include/mail_params.h
postscreen_tests.o: ../../include/maps.h
postscreen_tests.o: ../../include/match_list.h
postscreen_tests.o: ../../include/match_ops.h
postscreen_tests.o: ../../include/msg.h

View File

@ -101,6 +101,8 @@
/* COMPATIBILITY CONTROLS
/* .ad
/* .fi
/* .IP "\fBpostscreen_command_filter ($smtpd_command_filter)\fR"
/* A mechanism to transform commands from remote SMTP clients.
/* .IP "\fBpostscreen_discard_ehlo_keyword_address_maps ($smtpd_discard_ehlo_keyword_address_maps)\fR"
/* Lookup tables, indexed by the remote SMTP client address, with
/* case insensitive lists of EHLO keywords (pipelining, starttls, auth,
@ -254,6 +256,15 @@
/* .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
/* Mandatory TLS: announce STARTTLS support to SMTP clients, and
/* require that clients use TLS encryption.
/* TROUBLE SHOOTING CONTROLS
/* .ad
/* .fi
/* .IP "\fBpostscreen_expansion_filter (see 'postconf -d' output)\fR"
/* List of characters that are permitted in postscreen_reject_footer
/* attribute expansions.
/* .IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR"
/* Optional information that is appended after a 4XX or 5XX server
/* response.
/* MISCELLANEOUS CONTROLS
/* .ad
/* .fi
@ -265,9 +276,6 @@
/* sub-second delay values.
/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
/* The location of all postfix administrative commands.
/* .IP "\fBipc_timeout (3600s)\fR"
/* The time limit for sending or receiving information over an internal
/* communication channel.
/* .IP "\fBmax_idle (100s)\fR"
/* The maximum amount of time that an idle Postfix daemon process waits
/* for an incoming connection before terminating voluntarily.
@ -353,6 +361,9 @@ char *var_smtpd_banner;
bool var_disable_vrfy_cmd;
bool var_helo_required;
char *var_smtpd_cmd_filter;
char *var_psc_cmd_filter;
char *var_smtpd_forbid_cmds;
char *var_psc_forbid_cmds;
@ -410,9 +421,15 @@ int var_psc_barlf_ttl;
int var_psc_cmd_count;
char *var_psc_cmd_time;
char *var_smtpd_rej_footer;
char *var_psc_rej_footer;
int var_smtpd_cconn_limit;
int var_psc_cconn_limit;
char *var_smtpd_exp_filter;
char *var_psc_exp_filter;
/*
* Global variables.
*/
@ -835,6 +852,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
0, -1,
};
int cache_flags;
const char *tmp;
/*
* This routine runs after the skeleton code has entered the chroot jail.
@ -843,6 +861,24 @@ static void post_jail_init(char *unused_name, char **unused_argv)
*/
var_use_limit = 0;
/*
* Workaround for parameters whose values may contain "$", and that have
* a default of "$parametername". Not sure if it would be a good idea to
* always to this in the mail_conf_raw(3) module.
*/
if (*var_psc_rej_footer == '$'
&& mail_conf_lookup(var_psc_rej_footer + 1)) {
tmp = mail_conf_eval_once(var_psc_rej_footer);
myfree(var_psc_rej_footer);
var_psc_rej_footer = mystrdup(tmp);
}
if (*var_psc_exp_filter == '$'
&& mail_conf_lookup(var_psc_exp_filter + 1)) {
tmp = mail_conf_eval_once(var_psc_exp_filter);
myfree(var_psc_exp_filter);
var_psc_exp_filter = mystrdup(tmp);
}
/*
* Other one-time initialization.
*/
@ -952,6 +988,7 @@ int main(int argc, char **argv)
VAR_SMTPD_EHLO_DIS_WORDS, DEF_SMTPD_EHLO_DIS_WORDS, &var_smtpd_ehlo_dis_words, 0, 0,
VAR_SMTPD_EHLO_DIS_MAPS, DEF_SMTPD_EHLO_DIS_MAPS, &var_smtpd_ehlo_dis_maps, 0, 0,
VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
VAR_SMTPD_CMD_FILTER, DEF_SMTPD_CMD_FILTER, &var_smtpd_cmd_filter, 0, 0,
VAR_PSC_CACHE_MAP, DEF_PSC_CACHE_MAP, &var_psc_cache_map, 0, 0,
VAR_PSC_PREGR_BANNER, DEF_PSC_PREGR_BANNER, &var_psc_pregr_banner, 0, 0,
VAR_PSC_PREGR_ACTION, DEF_PSC_PREGR_ACTION, &var_psc_pregr_action, 1, 0,
@ -968,6 +1005,7 @@ int main(int argc, char **argv)
VAR_PSC_EHLO_DIS_MAPS, DEF_PSC_EHLO_DIS_MAPS, &var_psc_ehlo_dis_maps, 0, 0,
VAR_PSC_DNSBL_REPLY, DEF_PSC_DNSBL_REPLY, &var_psc_dnsbl_reply, 0, 0,
VAR_PSC_TLS_LEVEL, DEF_PSC_TLS_LEVEL, &var_psc_tls_level, 0, 0,
VAR_PSC_CMD_FILTER, DEF_PSC_CMD_FILTER, &var_psc_cmd_filter, 0, 0,
0,
};
static const CONFIG_INT_TABLE int_table[] = {
@ -1007,6 +1045,10 @@ int main(int argc, char **argv)
};
static const CONFIG_RAW_TABLE raw_table[] = {
VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, &var_psc_cmd_time, 1, 0,
VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
VAR_PSC_REJ_FOOTER, DEF_PSC_REJ_FOOTER, &var_psc_rej_footer, 0, 0,
VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
VAR_PSC_EXP_FILTER, DEF_PSC_EXP_FILTER, &var_psc_exp_filter, 1, 0,
0,
};
static const CONFIG_NBOOL_TABLE nbool_table[] = {

View File

@ -26,6 +26,7 @@
*/
#include <addr_match_list.h>
#include <string_list.h>
#include <maps.h>
/*
* Preliminary stuff, to be fixed.
@ -67,6 +68,7 @@ typedef struct {
int read_state; /* command read state machine */
/* smtpd(8) compatibility */
int ehlo_discard_mask; /* EHLO filter */
VSTRING *expand_buf; /* macro expansion */
} PSC_STATE;
#define PSC_TIME_STAMP_NEW (0) /* test was never passed */
@ -384,6 +386,8 @@ extern const char *psc_print_state_flags(int, const char *);
extern int psc_addr_match_list_match(ADDR_MATCH_LIST *, const char *);
extern const char *psc_cache_lookup(DICT_CACHE *, const char *);
extern void psc_cache_update(DICT_CACHE *, const char *, const char *);
const char *psc_dict_get(DICT *, const char *);
const char *psc_maps_find(MAPS *, const char *, int);
/*
* postscreen_dnsbl.c
@ -448,6 +452,13 @@ extern void psc_send_socket(PSC_STATE *);
*/
extern void psc_starttls_open(PSC_STATE *, EVENT_NOTIFY_FN);
/*
* postscreen_expand.c
*/
extern VSTRING *psc_expand_filter;
extern void psc_expand_init(void);
extern const char *psc_expand_lookup(const char *, int, char *);
/* LICENSE
/* .ad
/* .fi

View File

@ -18,6 +18,15 @@
/* DICT_CACHE *cache;
/* const char *key;
/* const char *value;
/*
/* void psc_dict_get(dict, key)
/* DICT *dict;
/* const char *key;
/*
/* void psc_maps_find(maps, key, flags)
/* MAPS *maps;
/* const char *key;
/* int flags;
/* DESCRIPTION
/* This module implements wrappers around time-critical table
/* access functions. The functions log a warning when table
@ -28,6 +37,9 @@
/*
/* psc_cache_lookup() and psc_cache_update() are wrappers around
/* the corresponding dict_cache() methods.
/*
/* psc_dict_get() and psc_maps_find() are wrappers around
/* dict_get() and maps_find(), respectively.
/* LICENSE
/* .ad
/* .fi
@ -46,6 +58,11 @@
/* Utility library. */
#include <msg.h>
#include <dict.h>
/* Global library. */
#include <maps.h>
/* Application-specific. */
@ -105,3 +122,29 @@ void psc_cache_update(DICT_CACHE *cache, const char *key, const char *value)
dict_cache_update(cache, key, value);
PSC_CHECK_TIME_AFTER_LOOKUP(dict_cache_name(cache), "update");
}
/* psc_dict_get - time-critical table lookup */
const char *psc_dict_get(DICT *dict, const char *key)
{
const char *myname = "psc_dict_get";
const char *result;
PSC_GET_TIME_BEFORE_LOOKUP;
result = dict_get(dict, key);
PSC_CHECK_TIME_AFTER_LOOKUP(dict->name, "lookup");
return (result);
}
/* psc_maps_find - time-critical table lookup */
const char *psc_maps_find(MAPS *maps, const char *key, int flags)
{
const char *myname = "psc_maps_find";
const char *result;
PSC_GET_TIME_BEFORE_LOOKUP;
result = maps_find(maps, key, flags);
PSC_CHECK_TIME_AFTER_LOOKUP(maps->title, "lookup");
return (result);
}

View File

@ -48,6 +48,7 @@
#include <postscreen.h>
static char *psc_teaser_greeting;
static VSTRING *psc_escape_buf;
/* psc_early_event - handle pre-greet, EOF, and DNSBL results. */
@ -172,9 +173,10 @@ static void psc_early_event(int event, char *context)
return;
}
read_buf[read_count] = 0;
escape(psc_escape_buf, read_buf, read_count);
msg_info("PREGREET %d after %s from [%s]:%s: %.100s", read_count,
psc_format_delta_time(psc_temp, state->start_time, &elapsed),
PSC_CLIENT_ADDR_PORT(state), printable(read_buf, '?'));
PSC_CLIENT_ADDR_PORT(state), STR(psc_escape_buf));
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_PREGR_FAIL);
switch (psc_pregr_action) {
case PSC_ACT_DROP:
@ -288,5 +290,6 @@ void psc_early_init(void)
if (*var_psc_pregr_banner) {
vstring_sprintf(psc_temp, "220-%s\r\n", var_psc_pregr_banner);
psc_teaser_greeting = mystrdup(STR(psc_temp));
psc_escape_buf = vstring_alloc(100);
}
}

View File

@ -0,0 +1,141 @@
/*++
/* NAME
/* postscreen_expand 3
/* SUMMARY
/* SMTP server macro expansion
/* SYNOPSIS
/* #include <postscreen.h>
/*
/* void psc_expand_init()
/*
/* VSTRING *psc_expand_filter;
/*
/* const char *psc_expand_lookup(name, unused_mode, context)
/* const char *name;
/* int unused_mode;
/* char *context;
/* DESCRIPTION
/* This module expands session-related macros.
/*
/* psc_expand_init() performs one-time initialization
/* of the psc_expand_filter buffer.
/*
/* The psc_expand_filter buffer contains the characters
/* that are allowed in macro expansion, as specified with the
/* psc_expand_filter configuration parameter.
/*
/* psc_expand_lookup() returns the value of the named
/* macro or a null pointer.
/*
/* Arguments:
/* .IP name
/* Macro name.
/* .IP context
/* Call-back context (a PSC_STATE pointer).
/* DIAGNOSTICS
/* Panic: interface violations. Fatal errors: out of memory.
/* internal protocol errors. postscreen_expand() returns the
/* binary OR of MAC_PARSE_ERROR (syntax error) and MAC_PARSE_UNDEF
/* (undefined macro 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>
#include <time.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <stringops.h>
/* Global library. */
#include <mail_params.h>
#include <mail_proto.h>
/* Application-specific. */
#include <postscreen.h>
/*
* Pre-parsed expansion filter.
*/
VSTRING *psc_expand_filter;
/* psc_expand_init - initialize once during process lifetime */
void psc_expand_init(void)
{
/*
* Expand the expansion filter :-)
*/
psc_expand_filter = vstring_alloc(10);
unescape(psc_expand_filter, var_psc_exp_filter);
}
/* psc_expand_lookup - generic SMTP attribute $name expansion */
const char *psc_expand_lookup(const char *name, int unused_mode,
char *context)
{
PSC_STATE *state = (PSC_STATE *) context;
time_t now;
struct tm *lt;
if (state->expand_buf == 0)
state->expand_buf = vstring_alloc(10);
if (msg_verbose > 1)
msg_info("psc_expand_lookup: ${%s}", name);
#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
#define STREQN(x,y,n) (*(x) == *(y) && strncmp((x), (y), (n)) == 0)
#define CONST_LEN(x) (sizeof(x) - 1)
/*
* Don't query main.cf parameters, as the result of expansion could
* reveal system-internal information in server replies.
*
* XXX: This said, multiple servers may be behind a single client-visible
* name or IP address, and each may generate its own logs. Therefore, it
* may be useful to expose the replying MTA id (myhostname) in the
* contact footer, to identify the right logs. So while we don't expose
* the raw configuration dictionary, we do expose "$myhostname" as
* expanded in var_myhostname.
*
* Return NULL only for non-existent names.
*/
if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
return (var_myhostname);
} else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
return (state->smtp_client_addr);
} else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
return (state->smtp_client_port);
} if (STREQ(name, MAIL_ATTR_LOCALTIME)) {
if (time(&now) == (time_t) - 1)
msg_fatal("time lookup failed: %m");
lt = localtime(&now);
VSTRING_RESET(state->expand_buf);
do {
VSTRING_SPACE(state->expand_buf, 100);
} while (strftime(STR(state->expand_buf),
vstring_avail(state->expand_buf),
"%b %d %H:%M:%S", lt) == 0);
return (STR(state->expand_buf));
} else {
msg_warn("unknown macro name \"%s\" in expansion request", name);
return (0);
}
}

View File

@ -58,6 +58,7 @@
/* Global library. */
#include <mail_params.h>
#include <smtp_reply_footer.h>
/* Application-specific. */
@ -74,7 +75,7 @@
int psc_send_reply(PSC_STATE *state, const char *text)
{
int start;
ssize_t start;
int ret;
if (msg_verbose)
@ -87,6 +88,10 @@ int psc_send_reply(PSC_STATE *state, const char *text)
*/
start = VSTRING_LEN(state->send_buf);
vstring_strcat(state->send_buf, text);
if (*var_psc_rej_footer && (*text == '4' || *text == '5'))
smtp_reply_footer(state->send_buf, start, var_psc_rej_footer,
STR(psc_expand_filter), psc_expand_lookup,
(char *) state);
/*
* XXX For soft_bounce support, it is not sufficient to fix replies here.

View File

@ -143,6 +143,7 @@
#include <string_list.h>
#include <maps.h>
#include <ehlo_mask.h>
#include <lex_822.h>
/* TLS library. */
@ -205,6 +206,11 @@ static void psc_smtpd_read_event(int, char *);
static MAPS *psc_ehlo_discard_maps;
static int psc_ehlo_discard_mask;
/*
* Command editing filter.
*/
static DICT *psc_cmd_filter;
/*
* Encapsulation. We must not forget turn off input/timer events when we
* terminate the SMTP protocol engine.
@ -319,8 +325,8 @@ static int psc_ehlo_cmd(PSC_STATE *state, char *args)
* smtpd(8) compatibility: dynamic reply filtering.
*/
if (psc_ehlo_discard_maps != 0
&& (ehlo_words = maps_find(psc_ehlo_discard_maps,
state->smtp_client_addr, 0)) != 0
&& (ehlo_words = psc_maps_find(psc_ehlo_discard_maps,
state->smtp_client_addr, 0)) != 0
&& (discard_mask = ehlo_mask(ehlo_words)) != psc_ehlo_discard_mask) {
if (discard_mask && !(discard_mask & EHLO_MASK_SILENT))
msg_info("[%s]%s: discarding EHLO keywords: %s",
@ -348,13 +354,14 @@ static void psc_starttls_resume(int unused_event, char *context)
PSC_STATE *state = (PSC_STATE *) context;
/*
* Reset SMTP server state if STARTTLS was successful. Todo: reset SASL
* AUTH state. Dovecot responses may change when it knows that a
* connection is encrypted.
* Reset SMTP server state if STARTTLS was successful.
*/
if (state->flags & PSC_STATE_FLAG_USING_TLS) {
PSC_STRING_RESET(state->helo_name);
PSC_STRING_RESET(state->sender);
#ifdef TODO_SASL_AUTH
/* Reset SASL AUTH state. Dovecot responses may change. */
#endif
}
/*
@ -791,11 +798,28 @@ static void psc_smtpd_read_event(int event, char *context)
}
/*
* Terminate the command line, and reset the command buffer write
* pointer and state machine in preparation for the next command. For
* this to work as expected, VSTRING_RESET() must be non-destructive.
* Terminate the command buffer, and apply the last-resort command
* editing workaround.
*/
VSTRING_TERMINATE(state->cmd_buffer);
if (psc_cmd_filter != 0) {
const char *cp;
for (cp = STR(state->cmd_buffer); *cp && IS_SPACE_TAB(*cp); cp++)
/* void */ ;
if ((cp = psc_dict_get(psc_cmd_filter, cp)) != 0) {
msg_info("[%s]:%s: replacing command \"%.100s\" with \"%.100s\"",
state->smtp_client_addr, state->smtp_client_port,
STR(state->cmd_buffer), cp);
vstring_strcpy(state->cmd_buffer, cp);
}
}
/*
* Reset the command buffer write pointer and state machine in
* preparation for the next command. For this to work as expected,
* VSTRING_RESET() must be non-destructive.
*/
state->read_state = PSC_SMTPD_CMD_ST_ANY;
VSTRING_RESET(state->cmd_buffer);
@ -1099,6 +1123,12 @@ void psc_smtpd_init(void)
vstring_sprintf(psc_temp, "421 %s Service unavailable - try again later\r\n",
var_myhostname);
psc_smtpd_421_reply = mystrdup(STR(psc_temp));
/*
* Initialize the reply footer.
*/
if (*var_psc_rej_footer)
psc_expand_init();
}
/* psc_smtpd_pre_jail_init - per-process deep protocol test initialization */
@ -1113,8 +1143,16 @@ void psc_smtpd_pre_jail_init(void)
*
* XXX Bugger. This means we have to restart when the table changes!
*/
psc_ehlo_discard_maps = maps_create(VAR_PSC_EHLO_DIS_MAPS,
var_psc_ehlo_dis_maps,
DICT_FLAG_LOCK);
if (*var_psc_ehlo_dis_maps)
psc_ehlo_discard_maps = maps_create(VAR_PSC_EHLO_DIS_MAPS,
var_psc_ehlo_dis_maps,
DICT_FLAG_LOCK);
psc_ehlo_discard_mask = ehlo_mask(var_psc_ehlo_dis_words);
/*
* Last-resort command editing support.
*/
if (*var_psc_cmd_filter)
psc_cmd_filter = dict_open(var_psc_cmd_filter, O_RDONLY,
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
}

View File

@ -165,6 +165,7 @@ PSC_STATE *psc_new_session_state(VSTREAM *stream,
state->cmd_buffer = 0;
state->read_state = 0;
state->ehlo_discard_mask = 0; /* XXX Should be ~0 */
state->expand_buf = 0;
/*
* Update the stress level.
@ -225,6 +226,8 @@ void psc_free_session_state(PSC_STATE *state)
myfree(state->sender);
if (state->cmd_buffer)
vstring_free(state->cmd_buffer);
if (state->expand_buf)
vstring_free(state->expand_buf);
myfree((char *) state);
if (psc_check_queue_length < 0 || psc_post_queue_length < 0)

View File

@ -849,6 +849,10 @@ static int smtp_start_tls(SMTP_STATE *state)
SMTP_RESP_FAKE(&fake, "4.7.5"),
"Server certificate not verified"));
/* At this point there must not be any pending plaintext. */
vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
/*
* At this point we have to re-negotiate the "EHLO" to reget the
* feature-list.

View File

@ -216,7 +216,6 @@ smtpd.o: smtpd_token.h
smtpd_chat.o: ../../include/argv.h
smtpd_chat.o: ../../include/attr.h
smtpd_chat.o: ../../include/cleanup_user.h
smtpd_chat.o: ../../include/dsn_util.h
smtpd_chat.o: ../../include/int_filt.h
smtpd_chat.o: ../../include/iostuff.h
smtpd_chat.o: ../../include/line_wrap.h
@ -236,6 +235,7 @@ smtpd_chat.o: ../../include/name_mask.h
smtpd_chat.o: ../../include/post_mail.h
smtpd_chat.o: ../../include/rec_type.h
smtpd_chat.o: ../../include/record.h
smtpd_chat.o: ../../include/smtp_reply_footer.h
smtpd_chat.o: ../../include/smtp_stream.h
smtpd_chat.o: ../../include/stringops.h
smtpd_chat.o: ../../include/sys_defs.h

View File

@ -489,9 +489,9 @@
/* and body_checks.
/* .IP "\fBnotify_classes (resource, software)\fR"
/* The list of error classes that are reported to the postmaster.
/* .IP "\fBsmtpd_reject_contact_information (empty)\fR"
/* Optional contact information that is appended after each SMTP
/* server 4XX or 5XX response.
/* .IP "\fBsmtpd_reject_footer (empty)\fR"
/* Optional information that is appended after each SMTP server
/* 4XX or 5XX response.
/* .IP "\fBsoft_bounce (no)\fR"
/* Safety net to keep mail queued that would otherwise be returned to
/* the sender.
@ -1187,7 +1187,7 @@ bool var_smtpd_enforce_tls;
bool var_smtpd_tls_wrappermode;
bool var_smtpd_tls_auth_only;
char *var_smtpd_cmd_filter;
char *var_smtpd_rej_contact;
char *var_smtpd_rej_footer;
#ifdef USE_TLS
char *var_smtpd_relay_ccerts;
@ -3936,10 +3936,51 @@ static void chat_reset(SMTPD_STATE *state, int threshold)
static void smtpd_start_tls(SMTPD_STATE *state)
{
int rate;
int cert_present;
int requirecert;
#ifdef USE_TLSPROXY
/*
* This is non-production code, for tlsproxy(8) load testing only. It
* implements enough to enable some Postfix features that depend on TLS
* encryption.
*
* To insert tlsproxy(8) between this process and the SMTP client, we swap
* the file descriptors between the state->tlsproxy and state->client
* VSTREAMS, so that we don't lose all the user-configurable
* state->client attributes (such as longjump buffers or timeouts).
*
* As we implement tlsproy support in the Postfix SMTP client we should
* develop a usable abstraction that encapsulates this stream plumbing in
* a library module.
*/
vstream_control(state->tlsproxy, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
vstream_control(state->client, VSTREAM_CTL_SWAP_FD, state->tlsproxy,
VSTREAM_CTL_END);
(void) vstream_fclose(state->tlsproxy); /* direct-to-client stream! */
state->tlsproxy = 0;
/*
* After plumbing the plaintext stream, receive the TLS context object.
* For this we must use the same VSTREAM buffer that we also use to
* receive subsequent SMTP commands. The attribute protocol is robust
* enough that an adversary cannot inject their own bogus TLS context
* attributes into the stream.
*/
state->tls_context = tls_proxy_context_receive(state->client);
/*
* XXX Maybe it is better to send this information to tlsproxy(8) when
* requesting service, effectively making a remote tls_server_start()
* call.
*/
requirecert = (var_smtpd_tls_req_ccert && var_smtpd_enforce_tls);
#else /* USE_TLSPROXY */
TLS_SERVER_START_PROPS props;
static char *cipher_grade;
static VSTRING *cipher_exclusions;
int cert_present;
/*
* Wrapper mode uses a dedicated port and always requires TLS.
@ -3976,20 +4017,23 @@ static void smtpd_start_tls(SMTPD_STATE *state)
* Perform the TLS handshake now. Check the client certificate
* requirements later, if necessary.
*/
requirecert = (var_smtpd_tls_req_ccert && var_smtpd_enforce_tls);
state->tls_context =
TLS_SERVER_START(&props,
ctx = smtpd_tls_ctx,
stream = state->client,
log_level = var_smtpd_tls_loglevel,
timeout = var_smtpd_starttls_tmout,
requirecert = (var_smtpd_tls_req_ccert
&& var_smtpd_enforce_tls),
requirecert = requirecert,
serverid = state->service,
namaddr = state->namaddr,
cipher_grade = cipher_grade,
cipher_exclusions = STR(cipher_exclusions),
fpt_dgst = var_smtpd_tls_fpt_dgst);
#endif /* USE_TLSPROXY */
/*
* For new (i.e. not re-used) TLS sessions, increment the client's new
* TLS session rate counter. We enforce the limit here only for human
@ -4034,7 +4078,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
* here. We have a usable TLS session with the client, so no need to
* disable I/O, ... we can even be polite and send "421 ...".
*/
if (props.requirecert && TLS_CERT_IS_TRUSTED(state->tls_context) == 0) {
if (requirecert && TLS_CERT_IS_TRUSTED(state->tls_context) == 0) {
/*
* Fetch and reject the next command (should be EHLO), then
@ -4083,11 +4127,6 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
const char *err;
int rate;
#ifdef USE_TLSPROXY
VSTREAM *proxy_stream;
#endif
if (argc != 1) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 5.5.4 Syntax: STARTTLS");
@ -4117,14 +4156,32 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
smtpd_chat_reply(state, "502 5.5.1 Error: command not implemented");
return (-1);
}
#ifndef USE_TLS_PROXY
#ifdef USE_TLSPROXY
/*
* Note: state->tlsproxy is left open when smtp_flush() calls longjmp(),
* so we garbage-collect the VSTREAM in smtpd_state_reset().
*/
#define PROXY_OPEN_FLAGS \
(TLS_PROXY_FLAG_ROLE_SERVER | TLS_PROXY_FLAG_SEND_CONTEXT)
state->tlsproxy = tls_proxy_open(PROXY_OPEN_FLAGS, state->client,
state->addr, state->port,
var_smtpd_tmout);
if (state->tlsproxy == 0) {
state->error_mask |= MAIL_ERROR_SOFTWARE;
/* RFC 4954 Section 6. */
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
return (-1);
}
#else /* USE_TLSPROXY */
if (smtpd_tls_ctx == 0) {
state->error_mask |= MAIL_ERROR_SOFTWARE;
/* RFC 4954 Section 6. */
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
return (-1);
}
#endif
#endif /* USE_TLSPROXY */
/*
* Enforce TLS handshake rate limit when this client negotiated too many
@ -4148,13 +4205,17 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
smtpd_chat_reply(state,
"454 4.7.0 Error: too many new TLS sessions from %s",
state->namaddr);
#ifdef USE_TLSPROXY
(void) vstream_fclose(state->tlsproxy);
state->tlsproxy = 0;
#endif
return (-1);
}
#ifndef USE_TLSPROXY
smtpd_chat_reply(state, "220 2.0.0 Ready to start TLS");
/* Flush before we switch the stream's read/write routines. */
/* Flush before we switch read/write routines or file descriptors. */
smtp_flush(state->client);
vstream_fpurge(state->client, VSTREAM_PURGE_READ); /* Yay! */
/* At this point there must not be any pending plaintext. */
vstream_fpurge(state->client, VSTREAM_PURGE_BOTH);
/*
* Reset all inputs to the initial state.
@ -4172,73 +4233,6 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
*/
smtpd_start_tls(state);
return (0);
#else /* USE_TLSPROXY */
/*
* This is non-production code, for tlsproxy(8) load testing only. It
* implements enough to enable the Postfix features that depend on TLS
* encryption.
*/
#define PROXY_OPEN_FLAGS \
(TLS_PROXY_FLAG_ROLE_SERVER | TLS_PROXY_FLAG_SEND_CONTEXT)
proxy_stream = tls_proxy_open(PROXY_OPEN_FLAGS, state->client, state->addr,
state->port, var_smtpd_tmout);
if (proxy_stream == 0) {
state->error_mask |= MAIL_ERROR_SOFTWARE;
/* RFC 4954 Section 6. */
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
return (-1);
}
smtpd_chat_reply(state, "220 2.0.0 Ready to start TLS");
smtp_flush(state->client);
vstream_fpurge(state->client, VSTREAM_PURGE_READ);
/*
* Reset all inputs to the initial state.
*
* XXX RFC 2487 does not forbid the use of STARTTLS while mail transfer is
* in progress, so we have to allow it even when it makes no sense.
*/
helo_reset(state);
mail_reset(state);
rcpt_reset(state);
#ifdef USE_SASL_AUTH
if (var_smtpd_sasl_enable) {
if (smtpd_sasl_is_active(state)) {
smtpd_sasl_auth_reset(state);
smtpd_sasl_deactivate(state);
}
smtpd_sasl_activate(state, VAR_SMTPD_SASL_TLS_OPTS,
var_smtpd_sasl_tls_opts);
}
#endif
/*
* To insert tlsproxy(8) between this process and the SMTP client, we
* swap the file descriptors between the proxy_stream and state->client
* VSTREAMS, so that we don't have to worry about loss of all the
* user-configurable state->client attributes (such as longjump buffers).
*/
vstream_control(proxy_stream, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
vstream_control(state->client, VSTREAM_CTL_SWAP_FD, proxy_stream,
VSTREAM_CTL_END);
(void) vstream_fclose(proxy_stream); /* direct-to-client stream! */
/*
* After plumbing the plaintext stream, receive the TLS context object.
* For this we must use the same VSTREAM buffer that we also use to
* receive subsequent SMTP commands.
*
* When the TLS handshake fails, the conversation is in an unknown state.
* There is nothing we can do except to disconnect from the client.
*/
state->tls_context = tls_proxy_state_receive(state->client);
if (state->tls_context == 0)
vstream_longjmp(state->client, SMTP_ERR_EOF);
return (0);
#endif /* USE_TLSPROXY */
}
/* tls_reset - undo STARTTLS */
@ -4254,11 +4248,11 @@ static void tls_reset(SMTPD_STATE *state)
if (vstream_feof(state->client) || vstream_ferror(state->client))
failure = 1;
vstream_fflush(state->client); /* NOT: smtp_flush() */
#ifndef USE_TLSPROXY
#ifdef USE_TLSPROXY
tls_proxy_context_free(state->tls_context);
#else
tls_server_stop(smtpd_tls_ctx, state->client, var_smtpd_starttls_tmout,
failure, state->tls_context);
#else
tls_proxy_state_free(state->tls_context);
#endif
state->tls_context = 0;
}
@ -4379,7 +4373,17 @@ static void smtpd_proto(SMTPD_STATE *state)
#ifdef USE_TLS
if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) {
#ifdef USE_TLSPROXY
msg_fatal("Wrapper-mode is unimplemented.");
/* We garbage-collect the VSTREAM in smtpd_state_reset() */
state->tlsproxy = tls_proxy_open(PROXY_OPEN_FLAGS, state->client,
state->addr, state->port,
var_smtpd_tmout);
if (state->tlsproxy == 0) {
msg_warn("Wrapper-mode request dropped from %s for service %s."
" TLS context initialization failed. For details see"
" earlier warnings in your logs.",
state->namaddr, state->service);
break;
}
#else /* USE_TLSPROXY */
if (smtpd_tls_ctx == 0) {
msg_warn("Wrapper-mode request dropped from %s for service %s."
@ -4388,6 +4392,7 @@ static void smtpd_proto(SMTPD_STATE *state)
state->namaddr, state->service);
break;
}
#endif /* USE_TLSPROXY */
if (var_smtpd_cntls_limit > 0
&& !xclient_allowed
&& anvil_clnt
@ -4401,7 +4406,6 @@ static void smtpd_proto(SMTPD_STATE *state)
break;
}
smtpd_start_tls(state);
#endif /* USE_TLSPROXY */
}
#endif
@ -4517,25 +4521,6 @@ static void smtpd_proto(SMTPD_STATE *state)
smtp_flush(state->client);
#endif
} else {
#ifdef PREGREET
if (*var_stress == 0 && strcmp(state->name, "unknown") == 0) {
smtpd_chat_reply(state, "220-%s", var_smtpd_banner);
smtp_flush(state->client);
if (read_wait(vstream_fileno(state->client), 1) == 0) {
int n = peekfd(vstream_fileno(state->client));
smtpd_chat_query(state);
msg_info("PREGREET %d from %s: %s",
n, state->namaddr, vstring_str(state->buffer));
state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state,
"521 %s ESMTP not accepting connections",
var_myhostname);
/* Not: state->error_count++; */
break;
}
}
#endif
smtpd_chat_reply(state, "220 %s", var_smtpd_banner);
}
}
@ -4587,7 +4572,7 @@ static void smtpd_proto(SMTPD_STATE *state)
for (cp = STR(state->buffer); *cp && IS_SPACE_TAB(*cp); cp++)
/* void */ ;
if ((cp = dict_get(smtpd_cmd_filter, cp)) != 0) {
msg_info("%s: replacing client command \"%s\" with \"%s\"",
msg_info("%s: replacing command \"%.100s\" with \"%.100s\"",
state->namaddr, STR(state->buffer), cp);
vstring_strcpy(state->buffer, cp);
}
@ -4914,6 +4899,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
if (getuid() == 0 || getuid() == var_owner_uid) {
if (var_smtpd_use_tls) {
#ifdef USE_TLS
#ifndef USE_TLSPROXY
TLS_SERVER_INIT_PROPS props;
const char *cert_file;
int have_server_cert;
@ -4980,6 +4966,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
fpt_dgst = var_smtpd_tls_fpt_dgst);
else
msg_warn("No server certs available. TLS won't be enabled");
#endif /* USE_TLSPROXY */
#else
msg_warn("TLS has been selected, but TLS support is not compiled in");
#endif
@ -5260,7 +5247,7 @@ int main(int argc, char **argv)
static const CONFIG_RAW_TABLE raw_table[] = {
VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
VAR_DEF_RBL_REPLY, DEF_DEF_RBL_REPLY, &var_def_rbl_reply, 1, 0,
VAR_SMTPD_REJ_CONTACT, DEF_SMTPD_REJ_CONTACT, &var_smtpd_rej_contact, 0, 0,
VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
0,
};

View File

@ -165,6 +165,9 @@ typedef struct {
* TLS related state.
*/
#ifdef USE_TLS
#ifdef USE_TLSPROXY
VSTREAM *tlsproxy; /* tlsproxy(8) temp. handle */
#endif
TLS_SESS_STATE *tls_context; /* TLS session state */
#endif

View File

@ -83,7 +83,7 @@
#include <mail_addr.h>
#include <post_mail.h>
#include <mail_error.h>
#include <dsn_util.h>
#include <smtp_reply_footer.h>
/* Application-specific. */
@ -147,7 +147,6 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
char *cp;
char *next;
char *end;
ssize_t dsn_len;
/*
* Slow down clients that make errors. Sleep-on-anything slows down
@ -156,48 +155,16 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
if (state->error_count >= var_smtpd_soft_erlim)
sleep(delay = var_smtpd_err_sleep);
/*
* The caller may send multi-line text, so we can't assume that there is
* only one SMTP reply code at the beginning of the response.
*/
va_start(ap, format);
vstring_vsprintf(state->buffer, format, ap);
va_end(ap);
/*
* Append the optional contact footer. Caution: as we append parts from
* the buffer to itself, extend the buffer before updating it, or else we
* have a dangling pointer bug.
*/
if (*var_smtpd_rej_contact
&& (*(cp = STR(state->buffer)) == '4' || *cp == '5')
&& ISDIGIT(cp[1]) && ISDIGIT(cp[2]) && cp[3] == ' ') {
dsn_len = dsn_valid(cp + 4);
for (cp = var_smtpd_rej_contact, end = cp + strlen(cp);;) {
if ((next = strstr(cp, "\\n")) != 0) {
*next = 0;
} else {
next = end;
}
/* Append a clone of the SMTP reply code. */
VSTRING_SPACE(state->buffer, sizeof("\r\n550 "));
vstring_sprintf_append(state->buffer, "\r\n%.3s ",
STR(state->buffer));
/* Append a clone of the optional enhanced status code. */
if (dsn_len > 0) {
VSTRING_SPACE(state->buffer, dsn_len + 1);
vstring_sprintf_append(state->buffer, "%.*s ",
(int) dsn_len, STR(state->buffer) + 4);
}
/* Append the actual contact information. */
smtpd_expand(state, state->buffer, cp, MAC_EXP_FLAG_APPEND);
if (next < end) {
*next = '\\';
cp = next + 2;
} else
break;
}
}
if (*var_smtpd_rej_footer
&& (*(cp = STR(state->buffer)) == '4' || *cp == '5'))
smtp_reply_footer(state->buffer, 0, var_smtpd_rej_footer,
STR(smtpd_expand_filter), smtpd_expand_lookup,
(char *) state);
/* All 5xx replies must have a 5.xx.xx detail code. */
for (cp = STR(state->buffer), end = cp + strlen(STR(state->buffer));;) {
if (var_soft_bounce) {

View File

@ -191,9 +191,18 @@ const char *smtpd_expand_lookup(const char *name, int unused_mode,
* Don't query main.cf parameters, as the result of expansion could
* reveal system-internal information in server replies.
*
* XXX: This said, multiple servers may be behind a single client-visible
* name or IP address, and each may generate its own logs. Therefore, it
* may be useful to expose the replying MTA id (myhostname) in the
* contact footer, to identify the right logs. So while we don't expose
* the raw configuration dictionary, we do expose "$myhostname" as
* expanded in var_myhostname.
*
* Return NULL only for non-existent names.
*/
if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
return (var_myhostname);
} else if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
return (state->namaddr);
} else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
return (state->port);

View File

@ -138,6 +138,9 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
state->dsn_buf = vstring_alloc(100);
state->dsn_orcpt_buf = vstring_alloc(100);
#ifdef USE_TLS
#ifdef USE_TLSPROXY
state->tlsproxy = 0;
#endif
state->tls_context = 0;
#endif
@ -208,4 +211,8 @@ void smtpd_state_reset(SMTPD_STATE *state)
vstring_free(state->dsn_buf);
if (state->dsn_orcpt_buf)
vstring_free(state->dsn_orcpt_buf);
#if (defined(USE_TLS) && defined(USE_TLSPROXY))
if (state->tlsproxy) /* still open after longjmp */
vstream_fclose(state->tlsproxy);
#endif
}

View File

@ -35,10 +35,10 @@
extern VSTREAM *tls_proxy_open(int, VSTREAM *, const char *,
const char *, int);
extern TLS_SESS_STATE *tls_proxy_state_receive(VSTREAM *);
extern void tls_proxy_state_free(TLS_SESS_STATE *);
extern int tls_proxy_print_state(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
extern int tls_proxy_scan_state(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
extern TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *);
extern void tls_proxy_context_free(TLS_SESS_STATE *);
extern int tls_proxy_context_print(ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *);
extern int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
#endif

View File

@ -14,10 +14,10 @@
/* const char *peer_port;
/* int timeout;
/*
/* TLS_SESS_STATE *tls_proxy_state_receive(proxy_stream)
/* TLS_SESS_STATE *tls_proxy_context_receive(proxy_stream)
/* VSTREAM *proxy_stream;
/*
/* void tls_proxy_state_free(tls_context)
/* void tls_proxy_context_free(tls_context)
/* TLS_SESS_STATE *tls_context;
/* DESCRIPTION
/* tls_proxy_open() prepares for inserting the tlsproxy(8)
@ -34,17 +34,17 @@
/* buffer, timeout, etc.). Once the file descriptors are
/* swapped, the proxy stream should be closed.
/*
/* tls_proxy_state_receive() receives the TLS context object
/* tls_proxy_context_receive() receives the TLS context object
/* for the named proxy stream. This function must be called
/* only if the TLS_PROXY_SEND_CONTEXT flag was specified in
/* the tls_proxy_open() call. Note that this TLS context object
/* is not compatible with tls_session_free(). It must be given
/* to tls_proxy_state_free() instead.
/* to tls_proxy_context_free() instead.
/*
/* After this, the proxy_stream is ready for plain-text I/O.
/*
/* tls_proxy_state_free() destroys a TLS context object that
/* was received with tls_proxy_state_receive().
/* tls_proxy_context_free() destroys a TLS context object that
/* was received with tls_proxy_context_receive().
/*
/* Arguments:
/* .IP flags
@ -68,7 +68,7 @@
/* .IP proxy_stream
/* Stream from tls_proxy_open().
/* .IP tls_context
/* TLS session object from tls_proxy_state_receive().
/* TLS session object from tls_proxy_context_receive().
/* LICENSE
/* .ad
/* .fi
@ -188,27 +188,27 @@ VSTREAM *tls_proxy_open(int flags, VSTREAM *peer_stream,
return (tlsproxy_stream);
}
/* tls_proxy_state_receive - receive TLS session object from tlsproxy(8) */
/* tls_proxy_context_receive - receive TLS session object from tlsproxy(8) */
TLS_SESS_STATE *tls_proxy_state_receive(VSTREAM *proxy_stream)
TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *proxy_stream)
{
TLS_SESS_STATE *tls_context;
tls_context = (TLS_SESS_STATE *) mymalloc(sizeof(*tls_context));
if (attr_scan(proxy_stream, ATTR_FLAG_STRICT,
ATTR_TYPE_FUNC, tls_proxy_scan_state, (char *) tls_context,
ATTR_TYPE_FUNC, tls_proxy_context_scan, (char *) tls_context,
ATTR_TYPE_END) != 1) {
tls_proxy_state_free(tls_context);
tls_proxy_context_free(tls_context);
return (0);
} else {
return (tls_context);
}
}
/* tls_proxy_state_free - destroy object from tls_proxy_state_receive() */
/* tls_proxy_context_free - destroy object from tls_proxy_context_receive() */
void tls_proxy_state_free(TLS_SESS_STATE *tls_context)
void tls_proxy_context_free(TLS_SESS_STATE *tls_context)
{
if (tls_context->peer_CN)
myfree(tls_context->peer_CN);

View File

@ -6,18 +6,18 @@
/* SYNOPSIS
/* #include <tls_proxy.h>
/*
/* int tls_proxy_print_state(print_fn, stream, flags, ptr)
/* int tls_proxy_context_print(print_fn, stream, flags, ptr)
/* ATTR_PRINT_MASTER_FN print_fn;
/* VSTREAM *stream;
/* int flags;
/* void *ptr;
/* DESCRIPTION
/* tls_proxy_print_state() writes a TLS_SESS_STATE structure
/* tls_proxy_context_print() writes a TLS_SESS_STATE structure
/* to the named stream using the specified attribute print
/* routine. TLS_SESS_STATE() is meant to be passed as a call-back
/* to attr_print(), thusly:
/*
/* ... ATTR_TYPE_FUNC, tls_proxy_print_state, (void *) tls_context, ...
/* ... ATTR_TYPE_FUNC, tls_proxy_context_print, (void *) tls_context, ...
/* DIAGNOSTICS
/* Fatal: out of memory.
/* LICENSE
@ -50,9 +50,9 @@
#include <tls.h>
#include <tls_proxy.h>
/* tls_proxy_print_state - send TLS session state over stream */
/* tls_proxy_context_print - send TLS session state over stream */
int tls_proxy_print_state(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
int tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
int flags, void *ptr)
{
TLS_SESS_STATE *tp = (TLS_SESS_STATE *) ptr;

View File

@ -6,18 +6,18 @@
/* SYNOPSIS
/* #include <tls_proxy.h>
/*
/* int tls_proxy_scan_state(scan_fn, stream, flags, ptr)
/* int tls_proxy_context_scan(scan_fn, stream, flags, ptr)
/* ATTR_SCAN_MASTER_FN scan_fn;
/* VSTREAM *stream;
/* int flags;
/* void *ptr;
/* DESCRIPTION
/* tls_proxy_scan_state() reads a TLS_SESS_STATE structure
/* tls_proxy_context_scan() reads a TLS_SESS_STATE structure
/* from the named stream using the specified attribute scan
/* routine. tls_proxy_scan_state() is meant to be passed as
/* routine. tls_proxy_context_scan() is meant to be passed as
/* a call-back to attr_scan(), thusly:
/*
/* ... ATTR_TYPE_FUNC, tls_proxy_scan_state, (void *) tls_context, ...
/* ... ATTR_TYPE_FUNC, tls_proxy_context_scan, (void *) tls_context, ...
/* DIAGNOSTICS
/* Fatal: out of memory.
/* LICENSE
@ -50,9 +50,9 @@
#include <tls.h>
#include <tls_proxy.h>
/* tls_proxy_scan_state - receive TLS session state from stream */
/* tls_proxy_context_scan - receive TLS session state from stream */
int tls_proxy_scan_state(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
int flags, void *ptr)
{
TLS_SESS_STATE *tls_context = (TLS_SESS_STATE *) ptr;

View File

@ -469,7 +469,7 @@ static void tlsp_strategy(TLSP_STATE *state)
}
if ((state->req_flags & TLS_PROXY_FLAG_SEND_CONTEXT) != 0
&& (attr_print(state->plaintext_stream, ATTR_FLAG_NONE,
ATTR_TYPE_FUNC, tls_proxy_print_state,
ATTR_TYPE_FUNC, tls_proxy_context_print,
(char *) state->tls_context, ATTR_TYPE_END) != 0
|| vstream_fflush(state->plaintext_stream) != 0)) {
msg_warn("cannot send TLS context: %m");