From: Wietse Venema
Date: Wed, 5 Jan 2011 05:00:00 +0000 (-0500)
Subject: postfix-2.8-20110105
X-Git-Tag: v2.8.0-RC1~6
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1d5ce4f053d8e8d3dd3b1a1495fd6dbf645f575;p=thirdparty%2Fpostfix.git
postfix-2.8-20110105
---
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 50274e0f3..214b50711 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -16340,7 +16340,7 @@ Apologies for any names omitted.
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
@@ -16349,3 +16349,24 @@ Apologies for any names omitted.
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].
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index 3e8792687..59f0445f8 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -34,6 +34,24 @@ is the $name of an smtpd_xxx parameter with a stress-dependent
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 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
======================================
@@ -397,59 +415,6 @@ any checks on clients in mynetworks (primarily, to avoid problems
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.
diff --git a/postfix/WISHLIST b/postfix/WISHLIST
index 016482248..e243dcd86 100644
--- a/postfix/WISHLIST
+++ b/postfix/WISHLIST
@@ -2,6 +2,8 @@ Wish list:
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.
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index 36e036254..3e7b683e6 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -13000,6 +13000,70 @@ Example:
+
+
+smtpd_reject_contact_information
+(default: empty)
+
+ Optional contact information that is appended after each SMTP
+server 4XX or 5XX response.
+
+ Example:
+
+
+/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).
+
+
+ Server response:
+
+
+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).
+
+
+ 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.
+
+ 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.
+
+
+ This feature supports a limited number of $name attributes in
+the contact text. These are replaced by their current value for the
+SMTP session:
+
+
+
+- client_address
- Client IP address
+
+- client_port
- Client TCP port
+
+- localtime
- Server local time (Mmm dd hh:mm:ss)
+
+- recipient
- The address in the RCPT TO command
+
+- sender
- The address in the MAIL FROM command
+
+
+
+ For safety reasons, text that does not match $smtpd_expansion_filter
+is censored.
+
+ 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.
+
+ This feature is available in Postfix 2.8 and later.
+
+
smtpd_reject_unlisted_recipient
diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html
index e942ab4d0..841eb9cbe 100644
--- a/postfix/html/smtpd.8.html
+++ b/postfix/html/smtpd.8.html
@@ -388,7 +388,7 @@ SMTPD(8) SMTPD(8)
Postfix SMTP server uses for TLS encrypted SMTP
sessions.
- smtpd_starttls_timeout (300s)
+ smtpd_starttls_timeout (see 'postconf -d' output)
The time limit for Postfix SMTP server write and
read operations during TLS startup and shutdown
handshake procedures.
@@ -647,6 +647,10 @@ SMTPD(8) SMTPD(8)
The list of error classes that are reported to the
postmaster.
+ smtpd_reject_contact_information (empty)
+ Optional contact information that is appended after
+ each SMTP server 4XX or 5XX response.
+
soft_bounce (no)
Safety net to keep mail queued that would otherwise
be returned to the sender.
@@ -654,22 +658,22 @@ SMTPD(8) SMTPD(8)
Available in Postfix version 2.1 and later:
smtpd_authorized_xclient_hosts (empty)
- What SMTP clients are allowed to use the XCLIENT
+ What SMTP clients are allowed to use the XCLIENT
feature.
KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS
- 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
LOCAL_RECIPIENT_README and ADDRESS_CLASS_README documents.
show_user_unknown_table_name (yes)
- Display the name of the recipient table in the
+ Display the name of the recipient table in the
"User unknown" responses.
canonical_maps (empty)
- Optional address mapping lookup tables for message
+ Optional address mapping lookup tables for message
headers and envelopes.
recipient_canonical_maps (empty)
@@ -680,7 +684,7 @@ SMTPD(8) SMTPD(8)
mydestination ($myhostname, localhost.$mydomain, local-
host)
- The list of domains that are delivered via the
+ The list of domains that are delivered via the
$local_transport mail delivery transport.
inet_interfaces (all)
@@ -689,146 +693,146 @@ SMTPD(8) SMTPD(8)
proxy_interfaces (empty)
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.
inet_protocols (ipv4)
- The Internet protocols Postfix will attempt to use
+ The Internet protocols Postfix will attempt to use
when making or accepting connections.
local_recipient_maps (proxy:unix:passwd.byname
$alias_maps)
- Lookup tables with all names or addresses of local
- recipients: a recipient address is local when its
- domain matches $mydestination, $inet_interfaces or
+ Lookup tables with all names or addresses of local
+ recipients: a recipient address is local when its
+ domain matches $mydestination, $inet_interfaces or
$proxy_interfaces.
unknown_local_recipient_reject_code (550)
- The numerical Postfix SMTP server response code
- when a recipient address is local, and
- $local_recipient_maps specifies a list of lookup
+ The numerical Postfix SMTP server response code
+ when a recipient address is local, and
+ $local_recipient_maps 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:
relay_domains ($mydestination)
- What destination domains (and subdomains thereof)
+ What destination domains (and subdomains thereof)
this system will relay mail to.
relay_recipient_maps (empty)
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $relay_domains.
unknown_relay_recipient_reject_code (550)
The numerical Postfix SMTP server reply code when a
- recipient address matches $relay_domains, and
- relay_recipient_maps specifies a list of lookup
+ recipient address matches $relay_domains, and
+ relay_recipient_maps 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:
virtual_alias_domains ($virtual_alias_maps)
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.
virtual_alias_maps ($virtual_maps)
- 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.
unknown_virtual_alias_reject_code (550)
The SMTP server reply code when a recipient address
- matches $virtual_alias_domains, and $vir-
- tual_alias_maps specifies a list of lookup tables
+ matches $virtual_alias_domains, and $vir-
+ tual_alias_maps 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:
virtual_mailbox_domains ($virtual_mailbox_maps)
Postfix is final destination for the specified list
- of domains; mail is delivered via the $vir-
+ of domains; mail is delivered via the $vir-
tual_transport mail delivery transport.
virtual_mailbox_maps (empty)
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $virtual_mailbox_domains.
unknown_virtual_mailbox_reject_code (550)
The SMTP server reply code when a recipient address
- matches $virtual_mailbox_domains, and $vir-
+ matches $virtual_mailbox_domains, and $vir-
tual_mailbox_maps specifies a list of lookup tables
that does not match the recipient address.
RESOURCE AND RATE CONTROLS
- 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.
line_length_limit (2048)
- 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.
queue_minfree (0)
- 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.
message_size_limit (10240000)
- The maximal size in bytes of a message, including
+ The maximal size in bytes of a message, including
envelope information.
smtpd_recipient_limit (1000)
- The maximal number of recipients that the Postfix
+ The maximal number of recipients that the Postfix
SMTP server accepts per message delivery request.
smtpd_timeout (normal: 300s, overload: 10s)
- 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.
smtpd_history_flush_threshold (100)
- 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:
smtpd_peername_lookup (yes)
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 anvil(8) ser-
- vice, and are available in Postfix version 2.2 and later.
+ vice, and are available in Postfix version 2.2 and later.
smtpd_client_connection_count_limit (50)
- How many simultaneous connections any client is
+ How many simultaneous connections any client is
allowed to make to this service.
smtpd_client_connection_rate_limit (0)
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.
smtpd_client_message_rate_limit (0)
- 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.
smtpd_client_recipient_rate_limit (0)
- 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.
smtpd_client_event_limit_exceptions ($mynetworks)
- Clients that are excluded from
+ Clients that are excluded from
smtpd_client_*_count/rate_limit restrictions.
Available in Postfix version 2.3 and later:
@@ -839,52 +843,52 @@ SMTPD(8) SMTPD(8)
tiate with this service per time unit.
TARPIT CONTROLS
- 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.
smtpd_error_sleep_time (1s)
With Postfix version 2.1 and later: the SMTP server
- response delay after a client has made more than
- $smtpd_soft_error_limit errors, and fewer than
- $smtpd_hard_error_limit errors, without delivering
+ response delay after a client has made more than
+ $smtpd_soft_error_limit errors, and fewer than
+ $smtpd_hard_error_limit errors, without delivering
mail.
smtpd_soft_error_limit (10)
- 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.
smtpd_hard_error_limit (normal: 20, overload: 1)
- 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.
smtpd_junk_command_limit (normal: 100, overload: 1)
- 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:
smtpd_recipient_overshoot_limit (1000)
- 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
$smtpd_recipient_limit, before the Postfix SMTP
- server increments the per-session error count for
+ server increments the per-session error count for
each excess recipient.
ACCESS POLICY DELEGATION CONTROLS
- 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 SMTPD_POLICY_README 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 SMTPD_POLICY_README for
more information.
smtpd_policy_service_max_idle (300s)
- The time after which an idle SMTPD policy service
+ The time after which an idle SMTPD policy service
connection is closed.
smtpd_policy_service_max_ttl (1000s)
@@ -892,151 +896,151 @@ SMTPD(8) SMTPD(8)
connection is closed.
smtpd_policy_service_timeout (100s)
- 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.
ACCESS CONTROLS
- The SMTPD_ACCESS_README document gives an introduction to
+ The SMTPD_ACCESS_README document gives an introduction to
all the SMTP server access control features.
smtpd_delay_reject (yes)
- Wait until the RCPT TO command before evaluating
+ Wait until the RCPT TO command before evaluating
$smtpd_client_restrictions, $smtpd_helo_restric-
tions and $smtpd_sender_restrictions, or wait until
- the ETRN command before evaluating
+ the ETRN command before evaluating
$smtpd_client_restrictions and $smtpd_helo_restric-
tions.
- parent_domain_matches_subdomains (see 'postconf -d' out-
+ parent_domain_matches_subdomains (see 'postconf -d' out-
put)
What Postfix features match subdomains of
"domain.tld" automatically, instead of requiring an
explicit ".domain.tld" pattern.
smtpd_client_restrictions (empty)
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client SMTP connection request.
smtpd_helo_required (no)
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.
smtpd_helo_restrictions (empty)
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the SMTP HELO command.
smtpd_sender_restrictions (empty)
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the MAIL FROM command.
smtpd_recipient_restrictions (permit_mynetworks,
reject_unauth_destination)
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.
smtpd_etrn_restrictions (empty)
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client ETRN request.
allow_untrusted_routing (no)
- 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 $relay_domains.
smtpd_restriction_classes (empty)
- User-defined aliases for groups of access restric-
+ User-defined aliases for groups of access restric-
tions.
smtpd_null_access_lookup_key (<>)
- The lookup key to be used in SMTP access(5) tables
+ The lookup key to be used in SMTP access(5) tables
instead of the null sender address.
permit_mx_backup_networks (empty)
Restrict the use of the permit_mx_backup 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:
smtpd_data_restrictions (empty)
- 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.
smtpd_expansion_filter (see 'postconf -d' output)
- 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:
smtpd_reject_unlisted_sender (no)
- Request that the Postfix SMTP server rejects mail
- from unknown sender addresses, even when no
- explicit reject_unlisted_sender access restriction
+ Request that the Postfix SMTP server rejects mail
+ from unknown sender addresses, even when no
+ explicit reject_unlisted_sender access restriction
is specified.
smtpd_reject_unlisted_recipient (yes)
- Request that the Postfix SMTP server rejects mail
+ Request that the Postfix SMTP server rejects mail
for unknown recipient addresses, even when no
- explicit reject_unlisted_recipient access restric-
+ explicit reject_unlisted_recipient access restric-
tion is specified.
Available in Postfix version 2.2 and later:
smtpd_end_of_data_restrictions (empty)
- 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.
SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS
- 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 reject_unverified_recipient 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 reject_unverified_recipient access
+ restrictions. The status of verification probes is main-
tained by the verify(8) server. See the file ADDRESS_VER-
- IFICATION_README for information about how to configure
+ IFICATION_README for information about how to configure
and operate the Postfix sender/recipient address verifica-
tion service.
address_verify_poll_count (normal: 3, overload: 1)
- How many times to query the verify(8) service for
- the completion of an address verification request
+ How many times to query the verify(8) service for
+ the completion of an address verification request
in progress.
address_verify_poll_delay (3s)
- The delay between queries for the completion of an
+ The delay between queries for the completion of an
address verification request in progress.
address_verify_sender ($double_bounce_sender)
- 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".
unverified_sender_reject_code (450)
- 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
reject_unverified_sender restriction.
unverified_recipient_reject_code (450)
- 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:
unverified_sender_defer_code (450)
- 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.
unverified_recipient_defer_code (450)
- 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.
unverified_sender_reject_reason (empty)
@@ -1050,7 +1054,7 @@ SMTPD(8) SMTPD(8)
unverified_sender_tempfail_action ($reject_temp-
fail_action)
The Postfix SMTP server's action when reject_unver-
- ified_sender fails due to a temporary error condi-
+ ified_sender fails due to a temporary error condi-
tion.
unverified_recipient_tempfail_action ($reject_temp-
@@ -1060,7 +1064,7 @@ SMTPD(8) SMTPD(8)
dition.
ACCESS CONTROL RESPONSES
- The following parameters control numerical SMTP reply
+ The following parameters control numerical SMTP reply
codes and/or text responses.
access_map_reject_code (554)
@@ -1068,18 +1072,18 @@ SMTPD(8) SMTPD(8)
an access(5) map "reject" action.
defer_code (450)
- 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.
invalid_hostname_reject_code (501)
- The numerical Postfix SMTP server response code
- when the client HELO or EHLO command parameter is
- rejected by the reject_invalid_helo_hostname
+ The numerical Postfix SMTP server response code
+ when the client HELO or EHLO command parameter is
+ rejected by the reject_invalid_helo_hostname
restriction.
maps_rbl_reject_code (554)
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
reject_rbl_client, reject_rhsbl_client,
reject_rhsbl_reverse_client, reject_rhsbl_sender or
@@ -1087,53 +1091,53 @@ SMTPD(8) SMTPD(8)
non_fqdn_reject_code (504)
The numerical Postfix SMTP server reply code when a
- client request is rejected by the
+ client request is rejected by the
reject_non_fqdn_helo_hostname,
reject_non_fqdn_sender or reject_non_fqdn_recipient
restriction.
plaintext_reject_code (450)
- The numerical Postfix SMTP server response code
- when a request is rejected by the reject_plain-
+ The numerical Postfix SMTP server response code
+ when a request is rejected by the reject_plain-
text_session restriction.
reject_code (554)
- 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.
relay_domains_reject_code (554)
- 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
reject_unauth_destination recipient restriction.
unknown_address_reject_code (450)
- 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 reject_unknown_sender_domain or
reject_unknown_recipient_domain restriction.
unknown_client_reject_code (450)
- 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.
unknown_hostname_reject_code (450)
- 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
reject_unknown_helo_hostname restriction.
Available in Postfix version 2.0 and later:
default_rbl_reply (see 'postconf -d' output)
- 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.
multi_recipient_bounce_reject_code (550)
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
reject_multi_recipient_bounce restriction.
@@ -1144,38 +1148,38 @@ SMTPD(8) SMTPD(8)
access_map_defer_code (450)
The numerical Postfix SMTP server response code for
- an access(5) map "defer" action, including
+ an access(5) map "defer" action, including
"defer_if_permit" or "defer_if_reject".
reject_tempfail_action (defer_if_permit)
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.
unknown_helo_hostname_tempfail_action ($reject_temp-
fail_action)
- The Postfix SMTP server's action when
+ The Postfix SMTP server's action when
reject_unknown_helo_hostname fails due to an tempo-
rary error condition.
unknown_address_tempfail_action ($reject_tempfail_action)
- The Postfix SMTP server's action when
+ The Postfix SMTP server's action when
reject_unknown_sender_domain or
- reject_unknown_recipient_domain fail due to a tem-
+ reject_unknown_recipient_domain fail due to a tem-
porary error condition.
MISCELLANEOUS CONTROLS
config_directory (see 'postconf -d' output)
- The default location of the Postfix main.cf and
+ The default location of the Postfix main.cf and
master.cf configuration files.
daemon_timeout (18000s)
- 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.
command_directory (see 'postconf -d' output)
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
double_bounce_sender (double-bounce)
@@ -1196,37 +1200,37 @@ SMTPD(8) SMTPD(8)
and most Postfix daemon processes.
max_idle (100s)
- 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.
max_use (100)
- 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.
myhostname (see 'postconf -d' output)
The internet hostname of this mail system.
mynetworks (see 'postconf -d' output)
- The list of "trusted" SMTP clients that have more
+ The list of "trusted" SMTP clients that have more
privileges than "strangers".
myorigin ($myhostname)
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.
process_id (read-only)
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
process_name (read-only)
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
queue_directory (see 'postconf -d' output)
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
recipient_delimiter (empty)
@@ -1234,28 +1238,28 @@ SMTPD(8) SMTPD(8)
sions (user+foo).
smtpd_banner ($myhostname ESMTP $mail_name)
- The text that follows the 220 status code in the
+ The text that follows the 220 status code in the
SMTP greeting banner.
syslog_facility (mail)
The syslog facility of Postfix logging.
syslog_name (see 'postconf -d' output)
- 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:
smtpd_forbidden_commands (CONNECT, GET, POST)
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:
smtpd_client_port_logging (no)
- 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.
SEE ALSO
@@ -1285,7 +1289,7 @@ SMTPD(8) SMTPD(8)
XFORWARD_README, Postfix XFORWARD extension
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 66beefb09..0258f573c 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -8094,6 +8094,67 @@ smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
.fi
.ad
.ft R
+.SH smtpd_reject_contact_information (default: empty)
+Optional contact information that is appended after each SMTP
+server 4XX or 5XX response.
+.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 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
diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8
index 1dd8cc5ae..a4f7fd5ea 100644
--- a/postfix/man/man8/smtpd.8
+++ b/postfix/man/man8/smtpd.8
@@ -341,7 +341,7 @@ smtpd_use_tls and smtpd_enforce_tls.
.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"
@@ -527,6 +527,9 @@ before-queue content inspection by non_smtpd_milters, header_checks
and body_checks.
.IP "\fBnotify_classes (resource, software)\fR"
The list of error classes that are reported to the postmaster.
+.IP "\fBsmtpd_reject_contact_information (empty)\fR"
+Optional contact information that is appended after each SMTP
+server 4XX or 5XX response.
.IP "\fBsoft_bounce (no)\fR"
Safety net to keep mail queued that would otherwise be returned to
the sender.
diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink
index 937495de4..e77614fe5 100755
--- a/postfix/mantools/postlink
+++ b/postfix/mantools/postlink
@@ -666,6 +666,7 @@ while (<>) {
s;\bsmtpd_tls_always_issue_session_ids\b;$&;g;
s;\bsmtpd_tls_wrappermode\b;$&;g;
s;\bsmtpd_use_tls\b;$&;g;
+ s;\bsmtpd_reject_contact_information\b;$&;g;
s;\btls_daemon_random_bytes\b;$&;g;
s;\btls_daemon_random_source\b;$&;g;
s;\btls_ran[-]*\n* *[]*dom_bytes\b;$&;g;
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index 0a44cfdfc..c39a711cc 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -13822,3 +13822,62 @@ for further details.
This feature is available in Postfix 2.8 and later.
+%PARAM smtpd_reject_contact_information
+
+ Optional contact information that is appended after each SMTP
+server 4XX or 5XX response.
+
+ Example:
+
+
+/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).
+
+
+ Server response:
+
+
+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).
+
+
+ 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.
+
+ 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.
+
+
+ This feature supports a limited number of $name attributes in
+the contact text. These are replaced by their current value for the
+SMTP session:
+
+
+
+- client_address
- Client IP address
+
+- client_port
- Client TCP port
+
+- localtime
- Server local time (Mmm dd hh:mm:ss)
+
+- recipient
- The address in the RCPT TO command
+
+- sender
- The address in the MAIL FROM command
+
+
+
+ For safety reasons, text that does not match $smtpd_expansion_filter
+is censored.
+
+ 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.
+
+ This feature is available in Postfix 2.8 and later.
diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in
index 6c1e0166d..47ab4d16a 100644
--- a/postfix/src/global/Makefile.in
+++ b/postfix/src/global/Makefile.in
@@ -802,6 +802,7 @@ dict_ldap.o: ../../include/match_list.h
dict_ldap.o: ../../include/match_ops.h
dict_ldap.o: ../../include/msg.h
dict_ldap.o: ../../include/mymalloc.h
+dict_ldap.o: ../../include/name_code.h
dict_ldap.o: ../../include/stringops.h
dict_ldap.o: ../../include/sys_defs.h
dict_ldap.o: ../../include/vbuf.h
@@ -811,6 +812,7 @@ dict_ldap.o: cfg_parser.h
dict_ldap.o: db_common.h
dict_ldap.o: dict_ldap.c
dict_ldap.o: dict_ldap.h
+dict_ldap.o: mail_conf.h
dict_ldap.o: string_list.h
dict_mysql.o: ../../include/sys_defs.h
dict_mysql.o: dict_mysql.c
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index a0796063b..c5644526b 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -3554,6 +3554,13 @@ extern int var_tlsp_tls_scache_timeout;
#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
diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h
index c3c97b5ad..84e825473 100644
--- a/postfix/src/global/mail_proto.h
+++ b/postfix/src/global/mail_proto.h
@@ -111,6 +111,7 @@ extern char *mail_pathname(const char *, const char *);
#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"
@@ -244,6 +245,14 @@ extern char *mail_pathname(const char *, const char *);
#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
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index c7ae8e44e..ffb3e0e7e 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20110103"
+#define MAIL_RELEASE_DATE "20110105"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
diff --git a/postfix/src/postscreen/Makefile.in b/postfix/src/postscreen/Makefile.in
index 5e41241a9..615ebb8f8 100644
--- a/postfix/src/postscreen/Makefile.in
+++ b/postfix/src/postscreen/Makefile.in
@@ -234,9 +234,13 @@ postscreen_starttls.o: ../../include/match_list.h
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
diff --git a/postfix/src/postscreen/postscreen_smtpd.c b/postfix/src/postscreen/postscreen_smtpd.c
index 07ebc8ca8..5384eb80e 100644
--- a/postfix/src/postscreen/postscreen_smtpd.c
+++ b/postfix/src/postscreen/postscreen_smtpd.c
@@ -205,20 +205,6 @@ static void psc_smtpd_read_event(int, char *);
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.
@@ -261,7 +247,7 @@ static int psc_helo_cmd(PSC_STATE *state, char *args)
/* 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;
@@ -291,12 +277,11 @@ static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
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);
@@ -393,7 +378,7 @@ static int psc_starttls_cmd(PSC_STATE *state, char *args)
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"));
@@ -955,7 +940,7 @@ static void psc_smtpd_read_event(int event, char *context)
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,
@@ -1052,8 +1037,14 @@ void psc_smtpd_init(void)
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)) {
@@ -1079,11 +1070,9 @@ void psc_smtpd_init(void)
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
/*
diff --git a/postfix/src/postscreen/postscreen_starttls.c b/postfix/src/postscreen/postscreen_starttls.c
index f43b53ec0..9d8c12805 100644
--- a/postfix/src/postscreen/postscreen_starttls.c
+++ b/postfix/src/postscreen/postscreen_starttls.c
@@ -55,6 +55,10 @@
#include
#include
+/* TLS library. */
+
+#include
+
/* Application-specific. */
#include
@@ -74,7 +78,6 @@ typedef struct {
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 */
@@ -155,9 +158,15 @@ static void psc_starttls_finish(int event, char *context)
* 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;
}
@@ -210,7 +219,7 @@ void psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
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);
diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in
index 0273877d6..856e8b8e6 100644
--- a/postfix/src/smtpd/Makefile.in
+++ b/postfix/src/smtpd/Makefile.in
@@ -1,13 +1,15 @@
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)
@@ -156,6 +158,8 @@ smtpd.o: ../../include/input_transp.h
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
@@ -188,6 +192,7 @@ smtpd.o: ../../include/string_list.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
@@ -202,6 +207,7 @@ smtpd.o: smtpd.c
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
@@ -210,9 +216,12 @@ smtpd.o: smtpd_token.h
smtpd_chat.o: ../../include/argv.h
smtpd_chat.o: ../../include/attr.h
smtpd_chat.o: ../../include/cleanup_user.h
+smtpd_chat.o: ../../include/dsn_util.h
smtpd_chat.o: ../../include/int_filt.h
smtpd_chat.o: ../../include/iostuff.h
smtpd_chat.o: ../../include/line_wrap.h
+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
@@ -237,6 +246,7 @@ smtpd_chat.o: ../../include/vstring.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
@@ -303,12 +313,35 @@ smtpd_check.o: smtpd.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
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 638cc95a0..0026c2571 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -309,7 +309,7 @@
/* .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"
@@ -489,6 +489,9 @@
/* and body_checks.
/* .IP "\fBnotify_classes (resource, software)\fR"
/* The list of error classes that are reported to the postmaster.
+/* .IP "\fBsmtpd_reject_contact_information (empty)\fR"
+/* Optional contact information that is appended after each SMTP
+/* server 4XX or 5XX response.
/* .IP "\fBsoft_bounce (no)\fR"
/* Safety net to keep mail queued that would otherwise be returned to
/* the sender.
@@ -1048,6 +1051,7 @@
#include
#include
#include
+#include
/* Single-threaded server skeleton. */
@@ -1067,6 +1071,7 @@
#include
#include
#include
+#include
/*
* Tunable parameters. Make sure that there is some bound on the length of
@@ -1182,6 +1187,7 @@ bool var_smtpd_enforce_tls;
bool var_smtpd_tls_wrappermode;
bool var_smtpd_tls_auth_only;
char *var_smtpd_cmd_filter;
+char *var_smtpd_rej_contact;
#ifdef USE_TLS
char *var_smtpd_relay_ccerts;
@@ -1324,8 +1330,6 @@ static int ask_client_cert;
#endif
-static int enforce_tls;
-
/*
* SMTP command mapping for broken clients.
*/
@@ -1640,7 +1644,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
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
@@ -3958,11 +3962,11 @@ static void smtpd_start_tls(SMTPD_STATE *state)
} 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");
@@ -3979,7 +3983,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
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,
@@ -4079,6 +4083,11 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
const char *err;
int rate;
+#ifdef USE_TLSPROXY
+ VSTREAM *proxy_stream;
+
+#endif
+
if (argc != 1) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 5.5.4 Syntax: STARTTLS");
@@ -4102,18 +4111,20 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
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
@@ -4139,9 +4150,11 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
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.
@@ -4159,6 +4172,73 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
*/
smtpd_start_tls(state);
return (0);
+#else /* USE_TLSPROXY */
+
+ /*
+ * This is non-production code, for tlsproxy(8) load testing only. It
+ * implements enough to enable the Postfix features that depend on TLS
+ * encryption.
+ */
+#define PROXY_OPEN_FLAGS \
+ (TLS_PROXY_FLAG_ROLE_SERVER | TLS_PROXY_FLAG_SEND_CONTEXT)
+
+ proxy_stream = tls_proxy_open(PROXY_OPEN_FLAGS, state->client, state->addr,
+ state->port, var_smtpd_tmout);
+ if (proxy_stream == 0) {
+ state->error_mask |= MAIL_ERROR_SOFTWARE;
+ /* RFC 4954 Section 6. */
+ smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
+ return (-1);
+ }
+ smtpd_chat_reply(state, "220 2.0.0 Ready to start TLS");
+ smtp_flush(state->client);
+ vstream_fpurge(state->client, VSTREAM_PURGE_READ);
+
+ /*
+ * Reset all inputs to the initial state.
+ *
+ * XXX RFC 2487 does not forbid the use of STARTTLS while mail transfer is
+ * in progress, so we have to allow it even when it makes no sense.
+ */
+ helo_reset(state);
+ mail_reset(state);
+ rcpt_reset(state);
+#ifdef USE_SASL_AUTH
+ if (var_smtpd_sasl_enable) {
+ if (smtpd_sasl_is_active(state)) {
+ smtpd_sasl_auth_reset(state);
+ smtpd_sasl_deactivate(state);
+ }
+ smtpd_sasl_activate(state, VAR_SMTPD_SASL_TLS_OPTS,
+ var_smtpd_sasl_tls_opts);
+ }
+#endif
+
+ /*
+ * To insert tlsproxy(8) between this process and the SMTP client, we
+ * swap the file descriptors between the proxy_stream and state->client
+ * VSTREAMS, so that we don't have to worry about loss of all the
+ * user-configurable state->client attributes (such as longjump buffers).
+ */
+ vstream_control(proxy_stream, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
+ vstream_control(state->client, VSTREAM_CTL_SWAP_FD, proxy_stream,
+ VSTREAM_CTL_END);
+ (void) vstream_fclose(proxy_stream); /* direct-to-client stream! */
+
+ /*
+ * After plumbing the plaintext stream, receive the TLS context object.
+ * For this we must use the same VSTREAM buffer that we also use to
+ * receive subsequent SMTP commands.
+ *
+ * When the TLS handshake fails, the conversation is in an unknown state.
+ * There is nothing we can do except to disconnect from the client.
+ */
+ state->tls_context = tls_proxy_state_receive(state->client);
+ if (state->tls_context == 0)
+ vstream_longjmp(state->client, SMTP_ERR_EOF);
+
+ return (0);
+#endif /* USE_TLSPROXY */
}
/* tls_reset - undo STARTTLS */
@@ -4174,8 +4254,12 @@ static void tls_reset(SMTPD_STATE *state)
if (vstream_feof(state->client) || vstream_ferror(state->client))
failure = 1;
vstream_fflush(state->client); /* NOT: smtp_flush() */
+#ifndef USE_TLSPROXY
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;
}
}
@@ -4294,6 +4378,9 @@ static void smtpd_proto(SMTPD_STATE *state)
*/
#ifdef USE_TLS
if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) {
+#ifdef USE_TLSPROXY
+ msg_fatal("Wrapper-mode is unimplemented.");
+#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"
@@ -4314,6 +4401,7 @@ static void smtpd_proto(SMTPD_STATE *state)
break;
}
smtpd_start_tls(state);
+#endif /* USE_TLSPROXY */
}
#endif
@@ -4473,7 +4561,7 @@ static void smtpd_proto(SMTPD_STATE *state)
#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
@@ -4558,7 +4646,7 @@ static void smtpd_proto(SMTPD_STATE *state)
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,
@@ -4674,26 +4762,13 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
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.
@@ -4742,7 +4817,6 @@ static void pre_accept(char *unused_name, char **unused_argv)
static void pre_jail_init(char *unused_name, char **unused_argv)
{
- int use_tls;
/*
* Initialize blacklist/etc. patterns before entering the chroot jail, in
@@ -4767,6 +4841,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
*/
if (getuid() == 0 || getuid() == var_owner_uid)
smtpd_check_init();
+ smtpd_expand_init();
debug_peer_init();
if (var_smtpd_sasl_enable)
@@ -4818,8 +4893,18 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
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
@@ -4827,7 +4912,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
* 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;
@@ -4843,7 +4928,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
*/
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 = "";
@@ -4857,7 +4942,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
/* 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))
@@ -4888,7 +4973,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
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,
@@ -5175,6 +5260,7 @@ int main(int argc, char **argv)
static const CONFIG_RAW_TABLE raw_table[] = {
VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
VAR_DEF_RBL_REPLY, DEF_DEF_RBL_REPLY, &var_def_rbl_reply, 1, 0,
+ VAR_SMTPD_REJ_CONTACT, DEF_SMTPD_REJ_CONTACT, &var_smtpd_rej_contact, 0, 0,
0,
};
diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h
index 931dcbcfd..9b98ac7d3 100644
--- a/postfix/src/smtpd/smtpd.h
+++ b/postfix/src/smtpd/smtpd.h
@@ -165,9 +165,6 @@ typedef struct {
* 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
diff --git a/postfix/src/smtpd/smtpd_chat.c b/postfix/src/smtpd/smtpd_chat.c
index fac66d3d6..72f17fd43 100644
--- a/postfix/src/smtpd/smtpd_chat.c
+++ b/postfix/src/smtpd/smtpd_chat.c
@@ -83,10 +83,12 @@
#include
#include
#include
+#include
/* Application-specific. */
#include "smtpd.h"
+#include "smtpd_expand.h"
#include "smtpd_chat.h"
#define STR vstring_str
@@ -145,6 +147,7 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
char *cp;
char *next;
char *end;
+ ssize_t dsn_len;
/*
* Slow down clients that make errors. Sleep-on-anything slows down
@@ -153,9 +156,48 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
if (state->error_count >= var_smtpd_soft_erlim)
sleep(delay = var_smtpd_err_sleep);
+ /*
+ * The caller may send multi-line text, so we can't assume that there is
+ * only one SMTP reply code at the beginning of the response.
+ */
va_start(ap, format);
vstring_vsprintf(state->buffer, format, ap);
va_end(ap);
+
+ /*
+ * Append the optional contact footer. Caution: as we append parts from
+ * the buffer to itself, extend the buffer before updating it, or else we
+ * have a dangling pointer bug.
+ */
+ if (*var_smtpd_rej_contact
+ && (*(cp = STR(state->buffer)) == '4' || *cp == '5')
+ && ISDIGIT(cp[1]) && ISDIGIT(cp[2]) && cp[3] == ' ') {
+ dsn_len = dsn_valid(cp + 4);
+ for (cp = var_smtpd_rej_contact, end = cp + strlen(cp);;) {
+ if ((next = strstr(cp, "\\n")) != 0) {
+ *next = 0;
+ } else {
+ next = end;
+ }
+ /* Append a clone of the SMTP reply code. */
+ VSTRING_SPACE(state->buffer, sizeof("\r\n550 "));
+ vstring_sprintf_append(state->buffer, "\r\n%.3s ",
+ STR(state->buffer));
+ /* Append a clone of the optional enhanced status code. */
+ if (dsn_len > 0) {
+ VSTRING_SPACE(state->buffer, dsn_len + 1);
+ vstring_sprintf_append(state->buffer, "%.*s ",
+ (int) dsn_len, STR(state->buffer) + 4);
+ }
+ /* Append the actual contact information. */
+ smtpd_expand(state, state->buffer, cp, MAC_EXP_FLAG_APPEND);
+ if (next < end) {
+ *next = '\\';
+ cp = next + 2;
+ } else
+ break;
+ }
+ }
/* 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) {
@@ -168,6 +210,7 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
/* 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;
}
diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c
index c1b2330bf..e381a36f3 100644
--- a/postfix/src/smtpd/smtpd_check.c
+++ b/postfix/src/smtpd/smtpd_check.c
@@ -246,6 +246,7 @@
#include "smtpd_check.h"
#include "smtpd_dsn_fix.h"
#include "smtpd_resolve.h"
+#include "smtpd_expand.h"
#define RESTRICTION_SEPARATORS ", \t\r\n"
@@ -331,11 +332,6 @@ static HTABLE *policy_clnt_table;
static ARGV *local_rewrite_clients;
- /*
- * Pre-parsed expansion filter.
- */
-static VSTRING *expand_filter;
-
/*
* The routine that recursively applies restrictions.
*/
@@ -704,12 +700,6 @@ void smtpd_check_init(void)
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.
*/
@@ -2828,123 +2818,6 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
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];
@@ -3061,6 +2934,8 @@ static const char *rbl_expand_lookup(const char *name, int mode,
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);
@@ -3121,7 +2996,7 @@ static int rbl_reject_reply(SMTPD_STATE *state, const SMTPD_RBL_STATE *rbl,
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)
diff --git a/postfix/src/smtpd/smtpd_expand.c b/postfix/src/smtpd/smtpd_expand.c
new file mode 100644
index 000000000..6683f4e0f
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_expand.c
@@ -0,0 +1,238 @@
+/*++
+/* NAME
+/* smtpd_expand 3
+/* SUMMARY
+/* SMTP server macro expansion
+/* SYNOPSIS
+/* #include
+/* #include
+/*
+/* 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
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+#include
+
+/* Global library. */
+
+#include
+#include
+
+/* Application-specific. */
+
+#include
+#include
+
+ /*
+ * 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));
+}
diff --git a/postfix/src/smtpd/smtpd_expand.h b/postfix/src/smtpd/smtpd_expand.h
new file mode 100644
index 000000000..7c0f838ac
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_expand.h
@@ -0,0 +1,35 @@
+/*++
+/* NAME
+/* smtpd_expand 3h
+/* SUMMARY
+/* SMTP server macro expansion
+/* SYNOPSIS
+/* #include
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include
+#include
+
+ /*
+ * 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
+/*--*/
diff --git a/postfix/src/smtpd/smtpd_sasl_proto.c b/postfix/src/smtpd/smtpd_sasl_proto.c
index 9fcdc1ed0..f419dc6bb 100644
--- a/postfix/src/smtpd/smtpd_sasl_proto.c
+++ b/postfix/src/smtpd/smtpd_sasl_proto.c
@@ -166,7 +166,7 @@ int smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
}
}
#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");
diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c
index 24091fa61..8dc77a0b0 100644
--- a/postfix/src/smtpd/smtpd_state.c
+++ b/postfix/src/smtpd/smtpd_state.c
@@ -138,9 +138,6 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
state->dsn_buf = vstring_alloc(100);
state->dsn_orcpt_buf = vstring_alloc(100);
#ifdef USE_TLS
- state->tls_use_tls = 0;
- state->tls_enforce_tls = 0;
- state->tls_auth_only = 0;
state->tls_context = 0;
#endif
diff --git a/postfix/src/tls/Makefile.in b/postfix/src/tls/Makefile.in
index 74c04bcaa..f47ae4ec6 100644
--- a/postfix/src/tls/Makefile.in
+++ b/postfix/src/tls/Makefile.in
@@ -3,13 +3,15 @@ SRCS = tls_prng_dev.c tls_prng_egd.c tls_prng_file.c \
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)
@@ -200,6 +202,49 @@ tls_prng_file.o: ../../include/mymalloc.h
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
diff --git a/postfix/src/tls/tls_proxy.h b/postfix/src/tls/tls_proxy.h
new file mode 100644
index 000000000..3cf093a51
--- /dev/null
+++ b/postfix/src/tls/tls_proxy.h
@@ -0,0 +1,56 @@
+#ifndef _TLS_PROXY_H_INCLUDED_
+#define _TLS_PROXY_H_INCLUDED_
+
+/*++
+/* NAME
+/* tls_proxy_clnt 3h
+/* SUMMARY
+/* postscreen TLS proxy support
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include
+#include
+
+ /*
+ * TLS library.
+ */
+#include
+
+ /*
+ * 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
diff --git a/postfix/src/tls/tls_proxy_clnt.c b/postfix/src/tls/tls_proxy_clnt.c
new file mode 100644
index 000000000..9f723d21a
--- /dev/null
+++ b/postfix/src/tls/tls_proxy_clnt.c
@@ -0,0 +1,226 @@
+/*++
+/* NAME
+/* tlsproxy_clnt 3
+/* SUMMARY
+/* postscreen TLS proxy support
+/* SYNOPSIS
+/* #include
+/*
+/* 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
+
+/* Utility library. */
+
+#include
+#include
+#include
+#include /* concatenate() */
+
+/* Global library. */
+
+#include
+
+/* TLS library-specific. */
+
+#include
+#include
+
+#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
diff --git a/postfix/src/tls/tls_proxy_print.c b/postfix/src/tls/tls_proxy_print.c
new file mode 100644
index 000000000..da759fdeb
--- /dev/null
+++ b/postfix/src/tls/tls_proxy_print.c
@@ -0,0 +1,84 @@
+/*++
+/* NAME
+/* tls_proxy_print
+/* SUMMARY
+/* write DSN structure to stream
+/* SYNOPSIS
+/* #include
+/*
+/* 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
+
+/* Utility library */
+
+#include
+
+/* Global library. */
+
+#include
+
+/* TLS library. */
+
+#include
+#include
+
+/* 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
diff --git a/postfix/src/tls/tls_proxy_scan.c b/postfix/src/tls/tls_proxy_scan.c
new file mode 100644
index 000000000..c68472743
--- /dev/null
+++ b/postfix/src/tls/tls_proxy_scan.c
@@ -0,0 +1,91 @@
+/*++
+/* NAME
+/* tls_proxy_scan
+/* SUMMARY
+/* read TLS session state from stream
+/* SYNOPSIS
+/* #include
+/*
+/* 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
+
+/* Utility library */
+
+#include
+
+/* Global library. */
+
+#include
+
+/* TLS library. */
+
+#include
+#include
+
+/* 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
diff --git a/postfix/src/tlsproxy/Makefile.in b/postfix/src/tlsproxy/Makefile.in
index 9b21b01d9..eb75dc5b7 100644
--- a/postfix/src/tlsproxy/Makefile.in
+++ b/postfix/src/tlsproxy/Makefile.in
@@ -74,6 +74,7 @@ tlsproxy.o: ../../include/name_mask.h
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
diff --git a/postfix/src/tlsproxy/tlsproxy.c b/postfix/src/tlsproxy/tlsproxy.c
index a7351e6a3..8786f29bf 100644
--- a/postfix/src/tlsproxy/tlsproxy.c
+++ b/postfix/src/tlsproxy/tlsproxy.c
@@ -218,6 +218,7 @@
#ifdef USE_TLS
#define TLS_INTERNAL /* XXX */
#include
+#include
/*
* Application-specific.
@@ -292,8 +293,6 @@ int var_tlsp_watchdog;
*/
static TLS_APPL_STATE *tlsp_server_ctx;
static int ask_client_cert;
-static int enforce_tls;
-static int tlsp_tls_enforce_tls;
/*
* SLMs.
@@ -468,6 +467,15 @@ static void tlsp_strategy(TLSP_STATE *state)
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;
}
@@ -630,7 +638,7 @@ static void tlsp_ciphertext_event(int event, char *context)
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);
@@ -668,10 +676,10 @@ static void tlsp_start_tls(TLSP_STATE *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");
@@ -683,7 +691,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
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,
@@ -779,17 +787,15 @@ static void tlsp_get_request_event(int event, char *context)
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
@@ -807,7 +813,7 @@ static void tlsp_get_request_event(int event, char *context)
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);
@@ -820,7 +826,7 @@ static void tlsp_get_request_event(int event, char *context)
* 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,
@@ -841,7 +847,11 @@ static void tlsp_get_request_event(int event, char *context)
*/
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,
@@ -868,10 +878,13 @@ static void tlsp_service(VSTREAM *plaintext_stream,
/*
* 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);
/*
@@ -922,8 +935,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
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;
@@ -937,7 +950,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
*/
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 = "";
@@ -951,7 +964,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
/* 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))
@@ -980,7 +993,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
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,
diff --git a/postfix/src/tlsproxy/tlsproxy.h b/postfix/src/tlsproxy/tlsproxy.h
index 0c4d129c7..340e02fff 100644
--- a/postfix/src/tlsproxy/tlsproxy.h
+++ b/postfix/src/tlsproxy/tlsproxy.h
@@ -24,6 +24,7 @@
*/
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 */
diff --git a/postfix/src/util/mac_expand.c b/postfix/src/util/mac_expand.c
index 3bd304616..049d7c6ee 100644
--- a/postfix/src/util/mac_expand.c
+++ b/postfix/src/util/mac_expand.c
@@ -47,6 +47,8 @@
/* .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
@@ -231,7 +233,8 @@ int mac_expand(VSTRING *result, const char *pattern, int flags,
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);
diff --git a/postfix/src/util/mac_expand.h b/postfix/src/util/mac_expand.h
index 5ae6b5b99..6cd375a39 100644
--- a/postfix/src/util/mac_expand.h
+++ b/postfix/src/util/mac_expand.h
@@ -22,6 +22,7 @@
*/
#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?
diff --git a/postfix/src/util/vstream.c b/postfix/src/util/vstream.c
index 28e4c0a87..ba3e842b1 100644
--- a/postfix/src/util/vstream.c
+++ b/postfix/src/util/vstream.c
@@ -267,6 +267,10 @@
/* 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,
@@ -1222,6 +1226,9 @@ void vstream_control(VSTREAM *stream, int name,...)
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) {
@@ -1263,8 +1270,20 @@ void vstream_control(VSTREAM *stream, int 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)
diff --git a/postfix/src/util/vstream.h b/postfix/src/util/vstream.h
index 943953f67..3c6c16aea 100644
--- a/postfix/src/util/vstream.h
+++ b/postfix/src/util/vstream.h
@@ -132,6 +132,7 @@ extern void vstream_control(VSTREAM *, int,...);
#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 *,...);
diff --git a/postfix/src/xsasl/Makefile.in b/postfix/src/xsasl/Makefile.in
index 56dd1d637..0a46cbc64 100644
--- a/postfix/src/xsasl/Makefile.in
+++ b/postfix/src/xsasl/Makefile.in
@@ -132,6 +132,7 @@ xsasl_dovecot_server.o: ../../include/connect.h
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