Roessner. Files: util/nbbio.[hc], tlsproxy/*.[hc],
postscreen/postscreen_starttlsd.c, postscreen/postscreen_smtpd.c.
-20101103
+20110103
Cleanup: missing tls_level support in tlsproxy (it has no
way to send plaintext, but perhaps an informative error
Cleanup: simplified the handling of throttled output (i.e.
output that can't be sent because the receiver tries to be
nasty). File: postscreen/postscreen_send.c.
+
+20110104
+
+ Feature: add contact information to each SMTP server reject
+ message. For example, "smtpd_reject_contact_information =
+ 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,
+ smtpd/smtpd_chat.c, smtpd/smtpd_expand.[hc], util/mac_expand.[hc].
+
+20110105
+
+ Cleanup: the forest of TLS-related booleans was shrunk.
+ Victor Duchovni. Files: smtpd/smtpd.c, postscreen/postscreen.c,
+ postscreen/postscreen_smtpd.c, tlsproxy/tlsproxy.c.
+
+ Non-production: tlsproxy support in the Postfix SMTP server
+ for stress testing of the tlsproxy daemon (#ifdef TLSPROXY).
+ 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].
default). Other postscreen parameters always evaluate as if the
stress value is equal to the empty string.
+Major changes with snapshot 20110105
+====================================
+
+The SMTP server now supports contact information that is appended
+to "reject" responses. This includes SMTP server responses that
+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.
+
+Server response:
+ 550-5.5.1 <user@example> Recipient address rejected: User unknown
+ 550 5.5.1 For assistance, call 800-555-0101.
+
+This feature supports macro expansion ($client_address, $localtime,
+etc.), as documented in the postconf(5) manpage.
+
Incompatibility with snapshot 20110102
======================================
with buggy SMTP implementations in network appliances). The logging
function alone is already useful for research.
-postscreen(8) can be configured to drop clients that start talking
-too soon, or clients that appear on DNS blocklists. For details,
-see below.
-
postscreen(8) has been tested on FreeBSD and Linux systems. It
probably needs additional work before it can be used on Solaris.
-This snapshot adds three new entries to the master.cf file.
-
-To enable the postscreen(8) service and log client information
-without blocking mail:
-
-1 - Comment out the "smtp inet ... smtpd" service in master.cf,
- including any "-o parameter=value" entries that follow.
-
-2 - Uncomment the new "smtpd pass ... smtpd" service in master.cf,
- and duplicate any "-o parameter=value" entries from the smtpd
- service that was commented out in step 1.
-
-3 - Uncomment the the new "smtp inet ... postscreen" service in
- master.cf.
-
-4 - Uncomment the new "dnsblog unix ... dnsblog" service in
- master.cf. This service does DNSBL lookups for postscreen(8)
- and logs results.
-
-5 - To enable DNSBL lookups, list some DNS blocklist sites in
- main.cf, e.g., "postscreen_dnsbl_sites = zen.spamhaus.org".
- Separate domain names with comma or whitespace.
-
-Note: you must stop and start the master daemon. This is needed
-because the Postfix "pass" master service type did not work reliably
-on all systems.
-
-To use the postscreen(8) service to block mail, edit main.cf and
-specify one or more of:
-
-- "postscreen_greet_action = drop", to drop clients that talk before
- their turn. This alone stops about one third of all known-to-be
- illegitimate connections to Wietse's mail server.
-
-- "postscreen_hangup_action = drop", to waste no time on clients
- that hang up without sending a command. On Wietse's server, only
- one percent of illegitimate connections behaves like this.
-
-- "postscreen_dnsbl_action = drop", to drop clients that are on DNS
- blocklists. Different blocklists cover different client categories.
-
-There is also support for permanent blacklists and whitelists; see
-the postscreen(8) manual page for details.
-
-Note: right now, postscreen(8) "drop" actions disconnect the client
-without reporting sender and recipient information. In a future
-implementation, the connection may instead be passed to a dummy
-SMTP protocol engine that logs sender and recipient information
-before dropping the connection.
Remove this file from the stable release.
+ Re-run "make depend" with all plugins enabled.
+
anvil rate limit for sasl_username.
Encapsulate nbbio buffer access and update by tlsproxy.
</pre>
+</DD>
+
+<DT><b><a name="smtpd_reject_contact_information">smtpd_reject_contact_information</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional contact 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.
+ Please provide the following information in your problem report:
+ time ($localtime) and client address ($client_address).
+</pre>
+
+<p> Server response: </p>
+
+<pre>
+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).
+</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> 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>
+
+<p> This feature supports a limited number of $name attributes in
+the contact text. These are replaced by their current value for the
+SMTP session: </p>
+
+<dl>
+
+<dt> client_address </dt> <dd> Client IP address </dd>
+
+<dt> client_port </dt> <dd> Client TCP port </dd>
+
+<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </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>
+
+</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> 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>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+
</DD>
<DT><b><a name="smtpd_reject_unlisted_recipient">smtpd_reject_unlisted_recipient</a>
Postfix SMTP server uses for TLS encrypted SMTP
sessions.
- <b><a href="postconf.5.html#smtpd_starttls_timeout">smtpd_starttls_timeout</a> (300s)</b>
+ <b><a href="postconf.5.html#smtpd_starttls_timeout">smtpd_starttls_timeout</a> (see 'postconf -d' output)</b>
The time limit for Postfix SMTP server write and
read operations during TLS startup and shutdown
handshake procedures.
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#soft_bounce">soft_bounce</a> (no)</b>
Safety net to keep mail queued that would otherwise
be returned to the sender.
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtpd_authorized_xclient_hosts">smtpd_authorized_xclient_hosts</a> (empty)</b>
- What SMTP clients are allowed to use the XCLIENT
+ What SMTP clients are allowed to use the XCLIENT
feature.
<b>KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS</b>
- As of Postfix version 2.0, the SMTP server rejects mail
- for unknown recipients. This prevents the mail queue from
- clogging up with undeliverable MAILER-DAEMON messages.
- Additional information on this topic is in the
+ As of Postfix version 2.0, the SMTP server rejects mail
+ for unknown recipients. This prevents the mail queue from
+ clogging up with undeliverable MAILER-DAEMON messages.
+ Additional information on this topic is in the
<a href="LOCAL_RECIPIENT_README.html">LOCAL_RECIPIENT_README</a> and <a href="ADDRESS_CLASS_README.html">ADDRESS_CLASS_README</a> documents.
<b><a href="postconf.5.html#show_user_unknown_table_name">show_user_unknown_table_name</a> (yes)</b>
- Display the name of the recipient table in the
+ Display the name of the recipient table in the
"User unknown" responses.
<b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
- Optional address mapping lookup tables for message
+ Optional address mapping lookup tables for message
headers and envelopes.
<b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
<b><a href="postconf.5.html#mydestination">mydestination</a> ($<a href="postconf.5.html#myhostname">myhostname</a>, localhost.$<a href="postconf.5.html#mydomain">mydomain</a>, local-</b>
<b>host)</b>
- The list of domains that are delivered via the
+ The list of domains that are delivered via the
$<a href="postconf.5.html#local_transport">local_transport</a> mail delivery transport.
<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
The network interface addresses that this mail sys-
- tem receives mail on by way of a proxy or network
+ tem receives mail on by way of a proxy or network
address translation unit.
<b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (ipv4)</b>
- The Internet protocols Postfix will attempt to use
+ The Internet protocols Postfix will attempt to use
when making or accepting connections.
<b><a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a> (<a href="proxymap.8.html">proxy</a>:unix:passwd.byname</b>
<b>$<a href="postconf.5.html#alias_maps">alias_maps</a>)</b>
- Lookup tables with all names or addresses of local
- recipients: a recipient address is local when its
- domain matches $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or
+ Lookup tables with all names or addresses of local
+ recipients: a recipient address is local when its
+ domain matches $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or
$<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
<b><a href="postconf.5.html#unknown_local_recipient_reject_code">unknown_local_recipient_reject_code</a> (550)</b>
- The numerical Postfix SMTP server response code
- when a recipient address is local, and
- $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a> specifies a list of lookup
+ The numerical Postfix SMTP server response code
+ when a recipient address is local, and
+ $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a> specifies a list of lookup
tables that does not match the recipient.
- Parameters concerning known/unknown recipients of relay
+ Parameters concerning known/unknown recipients of relay
destinations:
<b><a href="postconf.5.html#relay_domains">relay_domains</a> ($<a href="postconf.5.html#mydestination">mydestination</a>)</b>
- What destination domains (and subdomains thereof)
+ What destination domains (and subdomains thereof)
this system will relay mail to.
<b><a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> (empty)</b>
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $<a href="postconf.5.html#relay_domains">relay_domains</a>.
<b><a href="postconf.5.html#unknown_relay_recipient_reject_code">unknown_relay_recipient_reject_code</a> (550)</b>
The numerical Postfix SMTP server reply code when a
- recipient address matches $<a href="postconf.5.html#relay_domains">relay_domains</a>, and
- <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> specifies a list of lookup
+ recipient address matches $<a href="postconf.5.html#relay_domains">relay_domains</a>, and
+ <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> specifies a list of lookup
tables that does not match the recipient address.
- Parameters concerning known/unknown recipients in virtual
+ Parameters concerning known/unknown recipients in virtual
alias domains:
<b><a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a> ($<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a>)</b>
Postfix is final destination for the specified list
- of virtual alias domains, that is, domains for
- which all addresses are aliased to addresses in
+ of virtual alias domains, that is, domains for
+ which all addresses are aliased to addresses in
other local or remote domains.
<b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> ($<a href="postconf.5.html#virtual_maps">virtual_maps</a>)</b>
- Optional lookup tables that alias specific mail
- addresses or domains to other local or remote
+ Optional lookup tables that alias specific mail
+ addresses or domains to other local or remote
address.
<b><a href="postconf.5.html#unknown_virtual_alias_reject_code">unknown_virtual_alias_reject_code</a> (550)</b>
The SMTP server reply code when a recipient address
- matches $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>, and $<a href="postconf.5.html#virtual_alias_maps">vir</a>-
- <a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a> specifies a list of lookup tables
+ matches $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>, and $<a href="postconf.5.html#virtual_alias_maps">vir</a>-
+ <a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a> specifies a list of lookup tables
that does not match the recipient address.
- Parameters concerning known/unknown recipients in virtual
+ Parameters concerning known/unknown recipients in virtual
mailbox domains:
<b><a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> ($<a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a>)</b>
Postfix is final destination for the specified list
- of domains; mail is delivered via the $<a href="postconf.5.html#virtual_transport">vir</a>-
+ of domains; mail is delivered via the $<a href="postconf.5.html#virtual_transport">vir</a>-
<a href="postconf.5.html#virtual_transport">tual_transport</a> mail delivery transport.
<b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> (empty)</b>
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>.
<b><a href="postconf.5.html#unknown_virtual_mailbox_reject_code">unknown_virtual_mailbox_reject_code</a> (550)</b>
The SMTP server reply code when a recipient address
- matches $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>, and $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
+ matches $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>, and $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
<a href="postconf.5.html#virtual_mailbox_maps">tual_mailbox_maps</a> specifies a list of lookup tables
that does not match the recipient address.
<b>RESOURCE AND RATE CONTROLS</b>
- The following parameters limit resource usage by the SMTP
+ The following parameters limit resource usage by the SMTP
server and/or control client request rates.
<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#queue_minfree">queue_minfree</a> (0)</b>
- The minimal amount of free space in bytes in the
+ The minimal amount of free space in bytes in the
queue file system that is needed to receive mail.
<b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
- The maximal size in bytes of a message, including
+ The maximal size in bytes of a message, including
envelope information.
<b><a href="postconf.5.html#smtpd_recipient_limit">smtpd_recipient_limit</a> (1000)</b>
- The maximal number of recipients that the Postfix
+ The maximal number of recipients that the Postfix
SMTP server accepts per message delivery request.
<b><a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> (normal: 300s, overload: 10s)</b>
- The time limit for sending a Postfix SMTP server
- response and for receiving a remote SMTP client
+ The time limit for sending a Postfix SMTP server
+ response and for receiving a remote SMTP client
request.
<b><a href="postconf.5.html#smtpd_history_flush_threshold">smtpd_history_flush_threshold</a> (100)</b>
- The maximal number of lines in the Postfix SMTP
- server command history before it is flushed upon
+ The maximal number of lines in the Postfix SMTP
+ server command history before it is flushed upon
receipt of EHLO, RSET, or end of DATA.
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#smtpd_peername_lookup">smtpd_peername_lookup</a> (yes)</b>
Attempt to look up the remote SMTP client hostname,
- and verify that the name matches the client IP
+ and verify that the name matches the client IP
address.
The per SMTP client connection count and request rate lim-
its are implemented in co-operation with the <a href="anvil.8.html"><b>anvil</b>(8)</a> ser-
- vice, and are available in Postfix version 2.2 and later.
+ vice, and are available in Postfix version 2.2 and later.
<b><a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a> (50)</b>
- How many simultaneous connections any client is
+ How many simultaneous connections any client is
allowed to make to this service.
<b><a href="postconf.5.html#smtpd_client_connection_rate_limit">smtpd_client_connection_rate_limit</a> (0)</b>
The maximal number of connection attempts any
- client is allowed to make to this service per time
+ client is allowed to make to this service per time
unit.
<b><a href="postconf.5.html#smtpd_client_message_rate_limit">smtpd_client_message_rate_limit</a> (0)</b>
- The maximal number of message delivery requests
- that any client is allowed to make to this service
+ The maximal number of message delivery requests
+ that any client is allowed to make to this service
per time unit, regardless of whether or not Postfix
actually accepts those messages.
<b><a href="postconf.5.html#smtpd_client_recipient_rate_limit">smtpd_client_recipient_rate_limit</a> (0)</b>
- The maximal number of recipient addresses that any
- client is allowed to send to this service per time
+ The maximal number of recipient addresses that any
+ client is allowed to send to this service per time
unit, regardless of whether or not Postfix actually
accepts those recipients.
<b><a href="postconf.5.html#smtpd_client_event_limit_exceptions">smtpd_client_event_limit_exceptions</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
- Clients that are excluded from
+ Clients that are excluded from
smtpd_client_*_count/rate_limit restrictions.
Available in Postfix version 2.3 and later:
tiate with this service per time unit.
<b>TARPIT CONTROLS</b>
- When a remote SMTP client makes errors, the Postfix SMTP
- server can insert delays before responding. This can help
- to slow down run-away software. The behavior is con-
- trolled by an error counter that counts the number of
- errors within an SMTP session that a client makes without
+ When a remote SMTP client makes errors, the Postfix SMTP
+ server can insert delays before responding. This can help
+ to slow down run-away software. The behavior is con-
+ trolled by an error counter that counts the number of
+ errors within an SMTP session that a client makes without
delivering mail.
<b><a href="postconf.5.html#smtpd_error_sleep_time">smtpd_error_sleep_time</a> (1s)</b>
With Postfix version 2.1 and later: the SMTP server
- response delay after a client has made more than
- $<a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> errors, and fewer than
- $<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> errors, without delivering
+ response delay after a client has made more than
+ $<a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> errors, and fewer than
+ $<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> errors, without delivering
mail.
<b><a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> (10)</b>
- The number of errors a remote SMTP client is
- allowed to make without delivering mail before the
+ The number of errors a remote SMTP client is
+ allowed to make without delivering mail before the
Postfix SMTP server slows down all its responses.
<b><a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> (normal: 20, overload: 1)</b>
- The maximal number of errors a remote SMTP client
+ The maximal number of errors a remote SMTP client
is allowed to make without delivering mail.
<b><a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> (normal: 100, overload: 1)</b>
- The number of junk commands (NOOP, VRFY, ETRN or
+ The number of junk commands (NOOP, VRFY, ETRN or
RSET) that a remote SMTP client can send before the
- Postfix SMTP server starts to increment the error
+ Postfix SMTP server starts to increment the error
counter with each junk command.
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtpd_recipient_overshoot_limit">smtpd_recipient_overshoot_limit</a> (1000)</b>
- The number of recipients that a remote SMTP client
- can send in excess of the limit specified with
+ The number of recipients that a remote SMTP client
+ can send in excess of the limit specified with
$<a href="postconf.5.html#smtpd_recipient_limit">smtpd_recipient_limit</a>, before the Postfix SMTP
- server increments the per-session error count for
+ server increments the per-session error count for
each excess recipient.
<b>ACCESS POLICY DELEGATION CONTROLS</b>
- As of version 2.1, Postfix can be configured to delegate
- access policy decisions to an external server that runs
- outside Postfix. See the file <a href="SMTPD_POLICY_README.html">SMTPD_POLICY_README</a> for
+ As of version 2.1, Postfix can be configured to delegate
+ access policy decisions to an external server that runs
+ outside Postfix. See the file <a href="SMTPD_POLICY_README.html">SMTPD_POLICY_README</a> for
more information.
<b><a href="postconf.5.html#smtpd_policy_service_max_idle">smtpd_policy_service_max_idle</a> (300s)</b>
- The time after which an idle SMTPD policy service
+ The time after which an idle SMTPD policy service
connection is closed.
<b><a href="postconf.5.html#smtpd_policy_service_max_ttl">smtpd_policy_service_max_ttl</a> (1000s)</b>
connection is closed.
<b><a href="postconf.5.html#smtpd_policy_service_timeout">smtpd_policy_service_timeout</a> (100s)</b>
- The time limit for connecting to, writing to or
+ The time limit for connecting to, writing to or
receiving from a delegated SMTPD policy server.
<b>ACCESS CONTROLS</b>
- The <a href="SMTPD_ACCESS_README.html">SMTPD_ACCESS_README</a> document gives an introduction to
+ The <a href="SMTPD_ACCESS_README.html">SMTPD_ACCESS_README</a> document gives an introduction to
all the SMTP server access control features.
<b><a href="postconf.5.html#smtpd_delay_reject">smtpd_delay_reject</a> (yes)</b>
- Wait until the RCPT TO command before evaluating
+ Wait until the RCPT TO command before evaluating
$<a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a>, $smtpd_helo_restric-
tions and $<a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a>, or wait until
- the ETRN command before evaluating
+ the ETRN command before evaluating
$<a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> and $smtpd_helo_restric-
tions.
- <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf -d' out-</b>
+ <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf -d' out-</b>
<b>put)</b>
What Postfix features match subdomains of
"domain.tld" automatically, instead of requiring an
explicit ".domain.tld" pattern.
<b><a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> (empty)</b>
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client SMTP connection request.
<b><a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> (no)</b>
Require that a remote SMTP client introduces itself
- with the HELO or EHLO command before sending the
- MAIL command or other commands that require EHLO
+ with the HELO or EHLO command before sending the
+ MAIL command or other commands that require EHLO
negotiation.
<b><a href="postconf.5.html#smtpd_helo_restrictions">smtpd_helo_restrictions</a> (empty)</b>
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the SMTP HELO command.
<b><a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> (empty)</b>
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the MAIL FROM command.
<b><a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> (<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,</b>
<b><a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>)</b>
The access restrictions that the Postfix SMTP
- server applies in the context of the RCPT TO com-
+ server applies in the context of the RCPT TO com-
mand.
<b><a href="postconf.5.html#smtpd_etrn_restrictions">smtpd_etrn_restrictions</a> (empty)</b>
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client ETRN request.
<b><a href="postconf.5.html#allow_untrusted_routing">allow_untrusted_routing</a> (no)</b>
- Forward mail with sender-specified routing
- (user[@%!]remote[@%!]site) from untrusted clients
+ Forward mail with sender-specified routing
+ (user[@%!]remote[@%!]site) from untrusted clients
to destinations matching $<a href="postconf.5.html#relay_domains">relay_domains</a>.
<b><a href="postconf.5.html#smtpd_restriction_classes">smtpd_restriction_classes</a> (empty)</b>
- User-defined aliases for groups of access restric-
+ User-defined aliases for groups of access restric-
tions.
<b><a href="postconf.5.html#smtpd_null_access_lookup_key">smtpd_null_access_lookup_key</a> (</b><><b>)</b>
- The lookup key to be used in SMTP <a href="access.5.html"><b>access</b>(5)</a> tables
+ The lookup key to be used in SMTP <a href="access.5.html"><b>access</b>(5)</a> tables
instead of the null sender address.
<b><a href="postconf.5.html#permit_mx_backup_networks">permit_mx_backup_networks</a> (empty)</b>
Restrict the use of the <a href="postconf.5.html#permit_mx_backup">permit_mx_backup</a> SMTP
- access feature to only domains whose primary MX
+ access feature to only domains whose primary MX
hosts match the listed networks.
Available in Postfix version 2.0 and later:
<b><a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> (empty)</b>
- Optional access restrictions that the Postfix SMTP
+ Optional access restrictions that the Postfix SMTP
server applies in the context of the SMTP DATA com-
mand.
<b><a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> (see 'postconf -d' output)</b>
- What characters are allowed in $name expansions of
+ What characters are allowed in $name expansions of
RBL reply templates.
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtpd_reject_unlisted_sender">smtpd_reject_unlisted_sender</a> (no)</b>
- Request that the Postfix SMTP server rejects mail
- from unknown sender addresses, even when no
- explicit <a href="postconf.5.html#reject_unlisted_sender">reject_unlisted_sender</a> access restriction
+ Request that the Postfix SMTP server rejects mail
+ from unknown sender addresses, even when no
+ explicit <a href="postconf.5.html#reject_unlisted_sender">reject_unlisted_sender</a> access restriction
is specified.
<b><a href="postconf.5.html#smtpd_reject_unlisted_recipient">smtpd_reject_unlisted_recipient</a> (yes)</b>
- Request that the Postfix SMTP server rejects mail
+ Request that the Postfix SMTP server rejects mail
for unknown recipient addresses, even when no
- explicit <a href="postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a> access restric-
+ explicit <a href="postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a> access restric-
tion is specified.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> (empty)</b>
- Optional access restrictions that the Postfix SMTP
- server applies in the context of the SMTP END-OF-
+ Optional access restrictions that the Postfix SMTP
+ server applies in the context of the SMTP END-OF-
DATA command.
<b>SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS</b>
- Postfix version 2.1 introduces sender and recipient
- address verification. This feature is implemented by
- sending probe email messages that are not actually deliv-
- ered. This feature is requested via the reject_unveri-
- fied_sender and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> access
- restrictions. The status of verification probes is main-
+ Postfix version 2.1 introduces sender and recipient
+ address verification. This feature is implemented by
+ sending probe email messages that are not actually deliv-
+ ered. This feature is requested via the reject_unveri-
+ fied_sender and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> access
+ restrictions. The status of verification probes is main-
tained by the <a href="verify.8.html"><b>verify</b>(8)</a> server. See the file <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VER</a>-
- <a href="ADDRESS_VERIFICATION_README.html">IFICATION_README</a> for information about how to configure
+ <a href="ADDRESS_VERIFICATION_README.html">IFICATION_README</a> for information about how to configure
and operate the Postfix sender/recipient address verifica-
tion service.
<b><a href="postconf.5.html#address_verify_poll_count">address_verify_poll_count</a> (normal: 3, overload: 1)</b>
- How many times to query the <a href="verify.8.html"><b>verify</b>(8)</a> service for
- the completion of an address verification request
+ How many times to query the <a href="verify.8.html"><b>verify</b>(8)</a> service for
+ the completion of an address verification request
in progress.
<b><a href="postconf.5.html#address_verify_poll_delay">address_verify_poll_delay</a> (3s)</b>
- The delay between queries for the completion of an
+ The delay between queries for the completion of an
address verification request in progress.
<b><a href="postconf.5.html#address_verify_sender">address_verify_sender</a> ($<a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a>)</b>
- The sender address to use in address verification
+ The sender address to use in address verification
probes; prior to Postfix 2.5 the default was "post-
master".
<b><a href="postconf.5.html#unverified_sender_reject_code">unverified_sender_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a recipient address is rejected by the
+ The numerical Postfix SMTP server response code
+ when a recipient address is rejected by the
<a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a> restriction.
<b><a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response when a
+ The numerical Postfix SMTP server response when a
recipient address is rejected by the reject_unveri-
fied_recipient restriction.
Available in Postfix version 2.6 and later:
<b><a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a sender address probe fails due to a tempo-
+ The numerical Postfix SMTP server response code
+ when a sender address probe fails due to a tempo-
rary error condition.
<b><a href="postconf.5.html#unverified_recipient_defer_code">unverified_recipient_defer_code</a> (450)</b>
- The numerical Postfix SMTP server response when a
- recipient address probe fails due to a temporary
+ The numerical Postfix SMTP server response when a
+ recipient address probe fails due to a temporary
error condition.
<b><a href="postconf.5.html#unverified_sender_reject_reason">unverified_sender_reject_reason</a> (empty)</b>
<b><a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
<b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_sender">reject_unver</a>-
- <a href="postconf.5.html#reject_unverified_sender">ified_sender</a> fails due to a temporary error condi-
+ <a href="postconf.5.html#reject_unverified_sender">ified_sender</a> fails due to a temporary error condi-
tion.
<b><a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
dition.
<b>ACCESS CONTROL RESPONSES</b>
- The following parameters control numerical SMTP reply
+ The following parameters control numerical SMTP reply
codes and/or text responses.
<b><a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a> (554)</b>
an <a href="access.5.html"><b>access</b>(5)</a> map "reject" action.
<b><a href="postconf.5.html#defer_code">defer_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a remote SMTP client request is rejected by
+ The numerical Postfix SMTP server response code
+ when a remote SMTP client request is rejected by
the "defer" restriction.
<b><a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> (501)</b>
- The numerical Postfix SMTP server response code
- when the client HELO or EHLO command parameter is
- rejected by the <a href="postconf.5.html#reject_invalid_helo_hostname">reject_invalid_helo_hostname</a>
+ The numerical Postfix SMTP server response code
+ when the client HELO or EHLO command parameter is
+ rejected by the <a href="postconf.5.html#reject_invalid_helo_hostname">reject_invalid_helo_hostname</a>
restriction.
<b><a href="postconf.5.html#maps_rbl_reject_code">maps_rbl_reject_code</a> (554)</b>
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
<a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a>, <a href="postconf.5.html#reject_rhsbl_client">reject_rhsbl_client</a>,
<a href="postconf.5.html#reject_rhsbl_reverse_client">reject_rhsbl_reverse_client</a>, <a href="postconf.5.html#reject_rhsbl_sender">reject_rhsbl_sender</a> or
<b><a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> (504)</b>
The numerical Postfix SMTP server reply code when a
- client request is rejected by the
+ client request is rejected by the
<a href="postconf.5.html#reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a>,
<a href="postconf.5.html#reject_non_fqdn_sender">reject_non_fqdn_sender</a> or <a href="postconf.5.html#reject_non_fqdn_recipient">reject_non_fqdn_recipient</a>
restriction.
<b><a href="postconf.5.html#plaintext_reject_code">plaintext_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a request is rejected by the <b>reject_plain-</b>
+ The numerical Postfix SMTP server response code
+ when a request is rejected by the <b>reject_plain-</b>
<b>text_session</b> restriction.
<b><a href="postconf.5.html#reject_code">reject_code</a> (554)</b>
- The numerical Postfix SMTP server response code
- when a remote SMTP client request is rejected by
+ The numerical Postfix SMTP server response code
+ when a remote SMTP client request is rejected by
the "reject" restriction.
<b><a href="postconf.5.html#relay_domains_reject_code">relay_domains_reject_code</a> (554)</b>
- The numerical Postfix SMTP server response code
- when a client request is rejected by the
+ The numerical Postfix SMTP server response code
+ when a client request is rejected by the
<a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a> recipient restriction.
<b><a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a sender or recipient address is rejected by
+ The numerical Postfix SMTP server response code
+ when a sender or recipient address is rejected by
the <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a> or
<a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction.
<b><a href="postconf.5.html#unknown_client_reject_code">unknown_client_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when a client without valid address <=> name map-
+ The numerical Postfix SMTP server response code
+ when a client without valid address <=> name map-
ping is rejected by the reject_unknown_client_host-
name restriction.
<b><a href="postconf.5.html#unknown_hostname_reject_code">unknown_hostname_reject_code</a> (450)</b>
- The numerical Postfix SMTP server response code
- when the hostname specified with the HELO or EHLO
- command is rejected by the
+ The numerical Postfix SMTP server response code
+ when the hostname specified with the HELO or EHLO
+ command is rejected by the
<a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> restriction.
Available in Postfix version 2.0 and later:
<b><a href="postconf.5.html#default_rbl_reply">default_rbl_reply</a> (see 'postconf -d' output)</b>
- The default SMTP server response template for a
- request that is rejected by an RBL-based restric-
+ The default SMTP server response template for a
+ request that is rejected by an RBL-based restric-
tion.
<b><a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a> (550)</b>
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
<a href="postconf.5.html#reject_multi_recipient_bounce">reject_multi_recipient_bounce</a> restriction.
<b><a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a> (450)</b>
The numerical Postfix SMTP server response code for
- an <a href="access.5.html"><b>access</b>(5)</a> map "defer" action, including
+ an <a href="access.5.html"><b>access</b>(5)</a> map "defer" action, including
"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" or "<a href="postconf.5.html#defer_if_reject">defer_if_reject</a>".
<b><a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a> (<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>)</b>
The Postfix SMTP server's action when a reject-type
- restriction fails due to a temporary error condi-
+ restriction fails due to a temporary error condi-
tion.
<b><a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
<b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
- The Postfix SMTP server's action when
+ The Postfix SMTP server's action when
<a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> fails due to an tempo-
rary error condition.
<b><a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
- The Postfix SMTP server's action when
+ The Postfix SMTP server's action when
<a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a> or
- <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> fail due to a tem-
+ <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> fail due to a tem-
porary error condition.
<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#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
+ How much time a Postfix daemon process may take to
+ handle a request before it is terminated by a
built-in watchdog timer.
<b><a href="postconf.5.html#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#double_bounce_sender">double_bounce_sender</a> (double-bounce)</b>
and most Postfix daemon processes.
<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
+ The maximum amount of time that an idle Postfix
+ daemon process waits for an incoming connection
before terminating voluntarily.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
- The maximal number of incoming connections that a
- Postfix daemon process will service before termi-
+ The maximal number of incoming connections that a
+ Postfix daemon process will service before termi-
nating voluntarily.
<b><a href="postconf.5.html#myhostname">myhostname</a> (see 'postconf -d' output)</b>
The internet hostname of this mail system.
<b><a href="postconf.5.html#mynetworks">mynetworks</a> (see 'postconf -d' output)</b>
- The list of "trusted" SMTP clients that have more
+ The list of "trusted" SMTP clients that have more
privileges than "strangers".
<b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
The domain name that locally-posted mail appears to
- come from, and that locally posted mail is deliv-
+ come from, and that locally posted mail is deliv-
ered to.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
sions (user+foo).
<b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
- The text that follows the 220 status code in the
+ The text that follows the 220 status code in the
SMTP greeting banner.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the
- process name in syslog records, so that "smtpd"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT, GET, POST)</b>
List of commands that cause the Postfix SMTP server
- to immediately terminate the session with a 221
+ to immediately terminate the session with a 221
code.
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#smtpd_client_port_logging">smtpd_client_port_logging</a> (no)</b>
- Enable logging of the remote SMTP client port in
+ Enable logging of the remote SMTP client port in
addition to the hostname and IP address.
<b>SEE ALSO</b>
<a href="XFORWARD_README.html">XFORWARD_README</a>, Postfix XFORWARD extension
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
.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.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+ smtpd_reject_contact_information = For assistance, call 800-555-0101.
+ Please provide the following information in your problem report:
+ time ($localtime) and client address ($client_address).
+.fi
+.ad
+.ft R
+.PP
+Server response:
+.PP
+.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).
+.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.
+.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.
+.PP
+This feature supports a limited number of $name attributes in
+the contact 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
+.PP
+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.
+.PP
+This feature is available in Postfix 2.8 and later.
.SH smtpd_reject_unlisted_recipient (default: yes)
Request that the Postfix SMTP server rejects mail for unknown
recipient addresses, even when no explicit reject_unlisted_recipient
.IP "\fBsmtpd_sasl_tls_security_options ($smtpd_sasl_security_options)\fR"
The SASL authentication security options that the Postfix SMTP
server uses for TLS encrypted SMTP sessions.
-.IP "\fBsmtpd_starttls_timeout (300s)\fR"
+.IP "\fBsmtpd_starttls_timeout (see 'postconf -d' output)\fR"
The time limit for Postfix SMTP server write and read operations
during TLS startup and shutdown handshake procedures.
.IP "\fBsmtpd_tls_CAfile (empty)\fR"
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 "\fBsoft_bounce (no)\fR"
Safety net to keep mail queued that would otherwise be returned to
the sender.
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;\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;
<p> This feature is available in Postfix 2.8 and later. </p>
+%PARAM smtpd_reject_contact_information
+
+<p> Optional contact 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.
+ Please provide the following information in your problem report:
+ time ($localtime) and client address ($client_address).
+</pre>
+
+<p> Server response: </p>
+
+<pre>
+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).
+</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> 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>
+
+<p> This feature supports a limited number of $name attributes in
+the contact text. These are replaced by their current value for the
+SMTP session: </p>
+
+<dl>
+
+<dt> client_address </dt> <dd> Client IP address </dd>
+
+<dt> client_port </dt> <dd> Client TCP port </dd>
+
+<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </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>
+
+</dl>
+
+<p> For safety reasons, text that does not match $smtpd_expansion_filter
+is censored. </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>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
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: 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
#define DEF_TLSP_TLS_SET_SESSID "$" VAR_SMTPD_TLS_SET_SESSID
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;
+
/* LICENSE
/* .ad
/* .fi
#define MAIL_ATTR_ERRTO "errors-to"
#define MAIL_ATTR_RRCPT "return-receipt"
#define MAIL_ATTR_TIME "time"
+#define MAIL_ATTR_LOCALTIME "localtime"
#define MAIL_ATTR_CREATE_TIME "create_time"
#define MAIL_ATTR_RULE "rule"
#define MAIL_ATTR_ADDR "address"
#define MAIL_ATTR_ROLE_SERVER "server"
#define MAIL_ATTR_ROLE_CLIENT "client"
#define MAIL_ATTR_TIMEOUT "timeout"
+#define MAIL_ATTR_PEER_CN "peer_CN"
+#define MAIL_ATTR_ISSUER_CN "issuer_CN"
+#define MAIL_ATTR_PEER_FPT "peer_fingerprint"
+#define MAIL_ATTR_PEER_STATUS "peer_status"
+#define MAIL_ATTR_CIPHER_PROTOCOL "cipher_protocol"
+#define MAIL_ATTR_CIPHER_NAME "cipher_name"
+#define MAIL_ATTR_CIPHER_USEBITS "cipher_usebits"
+#define MAIL_ATTR_CIPHER_ALGBITS "cipher_algbits"
/* LICENSE
/* .ad
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20110103"
+#define MAIL_RELEASE_DATE "20110105"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
postscreen_starttls.o: ../../include/match_ops.h
postscreen_starttls.o: ../../include/msg.h
postscreen_starttls.o: ../../include/mymalloc.h
+postscreen_starttls.o: ../../include/name_code.h
+postscreen_starttls.o: ../../include/name_mask.h
postscreen_starttls.o: ../../include/string_list.h
postscreen_starttls.o: ../../include/stringops.h
postscreen_starttls.o: ../../include/sys_defs.h
+postscreen_starttls.o: ../../include/tls.h
+postscreen_starttls.o: ../../include/tls_proxy.h
postscreen_starttls.o: ../../include/vbuf.h
postscreen_starttls.o: ../../include/vstream.h
postscreen_starttls.o: ../../include/vstring.h
static MAPS *psc_ehlo_discard_maps;
static int psc_ehlo_discard_mask;
- /*
- * STARTTLS support. Note the complete absence of #ifdef USE_TLS throughout
- * the postscreen(8) source code. If Postfix is built without TLS support,
- * then the TLS proxy will simply report that TLS is not available, and
- * conventional error handling will take care of the issue.
- */
-static int psc_tls_use_tls;
-static int psc_tls_enforce_tls;
-
-#ifdef TODO_USE_SASL_AUTH
-static int psc_tls_auth_only;
-
-#endif
-
/*
* Encapsulation. We must not forget turn off input/timer events when we
* terminate the SMTP protocol engine.
/* psc_smtpd_format_ehlo_reply - format EHLO response */
static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
- /*, const char *sasl_mechanism_list */)
+ /* , const char *sasl_mechanism_list */ )
{
const char *myname = "psc_smtpd_format_ehlo_reply";
int saved_len = 0;
PSC_EHLO_APPEND(saved_len, psc_temp, "250-VRFY\r\n");
if ((discard_mask & EHLO_MASK_ETRN) == 0)
PSC_EHLO_APPEND(saved_len, psc_temp, "250-ETRN\r\n");
- if ((discard_mask & EHLO_MASK_STARTTLS) == 0
- && (psc_tls_use_tls || psc_tls_enforce_tls))
+ if ((discard_mask & EHLO_MASK_STARTTLS) == 0 && var_psc_use_tls)
PSC_EHLO_APPEND(saved_len, psc_temp, "250-STARTTLS\r\n");
#ifdef TODO_SASL_AUTH
if ((discard_mask & EHLO_MASK_AUTH) == 0 && sasl_mechanism_list
- && (psc_tls_auth_only == 0 || (discard_mask & EHLO_MASK_STARTTLS))) {
+ && (!var_psc_tls_auth_only || (discard_mask & EHLO_MASK_STARTTLS))) {
PSC_EHLO_APPEND1(saved_len, psc_temp, "AUTH %s", sasl_mechanism_list);
if (var_broken_auth_clients)
PSC_EHLO_APPEND1(saved_len, psc_temp, "AUTH=%s", sasl_mechanism_list);
if (state->flags & PSC_STATE_FLAG_USING_TLS)
return (PSC_SEND_REPLY(state,
"554 5.5.1 Error: TLS already active\r\n"));
- if (psc_tls_use_tls == 0 || (state->ehlo_discard_mask & EHLO_MASK_STARTTLS))
+ if (var_psc_use_tls == 0 || (state->ehlo_discard_mask & EHLO_MASK_STARTTLS))
return (PSC_SEND_REPLY(state,
"502 5.5.1 Error: command not implemented\r\n"));
if (cmdp->name == 0 || (cmdp->flags & PSC_SMTPD_CMD_FLAG_ENABLE) == 0) {
write_stat = PSC_SEND_REPLY(state,
"502 5.5.2 Error: command not recognized\r\n");
- } else if (psc_tls_enforce_tls
+ } else if (var_psc_enforce_tls
&& (state->flags & PSC_STATE_FLAG_USING_TLS) == 0
&& (cmdp->flags & PSC_SMTPD_CMD_FLAG_PRE_TLS) == 0) {
write_stat = PSC_SEND_REPLY(state,
psc_smtpd_helo_reply = mystrdup(STR(psc_temp));
/*
- * Legacy code copied from smtpd(8). The pre-fabricated EHLO reply
- * depends on this.
+ * STARTTLS support. Note the complete absence of #ifdef USE_TLS
+ * throughout the postscreen(8) source code. If Postfix is built without
+ * TLS support, then the TLS proxy will simply report that TLS is not
+ * available, and conventional error handling will take care of the
+ * issue.
+ *
+ * Legacy code copied from smtpd(8). The pre-fabricated EHLO reply depends
+ * on this.
*/
if (*var_psc_tls_level) {
switch (tls_level_lookup(var_psc_tls_level)) {
break;
}
}
- psc_tls_enforce_tls = var_psc_enforce_tls;
- psc_tls_use_tls = var_psc_use_tls || var_psc_enforce_tls;
+ var_psc_use_tls = var_psc_use_tls || var_psc_enforce_tls;
#ifdef TODO_SASL_AUTH
- if (var_psc_tls_auth_only || psc_tls_enforce_tls)
- psc_tls_auth_only = 1;
+ var_psc_tls_auth_only = var_psc_tls_auth_only || var_psc_enforce_tls;
#endif
/*
#include <mail_params.h>
#include <mail_proto.h>
+/* TLS library. */
+
+#include <tls_proxy.h>
+
/* Application-specific. */
#include <postscreen.h>
PSC_STATE *smtp_state; /* SMTP session state */
} PSC_STARTTLS;
-#define TLSPROXY_SERVICE "tlsproxy"
#define TLSPROXY_INIT_TIMEOUT 10
/* psc_starttls_finish - complete negotiation with TLS proxy */
* Replace our SMTP client stream by the TLS proxy stream. Once the
* TLS handshake is done, the TLS proxy will deliver plaintext SMTP
* commands to postscreen(8).
+ *
+ * Swap the file descriptors from under the VSTREAM so that we don't
+ * have to worry about loss of user-configurable VSTREAM attributes.
*/
- vstream_fclose(smtp_state->smtp_client_stream);
- smtp_state->smtp_client_stream = tlsproxy_stream;
+ vstream_fpurge(smtp_state->smtp_client_stream, VSTREAM_PURGE_BOTH);
+ vstream_control(smtp_state->smtp_client_stream,
+ VSTREAM_CTL_SWAP_FD, tlsproxy_stream,
+ VSTREAM_CTL_END);
+ vstream_fclose(tlsproxy_stream); /* direct-to-client stream! */
smtp_state->flags |= PSC_STATE_FLAG_USING_TLS;
}
smtp_state->smtp_client_port, (char *) 0);
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
- ATTR_TYPE_STR, MAIL_ATTR_ROLE, MAIL_ATTR_ROLE_SERVER,
+ ATTR_TYPE_INT, MAIL_ATTR_FLAGS, TLS_PROXY_FLAG_ROLE_SERVER,
ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, psc_normal_cmd_time_limit,
ATTR_TYPE_END);
myfree(remote_endpt);
SHELL = /bin/sh
SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
- smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c
+ smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c \
+ smtpd_expand.c
OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
- smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o
+ smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o \
+ smtpd_expand.o
HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
smtpd_sasl_glue.h smtpd_proxy.h smtpd_dsn_fix.h smtpd_milter.h \
- smtpd_resolve.h
+ smtpd_resolve.h smtpd_expand.h
TESTSRC = smtpd_token_test.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
smtpd.o: ../../include/iostuff.h
smtpd.o: ../../include/is_header.h
smtpd.o: ../../include/lex_822.h
+smtpd.o: ../../include/mac_expand.h
+smtpd.o: ../../include/mac_parse.h
smtpd.o: ../../include/mail_conf.h
smtpd.o: ../../include/mail_date.h
smtpd.o: ../../include/mail_error.h
smtpd.o: ../../include/stringops.h
smtpd.o: ../../include/sys_defs.h
smtpd.o: ../../include/tls.h
+smtpd.o: ../../include/tls_proxy.h
smtpd.o: ../../include/tok822.h
smtpd.o: ../../include/valid_hostname.h
smtpd.o: ../../include/valid_mailhost_addr.h
smtpd.o: smtpd.h
smtpd.o: smtpd_chat.h
smtpd.o: smtpd_check.h
+smtpd.o: smtpd_expand.h
smtpd.o: smtpd_milter.h
smtpd.o: smtpd_proxy.h
smtpd.o: smtpd_sasl_glue.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
+smtpd_chat.o: ../../include/mac_expand.h
+smtpd_chat.o: ../../include/mac_parse.h
smtpd_chat.o: ../../include/mail_addr.h
smtpd_chat.o: ../../include/mail_error.h
smtpd_chat.o: ../../include/mail_params.h
smtpd_chat.o: smtpd.h
smtpd_chat.o: smtpd_chat.c
smtpd_chat.o: smtpd_chat.h
+smtpd_chat.o: smtpd_expand.h
smtpd_check.o: ../../include/argv.h
smtpd_check.o: ../../include/attr.h
smtpd_check.o: ../../include/attr_clnt.h
smtpd_check.o: smtpd_check.c
smtpd_check.o: smtpd_check.h
smtpd_check.o: smtpd_dsn_fix.h
+smtpd_check.o: smtpd_expand.h
smtpd_check.o: smtpd_resolve.h
smtpd_check.o: smtpd_sasl_glue.h
smtpd_dsn_fix.o: ../../include/msg.h
smtpd_dsn_fix.o: ../../include/sys_defs.h
smtpd_dsn_fix.o: smtpd_dsn_fix.c
smtpd_dsn_fix.o: smtpd_dsn_fix.h
+smtpd_expand.o: ../../include/argv.h
+smtpd_expand.o: ../../include/attr.h
+smtpd_expand.o: ../../include/iostuff.h
+smtpd_expand.o: ../../include/mac_expand.h
+smtpd_expand.o: ../../include/mac_parse.h
+smtpd_expand.o: ../../include/mail_params.h
+smtpd_expand.o: ../../include/mail_proto.h
+smtpd_expand.o: ../../include/mail_stream.h
+smtpd_expand.o: ../../include/milter.h
+smtpd_expand.o: ../../include/msg.h
+smtpd_expand.o: ../../include/myaddrinfo.h
+smtpd_expand.o: ../../include/name_code.h
+smtpd_expand.o: ../../include/name_mask.h
+smtpd_expand.o: ../../include/stringops.h
+smtpd_expand.o: ../../include/sys_defs.h
+smtpd_expand.o: ../../include/tls.h
+smtpd_expand.o: ../../include/vbuf.h
+smtpd_expand.o: ../../include/vstream.h
+smtpd_expand.o: ../../include/vstring.h
+smtpd_expand.o: smtpd.h
+smtpd_expand.o: smtpd_expand.c
+smtpd_expand.o: smtpd_expand.h
smtpd_milter.o: ../../include/argv.h
smtpd_milter.o: ../../include/attr.h
smtpd_milter.o: ../../include/mail_params.h
/* .IP "\fBsmtpd_sasl_tls_security_options ($smtpd_sasl_security_options)\fR"
/* The SASL authentication security options that the Postfix SMTP
/* server uses for TLS encrypted SMTP sessions.
-/* .IP "\fBsmtpd_starttls_timeout (300s)\fR"
+/* .IP "\fBsmtpd_starttls_timeout (see 'postconf -d' output)\fR"
/* The time limit for Postfix SMTP server write and read operations
/* during TLS startup and shutdown handshake procedures.
/* .IP "\fBsmtpd_tls_CAfile (empty)\fR"
/* 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 "\fBsoft_bounce (no)\fR"
/* Safety net to keep mail queued that would otherwise be returned to
/* the sender.
#include <valid_mailhost_addr.h>
#include <dsn_mask.h>
#include <xtext.h>
+#include <tls_proxy.h>
/* Single-threaded server skeleton. */
#include <smtpd_sasl_glue.h>
#include <smtpd_proxy.h>
#include <smtpd_milter.h>
+#include <smtpd_expand.h>
/*
* Tunable parameters. Make sure that there is some bound on the length of
bool var_smtpd_tls_wrappermode;
bool var_smtpd_tls_auth_only;
char *var_smtpd_cmd_filter;
+char *var_smtpd_rej_contact;
#ifdef USE_TLS
char *var_smtpd_relay_ccerts;
#endif
-static int enforce_tls;
-
/*
* SMTP command mapping for broken clients.
*/
ENQUEUE_FIX_REPLY(state, reply_buf, SMTPD_CMD_ETRN);
#ifdef USE_TLS
if ((discard_mask & EHLO_MASK_STARTTLS) == 0)
- if ((state->tls_use_tls || state->tls_enforce_tls) && (!state->tls_context))
+ if (var_smtpd_use_tls && (!state->tls_context))
ENQUEUE_FIX_REPLY(state, reply_buf, SMTPD_CMD_STARTTLS);
#endif
#ifdef USE_SASL_AUTH
} while (0)
if (cipher_grade == 0) {
- cipher_grade =
- enforce_tls ? var_smtpd_tls_mand_ciph : var_smtpd_tls_ciph;
+ cipher_grade = var_smtpd_enforce_tls ?
+ var_smtpd_tls_mand_ciph : var_smtpd_tls_ciph;
cipher_exclusions = vstring_alloc(10);
ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_excl_ciph);
- if (enforce_tls)
+ if (var_smtpd_enforce_tls)
ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_mand_excl);
if (ask_client_cert)
ADD_EXCLUDE(cipher_exclusions, "aNULL");
log_level = var_smtpd_tls_loglevel,
timeout = var_smtpd_starttls_tmout,
requirecert = (var_smtpd_tls_req_ccert
- && state->tls_enforce_tls),
+ && var_smtpd_enforce_tls),
serverid = state->service,
namaddr = state->namaddr,
cipher_grade = cipher_grade,
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");
smtpd_chat_reply(state, "554 5.5.1 Error: TLS already active");
return (-1);
}
- if (state->tls_use_tls == 0
+ if (var_smtpd_use_tls == 0
|| (state->ehlo_discard_mask & EHLO_MASK_STARTTLS)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "502 5.5.1 Error: command not implemented");
return (-1);
}
+#ifndef USE_TLS_PROXY
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
/*
* Enforce TLS handshake rate limit when this client negotiated too many
state->namaddr);
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. */
smtp_flush(state->client);
+ vstream_fpurge(state->client, VSTREAM_PURGE_READ); /* Yay! */
/*
* Reset all inputs to the initial state.
*/
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 */
if (vstream_feof(state->client) || vstream_ferror(state->client))
failure = 1;
vstream_fflush(state->client); /* NOT: smtp_flush() */
+#ifndef USE_TLSPROXY
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;
}
}
*/
#ifdef USE_TLS
if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) {
+#ifdef USE_TLSPROXY
+ msg_fatal("Wrapper-mode is unimplemented.");
+#else /* USE_TLSPROXY */
if (smtpd_tls_ctx == 0) {
msg_warn("Wrapper-mode request dropped from %s for service %s."
" TLS context initialization failed. For details see"
break;
}
smtpd_start_tls(state);
+#endif /* USE_TLSPROXY */
}
#endif
#ifdef USE_SASL_AUTH
if (var_smtpd_sasl_enable && smtpd_sasl_is_active(state) == 0
#ifdef USE_TLS
- && state->tls_context == 0 && !state->tls_auth_only
+ && state->tls_context == 0 && !var_smtpd_tls_auth_only
#else
&& var_smtpd_tls_auth_only == 0
#endif
continue;
}
#ifdef USE_TLS
- if (state->tls_enforce_tls &&
+ if (var_smtpd_enforce_tls &&
!state->tls_context &&
(cmdp->flags & SMTPD_CMD_FLAG_PRE_TLS) == 0) {
smtpd_chat_reply(state,
msg_info("connect from %s", state.namaddr);
/*
- * With TLS wrapper mode, we run on a dedicated port and turn on TLS
- * before actually speaking the SMTP protocol. This implies TLS enforce
- * mode.
- *
- * With non-wrapper mode, TLS enforce mode implies that we don't advertise
- * AUTH before the client issues STARTTLS.
+ * Disable TLS when running in stand-alone mode via "sendmail -bs".
*/
-#ifdef USE_TLS
- if (!SMTPD_STAND_ALONE((&state))) {
- if (var_smtpd_tls_wrappermode) {
- state.tls_use_tls = 1;
- state.tls_enforce_tls = 1;
- } else {
- state.tls_use_tls = var_smtpd_use_tls | var_smtpd_enforce_tls;
- state.tls_enforce_tls = var_smtpd_enforce_tls;
- }
- if (var_smtpd_tls_auth_only || state.tls_enforce_tls)
- state.tls_auth_only = 1;
+ if (SMTPD_STAND_ALONE((&state))) {
+ var_smtpd_use_tls = 0;
+ var_smtpd_enforce_tls = 0;
+ var_smtpd_tls_auth_only = 0;
}
-#endif
/*
* XCLIENT must not override its own access control.
static void pre_jail_init(char *unused_name, char **unused_argv)
{
- int use_tls;
/*
* Initialize blacklist/etc. patterns before entering the chroot jail, in
*/
if (getuid() == 0 || getuid() == var_owner_uid)
smtpd_check_init();
+ smtpd_expand_init();
debug_peer_init();
if (var_smtpd_sasl_enable)
break;
}
}
- enforce_tls = var_smtpd_tls_wrappermode || var_smtpd_enforce_tls;
- use_tls = var_smtpd_use_tls || enforce_tls;
+
+ /*
+ * With TLS wrapper mode, we run on a dedicated port and turn on TLS
+ * before actually speaking the SMTP protocol. This implies TLS enforce
+ * mode.
+ *
+ * With non-wrapper mode, TLS enforce mode implies that we don't advertise
+ * AUTH before the client issues STARTTLS.
+ */
+ var_smtpd_enforce_tls = var_smtpd_tls_wrappermode || var_smtpd_enforce_tls;
+ var_smtpd_tls_auth_only = var_smtpd_tls_auth_only || var_smtpd_enforce_tls;
+ var_smtpd_use_tls = var_smtpd_use_tls || var_smtpd_enforce_tls;
/*
* Keys can only be loaded when running with suitable permissions. When
* announce STARTTLS support.
*/
if (getuid() == 0 || getuid() == var_owner_uid) {
- if (use_tls) {
+ if (var_smtpd_use_tls) {
#ifdef USE_TLS
TLS_SERVER_INIT_PROPS props;
const char *cert_file;
*/
ask_client_cert = require_server_cert =
(var_smtpd_tls_ask_ccert
- || (enforce_tls && var_smtpd_tls_req_ccert));
+ || (var_smtpd_enforce_tls && var_smtpd_tls_req_ccert));
if (strcasecmp(var_smtpd_tls_cert_file, "none") == 0) {
no_server_cert_ok = 1;
cert_file = "";
/* Some TLS configuration errors are not show stoppers. */
if (!have_server_cert && require_server_cert)
msg_warn("Need a server cert to request client certs");
- if (!enforce_tls && var_smtpd_tls_req_ccert)
+ if (!var_smtpd_enforce_tls && var_smtpd_tls_req_ccert)
msg_warn("Can't require client certs unless TLS is required");
/* After a show-stopper error, reply with 454 to STARTTLS. */
if (have_server_cert || (no_server_cert_ok && !require_server_cert))
dh512_param_file
= var_smtpd_tls_dh512_param_file,
eecdh_grade = var_smtpd_tls_eecdh,
- protocols = enforce_tls ?
+ protocols = var_smtpd_enforce_tls ?
var_smtpd_tls_mand_proto :
var_smtpd_tls_proto,
ask_ccert = ask_client_cert,
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,
0,
};
* TLS related state.
*/
#ifdef USE_TLS
- int tls_use_tls; /* can use TLS */
- int tls_enforce_tls; /* must use TLS */
- int tls_auth_only; /* use SASL over TLS only */
TLS_SESS_STATE *tls_context; /* TLS session state */
#endif
#include <mail_addr.h>
#include <post_mail.h>
#include <mail_error.h>
+#include <dsn_util.h>
/* Application-specific. */
#include "smtpd.h"
+#include "smtpd_expand.h"
#include "smtpd_chat.h"
#define STR vstring_str
char *cp;
char *next;
char *end;
+ ssize_t dsn_len;
/*
* Slow down clients that make errors. Sleep-on-anything slows down
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;
+ }
+ }
/* 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) {
/* This is why we use strlen() above instead of VSTRING_LEN(). */
if ((next = strstr(cp, "\r\n")) != 0) {
*next = 0;
+ cp[3] = '-'; /* contact footer kludge */
} else {
next = end;
}
#include "smtpd_check.h"
#include "smtpd_dsn_fix.h"
#include "smtpd_resolve.h"
+#include "smtpd_expand.h"
#define RESTRICTION_SEPARATORS ", \t\r\n"
static ARGV *local_rewrite_clients;
- /*
- * Pre-parsed expansion filter.
- */
-static VSTRING *expand_filter;
-
/*
* The routine that recursively applies restrictions.
*/
fail_required(VAR_RCPT_CHECKS, rcpt_required);
#endif
- /*
- * Expand the expansion filter :-)
- */
- expand_filter = vstring_alloc(10);
- unescape(expand_filter, var_smtpd_exp_filter);
-
/*
* Local rewrite policy.
*/
CHECK_MAIL_ACCESS_RETURN(SMTPD_CHECK_DUNNO);
}
-/* smtpd_expand_unknown - report unknown macro name */
-
-static void smtpd_expand_unknown(const char *name)
-{
- msg_warn("unknown macro name \"%s\" in expansion request", name);
-}
-
-/* smtpd_expand_addr - return address or substring thereof */
-
-static const char *smtpd_expand_addr(VSTRING *buf, const char *addr,
- const char *name, int prefix_len)
-{
- const char *p;
- const char *suffix;
-
- /*
- * Return NULL only for unknown names in expansion requests.
- */
- if (addr == 0)
- return ("");
-
- suffix = name + prefix_len;
-
- /*
- * MAIL_ATTR_SENDER or MAIL_ATTR_RECIP.
- */
- if (*suffix == 0) {
- if (*addr)
- return (addr);
- else
- return ("<>");
- }
-
- /*
- * "sender_name" or "recipient_name".
- */
-#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
-
- else if (STREQ(suffix, MAIL_ATTR_S_NAME)) {
- if (*addr) {
- if ((p = strrchr(addr, '@')) != 0) {
- vstring_strncpy(buf, addr, p - addr);
- return (STR(buf));
- } else {
- return (addr);
- }
- } else
- return ("<>");
- }
-
- /*
- * "sender_domain" or "recipient_domain".
- */
- else if (STREQ(suffix, MAIL_ATTR_S_DOMAIN)) {
- if (*addr) {
- if ((p = strrchr(addr, '@')) != 0) {
- return (p + 1);
- } else {
- return ("");
- }
- } else
- return ("");
- }
-
- /*
- * Unknown. Return NULL to indicate an "unknown name" error.
- */
- else {
- smtpd_expand_unknown(name);
- return (0);
- }
-}
-
-/* smtpd_expand_lookup - generic SMTP attribute $name expansion */
-
-static const char *smtpd_expand_lookup(const char *name, int unused_mode,
- char *context)
-{
- SMTPD_STATE *state = (SMTPD_STATE *) context;
-
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
-
- if (msg_verbose > 1)
- msg_info("smtpd_expand_lookup: ${%s}", name);
-
-#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.
- *
- * Return NULL only for non-existent names.
- */
- if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
- return (state->namaddr);
- } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
- return (state->addr);
- } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_NAME)) {
- return (state->name);
- } else if (STREQ(name, MAIL_ATTR_ACT_REVERSE_CLIENT_NAME)) {
- return (state->reverse_name);
- } else if (STREQ(name, MAIL_ATTR_ACT_HELO_NAME)) {
- return (state->helo_name ? state->helo_name : "");
- } else if (STREQN(name, MAIL_ATTR_SENDER, CONST_LEN(MAIL_ATTR_SENDER))) {
- return (smtpd_expand_addr(state->expand_buf, state->sender,
- name, CONST_LEN(MAIL_ATTR_SENDER)));
- } else if (STREQN(name, MAIL_ATTR_RECIP, CONST_LEN(MAIL_ATTR_RECIP))) {
- return (smtpd_expand_addr(state->expand_buf, state->recipient,
- name, CONST_LEN(MAIL_ATTR_RECIP)));
- } else {
- smtpd_expand_unknown(name);
- return (0);
- }
-}
-
/* Support for different DNSXL lookup results. */
static SMTPD_RBL_STATE dnsxl_stat_soft[1];
SMTPD_RBL_EXPAND_CONTEXT *rbl_exp = (SMTPD_RBL_EXPAND_CONTEXT *) context;
SMTPD_STATE *state = rbl_exp->state;
+#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
+
if (state->expand_buf == 0)
state->expand_buf = vstring_alloc(10);
if (template == 0)
template = var_def_rbl_reply;
if (mac_expand(why, template, MAC_EXP_FLAG_NONE,
- STR(expand_filter), rbl_expand_lookup,
+ STR(smtpd_expand_filter), rbl_expand_lookup,
(char *) &rbl_exp) == 0)
break;
if (template == var_def_rbl_reply)
--- /dev/null
+/*++
+/* NAME
+/* smtpd_expand 3
+/* SUMMARY
+/* SMTP server macro expansion
+/* SYNOPSIS
+/* #include <smtpd.h>
+/* #include <smtpd_expand.h>
+/*
+/* void smtpd_expand_init()
+/*
+/* int smtpd_expand(state, result, template, flags)
+/* SMTPD_STATE *state;
+/* VSTRING *result;
+/* const char *template;
+/* int flags;
+/* LOW_LEVEL INTERFACE
+/* VSTRING *smtpd_expand_filter;
+/*
+/* const char *smtpd_expand_lookup(name, unused_mode, context)
+/* const char *name;
+/* int unused_mode;
+/* char *context;
+/* const char *template;
+/* DESCRIPTION
+/* This module expands session-related macros.
+/*
+/* smtpd_expand_init() performs one-time initialization.
+/*
+/* smtpd_expand() expands macros in the template, using session
+/* attributes in the state argument, and writes the result to
+/* the result argument. The flags and result value are as with
+/* mac_expand().
+/*
+/* smtpd_expand_filter and smtpd_expand_lookup() provide access
+/* to lower-level interfaces that are used by smtpd_expand().
+/* smtpd_expand_lookup() returns null when a string is not
+/* found (or when it is a null pointer).
+/* DIAGNOSTICS
+/* Panic: interface violations. Fatal errors: out of memory.
+/* internal protocol errors. smtpd_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 <mac_expand.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <mail_proto.h>
+
+/* Application-specific. */
+
+#include <smtpd.h>
+#include <smtpd_expand.h>
+
+ /*
+ * Pre-parsed expansion filter.
+ */
+VSTRING *smtpd_expand_filter;
+
+ /*
+ * SLMs.
+ */
+#define STR vstring_str
+
+/* smtpd_expand_init - initialize once during process lifetime */
+
+void smtpd_expand_init(void)
+{
+
+ /*
+ * Expand the expansion filter :-)
+ */
+ smtpd_expand_filter = vstring_alloc(10);
+ unescape(smtpd_expand_filter, var_smtpd_exp_filter);
+}
+
+/* smtpd_expand_unknown - report unknown macro name */
+
+static void smtpd_expand_unknown(const char *name)
+{
+ msg_warn("unknown macro name \"%s\" in expansion request", name);
+}
+
+/* smtpd_expand_addr - return address or substring thereof */
+
+static const char *smtpd_expand_addr(VSTRING *buf, const char *addr,
+ const char *name, int prefix_len)
+{
+ const char *p;
+ const char *suffix;
+
+ /*
+ * Return NULL only for unknown names in expansion requests.
+ */
+ if (addr == 0)
+ return ("");
+
+ suffix = name + prefix_len;
+
+ /*
+ * MAIL_ATTR_SENDER or MAIL_ATTR_RECIP.
+ */
+ if (*suffix == 0) {
+ if (*addr)
+ return (addr);
+ else
+ return ("<>");
+ }
+
+ /*
+ * "sender_name" or "recipient_name".
+ */
+#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
+
+ else if (STREQ(suffix, MAIL_ATTR_S_NAME)) {
+ if (*addr) {
+ if ((p = strrchr(addr, '@')) != 0) {
+ vstring_strncpy(buf, addr, p - addr);
+ return (STR(buf));
+ } else {
+ return (addr);
+ }
+ } else
+ return ("<>");
+ }
+
+ /*
+ * "sender_domain" or "recipient_domain".
+ */
+ else if (STREQ(suffix, MAIL_ATTR_S_DOMAIN)) {
+ if (*addr) {
+ if ((p = strrchr(addr, '@')) != 0) {
+ return (p + 1);
+ } else {
+ return ("");
+ }
+ } else
+ return ("");
+ }
+
+ /*
+ * Unknown. Return NULL to indicate an "unknown name" error.
+ */
+ else {
+ smtpd_expand_unknown(name);
+ return (0);
+ }
+}
+
+/* smtpd_expand_lookup - generic SMTP attribute $name expansion */
+
+const char *smtpd_expand_lookup(const char *name, int unused_mode,
+ char *context)
+{
+ SMTPD_STATE *state = (SMTPD_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("smtpd_expand_lookup: ${%s}", name);
+
+#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.
+ *
+ * Return NULL only for non-existent names.
+ */
+ if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
+ return (state->namaddr);
+ } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
+ return (state->port);
+ } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
+ return (state->addr);
+ } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_NAME)) {
+ return (state->name);
+ } else if (STREQ(name, MAIL_ATTR_ACT_REVERSE_CLIENT_NAME)) {
+ return (state->reverse_name);
+ } else if (STREQ(name, MAIL_ATTR_ACT_HELO_NAME)) {
+ return (state->helo_name ? state->helo_name : "");
+ } else if (STREQN(name, MAIL_ATTR_SENDER, CONST_LEN(MAIL_ATTR_SENDER))) {
+ return (smtpd_expand_addr(state->expand_buf, state->sender,
+ name, CONST_LEN(MAIL_ATTR_SENDER)));
+ } else if (STREQN(name, MAIL_ATTR_RECIP, CONST_LEN(MAIL_ATTR_RECIP))) {
+ return (smtpd_expand_addr(state->expand_buf, state->recipient,
+ name, CONST_LEN(MAIL_ATTR_RECIP)));
+ } 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 {
+ smtpd_expand_unknown(name);
+ return (0);
+ }
+}
+
+/* smtpd_expand - expand session attributes in string */
+
+int smtpd_expand(SMTPD_STATE *state, VSTRING *result,
+ const char *template, int flags)
+{
+ return (mac_expand(result, template, flags, STR(smtpd_expand_filter),
+ smtpd_expand_lookup, (char *) state));
+}
--- /dev/null
+/*++
+/* NAME
+/* smtpd_expand 3h
+/* SUMMARY
+/* SMTP server macro expansion
+/* SYNOPSIS
+/* #include <smtpd.h>
+/* #include <smtpd_expand.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <vstring.h>
+#include <mac_expand.h>
+
+ /*
+ * External interface.
+ */
+VSTRING *smtpd_expand_filter;
+void smtpd_expand_init(void);
+const char *smtpd_expand_lookup(const char *, int, char *);
+int smtpd_expand(SMTPD_STATE *, VSTRING *, const char *, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
}
}
#ifdef USE_TLS
- if (state->tls_auth_only && !state->tls_context) {
+ if (var_smtpd_tls_auth_only && !state->tls_context) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
/* RFC 4954, Section 4. */
smtpd_chat_reply(state, "504 5.5.4 Encryption required for requested authentication mechanism");
state->dsn_buf = vstring_alloc(100);
state->dsn_orcpt_buf = vstring_alloc(100);
#ifdef USE_TLS
- state->tls_use_tls = 0;
- state->tls_enforce_tls = 0;
- state->tls_auth_only = 0;
state->tls_context = 0;
#endif
tls_prng_exch.c tls_stream.c tls_bio_ops.c tls_misc.c tls_dh.c \
tls_rsa.c tls_verify.c tls_certkey.c tls_session.c \
tls_client.c tls_server.c tls_scache.c tls_mgr.c tls_seed.c \
- tls_level.c
+ tls_level.c \
+ tls_proxy_clnt.c tls_proxy_print.c tls_proxy_scan.c
OBJS = tls_prng_dev.o tls_prng_egd.o tls_prng_file.o \
tls_prng_exch.o tls_stream.o tls_bio_ops.o tls_misc.o tls_dh.o \
tls_rsa.o tls_verify.o tls_certkey.o tls_session.o \
tls_client.o tls_server.o tls_scache.o tls_mgr.o tls_seed.o \
- tls_level.o
-HDRS = tls.h tls_prng.h tls_scache.h tls_mgr.h
+ tls_level.o \
+ tls_proxy_clnt.o tls_proxy_print.o tls_proxy_scan.o
+HDRS = tls.h tls_prng.h tls_scache.h tls_mgr.h tls_proxy.h
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
tls_prng_file.o: ../../include/sys_defs.h
tls_prng_file.o: tls_prng.h
tls_prng_file.o: tls_prng_file.c
+tls_proxy_clnt.o: ../../include/argv.h
+tls_proxy_clnt.o: ../../include/attr.h
+tls_proxy_clnt.o: ../../include/connect.h
+tls_proxy_clnt.o: ../../include/iostuff.h
+tls_proxy_clnt.o: ../../include/mail_proto.h
+tls_proxy_clnt.o: ../../include/msg.h
+tls_proxy_clnt.o: ../../include/mymalloc.h
+tls_proxy_clnt.o: ../../include/name_code.h
+tls_proxy_clnt.o: ../../include/name_mask.h
+tls_proxy_clnt.o: ../../include/stringops.h
+tls_proxy_clnt.o: ../../include/sys_defs.h
+tls_proxy_clnt.o: ../../include/vbuf.h
+tls_proxy_clnt.o: ../../include/vstream.h
+tls_proxy_clnt.o: ../../include/vstring.h
+tls_proxy_clnt.o: tls.h
+tls_proxy_clnt.o: tls_proxy.h
+tls_proxy_clnt.o: tls_proxy_clnt.c
+tls_proxy_print.o: ../../include/argv.h
+tls_proxy_print.o: ../../include/attr.h
+tls_proxy_print.o: ../../include/iostuff.h
+tls_proxy_print.o: ../../include/mail_proto.h
+tls_proxy_print.o: ../../include/name_code.h
+tls_proxy_print.o: ../../include/name_mask.h
+tls_proxy_print.o: ../../include/sys_defs.h
+tls_proxy_print.o: ../../include/vbuf.h
+tls_proxy_print.o: ../../include/vstream.h
+tls_proxy_print.o: ../../include/vstring.h
+tls_proxy_print.o: tls.h
+tls_proxy_print.o: tls_proxy.h
+tls_proxy_print.o: tls_proxy_print.c
+tls_proxy_scan.o: ../../include/argv.h
+tls_proxy_scan.o: ../../include/attr.h
+tls_proxy_scan.o: ../../include/iostuff.h
+tls_proxy_scan.o: ../../include/mail_proto.h
+tls_proxy_scan.o: ../../include/name_code.h
+tls_proxy_scan.o: ../../include/name_mask.h
+tls_proxy_scan.o: ../../include/sys_defs.h
+tls_proxy_scan.o: ../../include/vbuf.h
+tls_proxy_scan.o: ../../include/vstream.h
+tls_proxy_scan.o: ../../include/vstring.h
+tls_proxy_scan.o: tls.h
+tls_proxy_scan.o: tls_proxy.h
+tls_proxy_scan.o: tls_proxy_scan.c
tls_rsa.o: ../../include/argv.h
tls_rsa.o: ../../include/name_code.h
tls_rsa.o: ../../include/name_mask.h
--- /dev/null
+#ifndef _TLS_PROXY_H_INCLUDED_
+#define _TLS_PROXY_H_INCLUDED_
+
+/*++
+/* NAME
+/* tls_proxy_clnt 3h
+/* SUMMARY
+/* postscreen TLS proxy support
+/* SYNOPSIS
+/* #include <tls_proxy_clnt.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+ * TLS library.
+ */
+#include <tls.h>
+
+ /*
+ * External interface.
+ */
+#define TLSPROXY_SERVICE "tlsproxy"
+
+#define TLS_PROXY_FLAG_ROLE_SERVER (1<<0) /* request server role */
+#define TLS_PROXY_FLAG_ROLE_CLIENT (1<<1) /* request client role */
+#define TLS_PROXY_FLAG_SEND_CONTEXT (1<<2) /* send TLS context */
+
+#ifdef USE_TLS
+
+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 *);
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* tlsproxy_clnt 3
+/* SUMMARY
+/* postscreen TLS proxy support
+/* SYNOPSIS
+/* #include <tlsproxy_clnt.h>
+/*
+/* VSTREAM *tls_proxy_open(flags, peer_stream, peer_addr,
+/* peer_port, timeout)
+/* int flags;
+/* VSTREAM *peer_stream;
+/* const char *peer_addr;
+/* const char *peer_port;
+/* int timeout;
+/*
+/* TLS_SESS_STATE *tls_proxy_state_receive(proxy_stream)
+/* VSTREAM *proxy_stream;
+/*
+/* void tls_proxy_state_free(tls_context)
+/* TLS_SESS_STATE *tls_context;
+/* DESCRIPTION
+/* tls_proxy_open() prepares for inserting the tlsproxy(8)
+/* daemon between the current process and a remote peer (the
+/* actual insert operation is described in the next paragraph).
+/* The result value is a null pointer on failure. The peer_stream
+/* is not closed. The resulting proxy stream is single-buffered.
+/*
+/* After this, it is a good idea to use the VSTREAM_CTL_SWAP_FD
+/* request to swap the file descriptors between the plaintext
+/* peer_stream and the proxy stream from tls_proxy_open().
+/* This avoids the loss of application-configurable VSTREAM
+/* attributes on the plaintext peer_stream (such as longjmp
+/* buffer, timeout, etc.). Once the file descriptors are
+/* swapped, the proxy stream should be closed.
+/*
+/* tls_proxy_state_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.
+/*
+/* 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().
+/*
+/* Arguments:
+/* .IP flags
+/* Bit-wise OR of:
+/* .RS
+/* .IP TLS_PROXY_FLAG_ROLE_SERVER
+/* Request the TLS server proxy role.
+/* .IP TLS_PROXY_FLAG_ROLE_CLIENT
+/* Request the TLS client proxy role.
+/* .IP TLS_PROXY_FLAG_SEND_CONTEXT
+/* Send the TLS context object.
+/* .RE
+/* .IP peer_stream
+/* Stream that connects the current process to a remote peer.
+/* .IP peer_addr
+/* Printable IP address of the remote peer_stream endpoint.
+/* .IP peer_port
+/* Printable TCP port of the remote peer_stream endpoint.
+/* .IP timeout
+/* Time limit that the tlsproxy(8) daemon should use.
+/* .IP proxy_stream
+/* Stream from tls_proxy_open().
+/* .IP tls_context
+/* TLS session object from tls_proxy_state_receive().
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <connect.h>
+#include <stringops.h> /* concatenate() */
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library-specific. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+#define TLSPROXY_INIT_TIMEOUT 10
+
+/* tls_proxy_open - open negotiations with TLS proxy */
+
+VSTREAM *tls_proxy_open(int flags, VSTREAM *peer_stream,
+ const char *peer_addr,
+ const char *peer_port,
+ int timeout)
+{
+ VSTREAM *tlsproxy_stream;
+ char *remote_endpt;
+ int status;
+ int fd;
+
+ /*
+ * Connect to the tlsproxy(8) daemon. We report all errors
+ * asynchronously, to avoid having to maintain multiple delivery paths.
+ */
+ if ((fd = LOCAL_CONNECT("private/" TLSPROXY_SERVICE, BLOCKING,
+ TLSPROXY_INIT_TIMEOUT)) < 0) {
+ msg_warn("connect to %s service: %m", TLSPROXY_SERVICE);
+ return (0);
+ }
+
+ /*
+ * Initial handshake. Send the data attributes now, and send the client
+ * file descriptor in a later transaction.
+ *
+ * XXX The formatted endpoint should be a state member. Then, we can
+ * simplify all the format strings throughout the program.
+ */
+ tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
+ remote_endpt = concatenate("[", peer_addr, "]:",
+ peer_port, (char *) 0);
+ attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
+ ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
+ ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
+ ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, timeout,
+ ATTR_TYPE_END);
+ myfree(remote_endpt);
+ if (vstream_fflush(tlsproxy_stream) != 0) {
+ msg_warn("error sending request to %s service: %m", TLSPROXY_SERVICE);
+ vstream_fclose(tlsproxy_stream);
+ return (0);
+ }
+
+ /*
+ * Receive the "TLS is available" indication.
+ *
+ * This may seem out of order, but we must have a read transaction between
+ * sending the request attributes and sending the SMTP client file
+ * descriptor. We can't assume UNIX-domain socket semantics here.
+ */
+ if (attr_scan(tlsproxy_stream, ATTR_FLAG_STRICT,
+ ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
+ ATTR_TYPE_END) != 1 || status == 0) {
+
+ /*
+ * The TLS proxy reports that the TLS engine is not available (due to
+ * configuration error, or other causes).
+ */
+ msg_warn("%s service role \"%s\" is not available",
+ TLSPROXY_SERVICE,
+ (flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "server" :
+ (flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "client" :
+ "bogus role");
+ vstream_fclose(tlsproxy_stream);
+ return (0);
+ }
+
+ /*
+ * Send the remote SMTP client file descriptor.
+ */
+ if (LOCAL_SEND_FD(vstream_fileno(tlsproxy_stream),
+ vstream_fileno(peer_stream)) < 0) {
+
+ /*
+ * Some error: drop the TLS proxy stream.
+ */
+ msg_warn("sending file handle to %s service: %m", TLSPROXY_SERVICE);
+ vstream_fclose(tlsproxy_stream);
+ return (0);
+ }
+ return (tlsproxy_stream);
+}
+
+/* tls_proxy_state_receive - receive TLS session object from tlsproxy(8) */
+
+TLS_SESS_STATE *tls_proxy_state_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_END) != 1) {
+ tls_proxy_state_free(tls_context);
+ return (0);
+ } else {
+ return (tls_context);
+ }
+}
+
+/* tls_proxy_state_free - destroy object from tls_proxy_state_receive() */
+
+void tls_proxy_state_free(TLS_SESS_STATE *tls_context)
+{
+ if (tls_context->peer_CN)
+ myfree(tls_context->peer_CN);
+ if (tls_context->issuer_CN)
+ myfree(tls_context->issuer_CN);
+ if (tls_context->peer_fingerprint)
+ myfree(tls_context->peer_fingerprint);
+ if (tls_context->protocol)
+ myfree((char *) tls_context->protocol);
+ if (tls_context->cipher_name)
+ myfree((char *) tls_context->cipher_name);
+ myfree((char *) tls_context);
+}
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* tls_proxy_print
+/* SUMMARY
+/* write DSN structure to stream
+/* SYNOPSIS
+/* #include <tls_proxy.h>
+/*
+/* int tls_proxy_print_state(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
+/* 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, ...
+/* DIAGNOSTICS
+/* Fatal: out of memory.
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+/* tls_proxy_print_state - send TLS session state over stream */
+
+int tls_proxy_print_state(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
+ int flags, void *ptr)
+{
+ TLS_SESS_STATE *tp = (TLS_SESS_STATE *) ptr;
+ int ret;
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+ ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+ ATTR_TYPE_STR, MAIL_ATTR_PEER_CN,
+ STRING_OR_EMPTY(tp->peer_CN),
+ ATTR_TYPE_STR, MAIL_ATTR_ISSUER_CN,
+ STRING_OR_EMPTY(tp->issuer_CN),
+ ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT,
+ STRING_OR_EMPTY(tp->peer_fingerprint),
+ ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS,
+ tp->peer_status,
+ ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL,
+ STRING_OR_EMPTY(tp->protocol),
+ ATTR_TYPE_STR, MAIL_ATTR_CIPHER_NAME,
+ STRING_OR_EMPTY(tp->cipher_name),
+ ATTR_TYPE_INT, MAIL_ATTR_CIPHER_USEBITS,
+ tp->cipher_usebits,
+ ATTR_TYPE_INT, MAIL_ATTR_CIPHER_ALGBITS,
+ tp->cipher_algbits,
+ ATTR_TYPE_END);
+ return (ret);
+}
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* tls_proxy_scan
+/* SUMMARY
+/* read TLS session state from stream
+/* SYNOPSIS
+/* #include <tls_proxy.h>
+/*
+/* int tls_proxy_scan_state(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
+/* from the named stream using the specified attribute scan
+/* routine. tls_proxy_scan_state() is meant to be passed as
+/* a call-back to attr_scan(), thusly:
+/*
+/* ... ATTR_TYPE_FUNC, tls_proxy_scan_state, (void *) tls_context, ...
+/* DIAGNOSTICS
+/* Fatal: out of memory.
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+/* tls_proxy_scan_state - receive TLS session state from stream */
+
+int tls_proxy_scan_state(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
+ int flags, void *ptr)
+{
+ TLS_SESS_STATE *tls_context = (TLS_SESS_STATE *) ptr;
+ int ret;
+ VSTRING *peer_CN = vstring_alloc(25);
+ VSTRING *issuer_CN = vstring_alloc(25);
+ VSTRING *peer_fingerprint = vstring_alloc(25);
+ VSTRING *protocol = vstring_alloc(25);
+ VSTRING *cipher_name = vstring_alloc(25);
+
+ /*
+ * Note: memset() is not a portable way to initialize non-integer types.
+ */
+ memset(ptr, 0, sizeof(TLS_SESS_STATE));
+ ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+ ATTR_TYPE_STR, MAIL_ATTR_PEER_CN, peer_CN,
+ ATTR_TYPE_STR, MAIL_ATTR_ISSUER_CN, issuer_CN,
+ ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT, peer_fingerprint,
+ ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS,
+ &tls_context->peer_status,
+ ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL, protocol,
+ ATTR_TYPE_STR, MAIL_ATTR_CIPHER_NAME, cipher_name,
+ ATTR_TYPE_INT, MAIL_ATTR_CIPHER_USEBITS,
+ &tls_context->cipher_usebits,
+ ATTR_TYPE_INT, MAIL_ATTR_CIPHER_ALGBITS,
+ &tls_context->cipher_algbits,
+ ATTR_TYPE_END);
+ tls_context->peer_CN = vstring_export(peer_CN);
+ tls_context->issuer_CN = vstring_export(issuer_CN);
+ tls_context->peer_fingerprint = vstring_export(peer_fingerprint);
+ tls_context->protocol = vstring_export(protocol);
+ tls_context->cipher_name = vstring_export(cipher_name);
+ return (ret == 8 ? 1 : -1);
+}
+
+#endif
tlsproxy.o: ../../include/nbbio.h
tlsproxy.o: ../../include/sys_defs.h
tlsproxy.o: ../../include/tls.h
+tlsproxy.o: ../../include/tls_proxy.h
tlsproxy.o: ../../include/vbuf.h
tlsproxy.o: ../../include/vstream.h
tlsproxy.o: ../../include/vstring.h
#ifdef USE_TLS
#define TLS_INTERNAL /* XXX */
#include <tls.h>
+#include <tls_proxy.h>
/*
* Application-specific.
*/
static TLS_APPL_STATE *tlsp_server_ctx;
static int ask_client_cert;
-static int enforce_tls;
-static int tlsp_tls_enforce_tls;
/*
* SLMs.
tlsp_state_free(state);
return;
}
+ 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,
+ (char *) state->tls_context, ATTR_TYPE_END) != 0
+ || vstream_fflush(state->plaintext_stream) != 0)) {
+ msg_warn("cannot send TLS context: %m");
+ tlsp_state_free(state);
+ return;
+ }
state->flags &= ~TLSP_FLAG_DO_HANDSHAKE;
}
msg_warn("deadlock on plaintext stream for %s",
state->remote_endpt);
else
- msg_warn("read/write %s for %s",
+ msg_warn("ciphertext read/write %s for %s",
event == EVENT_TIME ? "timeout" : "error",
state->remote_endpt);
tlsp_state_free(state);
if (cipher_grade == 0) {
cipher_grade =
- enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
+ var_tlsp_enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
cipher_exclusions = vstring_alloc(10);
ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_excl_ciph);
- if (enforce_tls)
+ if (var_tlsp_enforce_tls)
ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_mand_excl);
if (ask_client_cert)
ADD_EXCLUDE(cipher_exclusions, "aNULL");
log_level = var_tlsp_tls_loglevel,
timeout = 0, /* unused */
requirecert = (var_tlsp_tls_req_ccert
- && tlsp_tls_enforce_tls),
+ && var_tlsp_enforce_tls),
serverid = state->service,
namaddr = state->remote_endpt,
cipher_grade = cipher_grade,
VSTREAM *plaintext_stream = state->plaintext_stream;
int plaintext_fd = vstream_fileno(plaintext_stream);
static VSTRING *remote_endpt;
- static VSTRING *role;
+ int req_flags;
int timeout;
int ready;
/*
* One-time initialization.
*/
- if (remote_endpt == 0) {
+ if (remote_endpt == 0)
remote_endpt = vstring_alloc(10);
- role = vstring_alloc(10);
- }
/*
* At this point we still manually manage plaintext read/write/timeout
if (event != EVENT_READ
|| attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
- ATTR_TYPE_STR, MAIL_ATTR_ROLE, role,
+ ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &req_flags,
ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, &timeout,
ATTR_TYPE_END) != 3) {
msg_warn("%s: receive request attributes: %m", myname);
* If the requested TLS engine is unavailable, hang up after making sure
* that the plaintext peer has received our "sorry" indication.
*/
- ready = (strcmp(STR(role), MAIL_ATTR_ROLE_SERVER) == 0
+ ready = ((req_flags & TLS_PROXY_FLAG_ROLE_SERVER) != 0
&& tlsp_server_ctx != 0);
if (attr_print(plaintext_stream, ATTR_FLAG_NONE,
ATTR_TYPE_INT, MAIL_ATTR_STATUS, ready,
*/
else {
state->remote_endpt = mystrdup(STR(remote_endpt));
- msg_info("CONNECT %s", state->remote_endpt);
+ msg_info("CONNECT %s %s",
+ (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
+ (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
+ "(bogus direction)", state->remote_endpt);
+ state->req_flags = req_flags;
state->timeout = timeout + 10; /* XXX */
event_enable_read(plaintext_fd, tlsp_get_fd_event, (char *) state);
event_request_timer(tlsp_get_fd_event, (char *) state,
/*
* This program handles multiple connections, so it must not block. We
* use event-driven code for all operations that introduce latency.
+ * Except that attribute lists are sent/received synchronously, once the
+ * socket is found to be ready for transmission.
*/
non_blocking(plaintext_fd, NON_BLOCKING);
vstream_control(plaintext_stream,
VSTREAM_CTL_PATH, "plaintext",
+ VSTREAM_CTL_TIMEOUT, 5,
VSTREAM_CTL_END);
/*
break;
}
}
- tlsp_tls_enforce_tls = var_tlsp_enforce_tls;
- if (!(var_tlsp_use_tls || var_tlsp_enforce_tls)) {
+ var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
+ if (!var_tlsp_use_tls) {
msg_warn("TLS service is requested, but disabled with %s or %s",
VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
return;
*/
ask_client_cert = require_server_cert =
(var_tlsp_tls_ask_ccert
- || (enforce_tls && var_tlsp_tls_req_ccert));
+ || (var_tlsp_enforce_tls && var_tlsp_tls_req_ccert));
if (strcasecmp(var_tlsp_tls_cert_file, "none") == 0) {
no_server_cert_ok = 1;
cert_file = "";
/* Some TLS configuration errors are not show stoppers. */
if (!have_server_cert && require_server_cert)
msg_warn("Need a server cert to request client certs");
- if (!enforce_tls && var_tlsp_tls_req_ccert)
+ if (!var_tlsp_enforce_tls && var_tlsp_tls_req_ccert)
msg_warn("Can't require client certs unless TLS is required");
/* After a show-stopper error, log a warning. */
if (have_server_cert || (no_server_cert_ok && !require_server_cert))
dh512_param_file
= var_tlsp_tls_dh512_param_file,
eecdh_grade = var_tlsp_tls_eecdh,
- protocols = enforce_tls ?
+ protocols = var_tlsp_enforce_tls ?
var_tlsp_tls_mand_proto :
var_tlsp_tls_proto,
ask_ccert = ask_client_cert,
*/
typedef struct {
int flags; /* see below */
+ int req_flags; /* request flags, see tls_proxy.h */
char *service; /* argv[0] */
VSTREAM *plaintext_stream; /* local peer: postscreen(8), etc. */
NBBIO *plaintext_buf; /* plaintext buffer */
/* .IP MAC_EXP_FLAG_RECURSE
/* Expand macros in lookup results. This should never be done with
/* data whose origin is untrusted.
+/* .IP MAC_EXP_FLAG_APPEND
+/* Append text to the result buffer.
/* .PP
/* The constant MAC_EXP_FLAG_NONE specifies a manifest null value.
/* .RE
mc.context = context;
mc.status = 0;
mc.level = 0;
- VSTRING_RESET(result);
+ if ((flags & MAC_EXP_FLAG_APPEND) == 0)
+ VSTRING_RESET(result);
status = mac_parse(pattern, mac_expand_callback, (char *) &mc);
VSTRING_TERMINATE(result);
*/
#define MAC_EXP_FLAG_NONE (0)
#define MAC_EXP_FLAG_RECURSE (1<<0)
+#define MAC_EXP_FLAG_APPEND (1<<1)
/*
* Real lookup or just a test?
/* The argument specifies the file descriptor to be used for writing.
/* This feature is limited to double-buffered streams, and makes the
/* stream non-seekable.
+/* .IP "VSTREAM_CTL_SWAP_FD (VSTREAM *)"
+/* The argument specifies a VSTREAM pointer; the request swaps the
+/* file descriptor members of the two streams. This feature is limited
+/* to streams that are both double-buffered or both single-buffered.
/* .IP "VSTREAM_CTL_DUPFD (int)"
/* The argument specifies a minimum file descriptor value. If
/* the actual stream's file descriptors are below the minimum,
int floor;
int old_fd;
ssize_t req_bufsize = 0;
+ VSTREAM *stream2;
+
+#define SWAP(type,a,b) do { type temp = (a); (a) = (b); (b) = (temp); } while (0)
for (va_start(ap, name); name != VSTREAM_CTL_END; name = va_arg(ap, int)) {
switch (name) {
stream->write_fd = va_arg(ap, int);
stream->buf.flags |= VSTREAM_FLAG_NSEEK;
break;
- case VSTREAM_CTL_WAITPID_FN:
- stream->waitpid_fn = va_arg(ap, VSTREAM_WAITPID_FN);
+ case VSTREAM_CTL_SWAP_FD:
+ stream2 = va_arg(ap, VSTREAM *);
+ if ((stream->buf.flags & VSTREAM_FLAG_DOUBLE)
+ != (stream2->buf.flags & VSTREAM_FLAG_DOUBLE))
+ msg_panic("VSTREAM_CTL_SWAP_FD can't swap descriptors between "
+ "single-buffered and double-buffered streams");
+ if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
+ SWAP(int, stream->read_fd, stream2->read_fd);
+ SWAP(int, stream->write_fd, stream2->write_fd);
+ stream->fd = ((stream->buf.flags & VSTREAM_FLAG_WRITE) ?
+ stream->write_fd : stream->read_fd);
+ } else {
+ SWAP(int, stream->fd, stream2->fd);
+ }
break;
case VSTREAM_CTL_TIMEOUT:
if (stream->timeout == 0)
#define VSTREAM_CTL_DUPFD 11
#endif
#define VSTREAM_CTL_BUFSIZE 12
+#define VSTREAM_CTL_SWAP_FD 13
extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
xsasl_dovecot_server.o: ../../include/iostuff.h
xsasl_dovecot_server.o: ../../include/mail_params.h
xsasl_dovecot_server.o: ../../include/msg.h
+xsasl_dovecot_server.o: ../../include/myaddrinfo.h
xsasl_dovecot_server.o: ../../include/mymalloc.h
xsasl_dovecot_server.o: ../../include/name_mask.h
xsasl_dovecot_server.o: ../../include/split_at.h