diff --git a/postfix/HISTORY b/postfix/HISTORY
index 19eef1a2e..50274e0f3 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -16337,5 +16337,15 @@ Apologies for any names omitted.
TLS <=> plaintext for postscreen(8). One tlsproxy(8) process
can translate traffic for multiple remote SMTP clients.
With early testing feedback from Victor Duchovni and Christian
- Roessner. Files: util/nbbio.c, tlsproxy/starttlsd.c,
- tlsproxy/starttlsd_state.c.
+ Roessner. Files: util/nbbio.[hc], tlsproxy/*.[hc],
+ postscreen/postscreen_starttlsd.c, postscreen/postscreen_smtpd.c.
+
+20101103
+
+ Cleanup: missing tls_level support in tlsproxy (it has no
+ way to send plaintext, but perhaps an informative error
+ message is in order anyway). File: tlsproxy/tlsproxy.c.
+
+ 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.
diff --git a/postfix/WISHLIST b/postfix/WISHLIST
index 3092ca6fc..016482248 100644
--- a/postfix/WISHLIST
+++ b/postfix/WISHLIST
@@ -4,7 +4,12 @@ Wish list:
anvil rate limit for sasl_username.
- encapsulate nbbio buffer access and update by tlsproxy.
+ Encapsulate nbbio buffer access and update by tlsproxy.
+
+ Full-duplex support for tlsproxy(8). This requires updating
+ events(3) and nbbio(3).
+
+ Register automagic destructor for object attached to VSTREAM.
smtpd xclient option for sasl_username.
diff --git a/postfix/html/postscreen.8.html b/postfix/html/postscreen.8.html
index a4ab206fc..4f7250d7e 100644
--- a/postfix/html/postscreen.8.html
+++ b/postfix/html/postscreen.8.html
@@ -60,98 +60,101 @@ POSTSCREEN(8) POSTSCREEN(8)
RFC 3207 (STARTTLS command)
RFC 3461 (SMTP DSN Extension)
RFC 3463 (Enhanced Status Codes)
- RFC 5321 (SMTP protocol, including multi-line 220 greetings)
+ RFC 5321 (SMTP protocol, including multi-line 220 banners)
DIAGNOSTICS
Problems and transactions are logged to syslogd(8).
BUGS
- The postscreen(8) built-in SMTP protocol engine currently
- does not announce support for AUTH, XCLIENT or XFORWARD.
- Support for AUTH may be added in the future. In the mean
+ The postscreen(8) server does not yet implement the
+ soft_bounce feature.
+
+ The postscreen(8) built-in SMTP protocol engine currently
+ does not announce support for AUTH, XCLIENT or XFORWARD.
+ Support for AUTH may be added in the future. In the mean
time, if you need to make these services available on port
- 25, then do not enable the optional "after 220 server
+ 25, then do not enable the optional "after 220 server
greeting" tests.
- The optional "after 220 server greeting" tests involve
- postscreen(8)'s built-in SMTP protocol engine. When these
+ The optional "after 220 server greeting" tests involve
+ postscreen(8)'s built-in SMTP protocol engine. When these
tests succeed, postscreen(8) adds the client to the tempo-
- rary whitelist but it cannot not hand off the "live" con-
- nection to a Postfix SMTP server process in the middle of
- a session. Instead, postscreen(8) defers attempts to
- deliver mail with a 4XX status, and waits for the client
- to disconnect. The next time a good client connects, it
- will be allowed to talk to a Postfix SMTP server process
- to deliver mail. postscreen(8) mitigates the impact of
- this limitation by giving such tests a long expiration
+ rary whitelist but it cannot not hand off the "live" con-
+ nection to a Postfix SMTP server process in the middle of
+ a session. Instead, postscreen(8) defers attempts to
+ deliver mail with a 4XX status, and waits for the client
+ to disconnect. The next time a good client connects, it
+ will be allowed to talk to a Postfix SMTP server process
+ to deliver mail. postscreen(8) mitigates the impact of
+ this limitation by giving such tests a long expiration
time.
CONFIGURATION PARAMETERS
- Changes to main.cf are not picked up automatically, as
- postscreen(8) processes may run for several hours. Use
+ Changes to main.cf are not picked up automatically, as
+ postscreen(8) processes may run for several hours. Use
the command "postfix reload" after a configuration change.
- The text below provides only a parameter summary. See
+ The text below provides only a parameter summary. See
postconf(5) for more details including examples.
NOTE: Some postscreen(8) parameters implement stress-
- dependent behavior. This is supported only when the
- default parameter value is stress-dependent (that is, it
- looks like ${stress?X}${stress:Y}, or it is the $name of
+ dependent behavior. This is supported only when the
+ default parameter value is stress-dependent (that is, it
+ looks like ${stress?X}${stress:Y}, or it is the $name of
an smtpd parameter with a stress-dependent default).
- Other parameters always evaluate as if the stress parame-
+ Other parameters always evaluate as if the stress parame-
ter value is the empty string.
COMPATIBILITY CONTROLS
postscreen_discard_ehlo_keyword_address_maps ($smtpd_dis-
card_ehlo_keyword_address_maps)
- Lookup tables, indexed by the remote SMTP client
- address, with case insensitive lists of EHLO key-
- words (pipelining, starttls, auth, etc.) that the
- postscreen(8) server will not send in the EHLO
+ Lookup tables, indexed by the remote SMTP client
+ address, with case insensitive lists of EHLO key-
+ words (pipelining, starttls, auth, etc.) that the
+ postscreen(8) server will not send in the EHLO
response to a remote SMTP client.
postscreen_discard_ehlo_keywords ($smtpd_discard_ehlo_key-
words)
- A case insensitive list of EHLO keywords (pipelin-
- ing, starttls, auth, etc.) that the postscreen(8)
- server will not send in the EHLO response to a
+ A case insensitive list of EHLO keywords (pipelin-
+ ing, starttls, auth, etc.) that the postscreen(8)
+ server will not send in the EHLO response to a
remote SMTP client.
TRIAGE PARAMETERS
postscreen_bare_newline_action (ignore)
- The action that postscreen(8) takes when an SMTP
- client sends a bare newline character, that is, a
+ The action that postscreen(8) takes when an SMTP
+ client sends a bare newline character, that is, a
newline not preceded by carriage return.
postscreen_bare_newline_enable (no)
- Enable "bare newline" SMTP protocol tests in the
+ Enable "bare newline" SMTP protocol tests in the
postscreen(8) server.
postscreen_blacklist_action (ignore)
- The action that postscreen(8) takes when an SMTP
- client is permanently blacklisted with the
+ The action that postscreen(8) takes when an SMTP
+ client is permanently blacklisted with the
postscreen_blacklist_networks parameter.
postscreen_blacklist_networks (empty)
Network addresses that are permanently blacklisted;
- see the postscreen_blacklist_action parameter for
+ see the postscreen_blacklist_action parameter for
possible actions.
postscreen_disable_vrfy_command ($disable_vrfy_command)
- Disable the SMTP VRFY command in the postscreen(8)
+ Disable the SMTP VRFY command in the postscreen(8)
daemon.
postscreen_dnsbl_action (ignore)
- The action that postscreen(8) takes when an SMTP
+ The action that postscreen(8) takes when an SMTP
client's combined DNSBL score is equal to or
- greater than a threshold (as defined with the
+ greater than a threshold (as defined with the
postscreen_dnsbl_sites and postscreen_dnsbl_thresh-
old parameters).
postscreen_dnsbl_reply_map (empty)
- A mapping from actual DNSBL domain name which
- includes a secret password, to the DNSBL domain
+ A mapping from actual DNSBL domain name which
+ includes a secret password, to the DNSBL domain
name that postscreen will reply with when it
rejects mail.
@@ -160,16 +163,16 @@ POSTSCREEN(8) POSTSCREEN(8)
weight factors.
postscreen_dnsbl_threshold (1)
- The inclusive lower bound for blocking an SMTP
+ The inclusive lower bound for blocking an SMTP
client, based on its combined DNSBL score as
- defined with the postscreen_dnsbl_sites parameter.
+ defined with the postscreen_dnsbl_sites parameter.
postscreen_forbidden_commands ($smtpd_forbidden_commands)
List of commands that the postscreen(8) server con-
siders in violation of the SMTP protocol.
postscreen_greet_action (ignore)
- The action that postscreen(8) takes when an SMTP
+ The action that postscreen(8) takes when an SMTP
client speaks before its turn within the time spec-
ified with the postscreen_greet_wait parameter.
@@ -177,151 +180,151 @@ POSTSCREEN(8) POSTSCREEN(8)
The text in the optional "220-text..." server
response that postscreen(8) sends ahead of the real
Postfix SMTP server's "220 text..." response, in an
- attempt to confuse bad SMTP clients so that they
+ attempt to confuse bad SMTP clients so that they
speak before their turn (pre-greet).
postscreen_greet_wait (${stress?2}${stress:6}s)
The amount of time that postscreen(8) will wait for
- an SMTP client to send a command before its turn,
- and for DNS blocklist lookup results to arrive
- (default: up to 2 seconds under stress, up to 6
+ an SMTP client to send a command before its turn,
+ and for DNS blocklist lookup results to arrive
+ (default: up to 2 seconds under stress, up to 6
seconds otherwise).
postscreen_helo_required ($smtpd_helo_required)
- Require that a remote SMTP client sends HELO or
+ Require that a remote SMTP client sends HELO or
EHLO before commencing a MAIL transaction.
postscreen_non_smtp_command_action (drop)
- The action that postscreen(8) takes when an SMTP
- client sends non-SMTP commands as specified with
+ The action that postscreen(8) takes when an SMTP
+ client sends non-SMTP commands as specified with
the postscreen_forbidden_commands parameter.
postscreen_non_smtp_command_enable (no)
- Enable "non-SMTP command" tests in the
+ Enable "non-SMTP command" tests in the
postscreen(8) server.
postscreen_pipelining_action (enforce)
- The action that postscreen(8) takes when an SMTP
- client sends multiple commands instead of sending
- one command and waiting for the server to respond.
+ The action that postscreen(8) takes when an SMTP
+ client sends multiple commands instead of sending
+ one command and waiting for the server to respond.
postscreen_pipelining_enable (no)
- Enable "pipelining" SMTP protocol tests in the
+ Enable "pipelining" SMTP protocol tests in the
postscreen(8) server.
postscreen_whitelist_networks ($mynetworks)
Network addresses that are permanently whitelisted,
- and that will not be subjected to postscreen(8)
+ and that will not be subjected to postscreen(8)
checks.
smtpd_service_name (smtpd)
- The internal service that postscreen(8) forwards
+ The internal service that postscreen(8) forwards
allowed connections to.
CACHE CONTROLS
postscreen_cache_cleanup_interval (12h)
- The amount of time between postscreen(8) cache
+ The amount of time between postscreen(8) cache
cleanup runs.
postscreen_cache_map (btree:$data_directory/ps_cache)
- Persistent storage for the postscreen(8) server
+ Persistent storage for the postscreen(8) server
decisions.
postscreen_cache_retention_time (7d)
The amount of time that postscreen(8) will cache an
- expired temporary whitelist entry before it is
+ expired temporary whitelist entry before it is
removed.
postscreen_bare_newline_ttl (30d)
- The amount of time that postscreen(8) will cache
- results from a successful "bare newline" SMTP pro-
+ The amount of time that postscreen(8) will cache
+ results from a successful "bare newline" SMTP pro-
tocol test.
postscreen_dnsbl_ttl (1h)
- The amount of time that postscreen(8) will cache
+ The amount of time that postscreen(8) will cache
results from a successful DNS blocklist test.
postscreen_greet_ttl (1d)
- The amount of time that postscreen(8) will cache
+ The amount of time that postscreen(8) will cache
results from a successful PREGREET test.
postscreen_non_smtp_command_ttl (30d)
- The amount of time that postscreen(8) will cache
- results from a successful "non_smtp_command" SMTP
+ The amount of time that postscreen(8) will cache
+ results from a successful "non_smtp_command" SMTP
protocol test.
postscreen_pipelining_ttl (30d)
- The amount of time that postscreen(8) will cache
- results from a successful "pipelining" SMTP proto-
+ The amount of time that postscreen(8) will cache
+ results from a successful "pipelining" SMTP proto-
col test.
RESOURCE CONTROLS
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.
postscreen_client_connection_count_limit
($smtpd_client_connection_count_limit)
- How many simultaneous connections any client is
+ How many simultaneous connections any client is
allowed to have with the postscreen(8) daemon.
postscreen_command_count_limit (20)
- The limit on the total number of commands per SMTP
- session for postscreen(8)'s built-in SMTP protocol
+ The limit on the total number of commands per SMTP
+ session for postscreen(8)'s built-in SMTP protocol
engine.
postscreen_command_time_limit (${stress?10}${stress:300}s)
- The command "read" time limit for postscreen(8)'s
+ The command "read" time limit for postscreen(8)'s
built-in SMTP protocol engine.
postscreen_post_queue_limit ($default_process_limit)
- The number of clients that can be waiting for ser-
+ The number of clients that can be waiting for ser-
vice from a real SMTP server process.
postscreen_pre_queue_limit ($default_process_limit)
- The number of non-whitelisted clients that can be
- waiting for a decision whether they will receive
+ The number of non-whitelisted clients that can be
+ waiting for a decision whether they will receive
service from a real SMTP server process.
postscreen_watchdog_timeout (10s)
- How much time a postscreen(8) process may take to
- respond to an SMTP client command or to perform a
+ How much time a postscreen(8) process may take to
+ respond to an SMTP client command or to perform a
cache operation before it is terminated by a built-
in watchdog timer.
STARTTLS CONTROLS
postscreen_tls_security_level ($smtpd_tls_security_level)
- The SMTP TLS security level for the postscreen(8)
- server; when a non-empty value is specified, this
+ The SMTP TLS security level for the postscreen(8)
+ server; when a non-empty value is specified, this
overrides the obsolete parameters
postscreen_use_tls and postscreen_enforce_tls.
OBSOLETE STARTTLS SUPPORT CONTROLS
- These parameters are supported for compatibility with
+ These parameters are supported for compatibility with
smtpd(8) legacy parameters.
postscreen_use_tls ($smtpd_use_tls)
- Opportunistic TLS: announce STARTTLS support to
- SMTP clients, but do not require that clients use
+ Opportunistic TLS: announce STARTTLS support to
+ SMTP clients, but do not require that clients use
TLS encryption.
postscreen_enforce_tls ($smtpd_enforce_tls)
- Mandatory TLS: announce STARTTLS support to SMTP
- clients, and require that clients use TLS encryp-
+ Mandatory TLS: announce STARTTLS support to SMTP
+ clients, and require that clients use TLS encryp-
tion.
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.
delay_logging_resolution_limit (2)
- The maximal number of digits after the decimal
+ The maximal number of digits after the decimal
point when logging sub-second delay values.
command_directory (see 'postconf -d' output)
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
ipc_timeout (3600s)
@@ -329,24 +332,24 @@ POSTSCREEN(8) POSTSCREEN(8)
over an internal communication channel.
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.
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.
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".
SEE ALSO
@@ -359,12 +362,12 @@ POSTSCREEN(8) POSTSCREEN(8)
POSTSCREEN_README, Postfix Postscreen Howto
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
HISTORY
- Many ideas in postscreen(8) were explored in earlier work
- by Michael Tokarev, in OpenBSD spamd, and in MailChannels
+ Many ideas in postscreen(8) were explored in earlier work
+ by Michael Tokarev, in OpenBSD spamd, and in MailChannels
Traffic Control.
AUTHOR(S)
diff --git a/postfix/man/man8/postscreen.8 b/postfix/man/man8/postscreen.8
index f8acab135..67b09c982 100644
--- a/postfix/man/man8/postscreen.8
+++ b/postfix/man/man8/postscreen.8
@@ -63,7 +63,7 @@ RFC 2920 (SMTP Pipelining)
RFC 3207 (STARTTLS command)
RFC 3461 (SMTP DSN Extension)
RFC 3463 (Enhanced Status Codes)
-RFC 5321 (SMTP protocol, including multi-line 220 greetings)
+RFC 5321 (SMTP protocol, including multi-line 220 banners)
.SH DIAGNOSTICS
.ad
.fi
@@ -71,6 +71,9 @@ Problems and transactions are logged to \fBsyslogd\fR(8).
.SH BUGS
.ad
.fi
+The \fBpostscreen\fR(8) server does not yet implement
+the \fBsoft_bounce\fR feature.
+
The \fBpostscreen\fR(8) built-in SMTP protocol engine
currently does not announce support for AUTH, XCLIENT or
XFORWARD.
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index c1e99f217..c7ae8e44e 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 "20110102"
+#define MAIL_RELEASE_DATE "20110103"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
diff --git a/postfix/src/postscreen/Makefile.in b/postfix/src/postscreen/Makefile.in
index b856fc5ff..5e41241a9 100644
--- a/postfix/src/postscreen/Makefile.in
+++ b/postfix/src/postscreen/Makefile.in
@@ -180,6 +180,7 @@ postscreen_send.o: ../../include/dict_cache.h
postscreen_send.o: ../../include/events.h
postscreen_send.o: ../../include/htable.h
postscreen_send.o: ../../include/iostuff.h
+postscreen_send.o: ../../include/mail_params.h
postscreen_send.o: ../../include/match_list.h
postscreen_send.o: ../../include/match_ops.h
postscreen_send.o: ../../include/msg.h
diff --git a/postfix/src/postscreen/postscreen.c b/postfix/src/postscreen/postscreen.c
index f40f25e01..580955461 100644
--- a/postfix/src/postscreen/postscreen.c
+++ b/postfix/src/postscreen/postscreen.c
@@ -53,10 +53,13 @@
/* RFC 3207 (STARTTLS command)
/* RFC 3461 (SMTP DSN Extension)
/* RFC 3463 (Enhanced Status Codes)
-/* RFC 5321 (SMTP protocol, including multi-line 220 greetings)
+/* RFC 5321 (SMTP protocol, including multi-line 220 banners)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS
+/* The \fBpostscreen\fR(8) server does not yet implement
+/* the \fBsoft_bounce\fR feature.
+/*
/* The \fBpostscreen\fR(8) built-in SMTP protocol engine
/* currently does not announce support for AUTH, XCLIENT or
/* XFORWARD.
@@ -542,9 +545,10 @@ static void psc_service(VSTREAM *smtp_client_stream,
if (getpeername(vstream_fileno(smtp_client_stream), (struct sockaddr *)
& addr_storage, &addr_storage_len) < 0) {
msg_warn("getpeername: %m -- dropping this connection");
- psc_send_reply(vstream_fileno(smtp_client_stream),
- "unknown_address", "unknown_port",
- "421 4.3.2 No system resources\r\n");
+ /* Best effort - if this non-blocking write(2) fails, so be it. */
+ (void) write(vstream_fileno(smtp_client_stream),
+ "421 4.3.2 No system resources\r\n",
+ sizeof("421 4.3.2 No system resources\r\n") - 1);
PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream);
}
@@ -558,9 +562,10 @@ static void psc_service(VSTREAM *smtp_client_stream,
msg_warn("cannot convert client address/port to string: %s"
" -- dropping this connection",
MAI_STRERROR(aierr));
- psc_send_reply(vstream_fileno(smtp_client_stream),
- "unknown_address", "unknown_port",
- "421 4.3.2 No system resources\r\n");
+ /* Best effort - if this non-blocking write(2) fails, so be it. */
+ (void) write(vstream_fileno(smtp_client_stream),
+ "421 4.3.2 No system resources\r\n",
+ sizeof("421 4.3.2 No system resources\r\n") - 1);
PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream);
}
if (strncasecmp("::ffff:", smtp_client_addr.buf, 7) == 0)
diff --git a/postfix/src/postscreen/postscreen.h b/postfix/src/postscreen/postscreen.h
index c0885be85..f5b894e3d 100644
--- a/postfix/src/postscreen/postscreen.h
+++ b/postfix/src/postscreen/postscreen.h
@@ -44,6 +44,7 @@ typedef struct {
char *smtp_client_port; /* client port */
int client_concurrency; /* per-client */
const char *final_reply; /* cause for hanging up */
+ VSTRING *send_buf; /* pending output */
/* Test context. */
struct timeval start_time; /* start of current test */
const char *test_name; /* name of current test */
@@ -438,12 +439,8 @@ extern void psc_hangup_event(PSC_STATE *);
/*
* postscreen_send.c
*/
-#define PSC_SEND_REPLY(state, text) \
- psc_send_reply(vstream_fileno((state)->smtp_client_stream), \
- (state)->smtp_client_addr, \
- (state)->smtp_client_port, \
- (text))
-extern int psc_send_reply(int, const char *, const char *, const char *);
+#define PSC_SEND_REPLY psc_send_reply /* legacy macro */
+extern int psc_send_reply(PSC_STATE *, const char *);
extern void psc_send_socket(PSC_STATE *);
/*
diff --git a/postfix/src/postscreen/postscreen_send.c b/postfix/src/postscreen/postscreen_send.c
index 7b7edc350..d74e60049 100644
--- a/postfix/src/postscreen/postscreen_send.c
+++ b/postfix/src/postscreen/postscreen_send.c
@@ -6,13 +6,12 @@
/* SYNOPSIS
/* #include
/*
-/* int psc_send_reply(client_fd, client_addr, client_port, text)
-/* int client_fd;
-/* const char *client_addr;
-/* const char *client_port;
+/* int psc_send_reply(state, text)
+/* PSC_STATE *state;
/* const char *text;
/*
/* int PSC_SEND_REPLY(state, text)
+/* PSC_STATE *state;
/* const char *text;
/*
/* void psc_send_socket(state)
@@ -23,9 +22,8 @@
/* a warning (except EPIPE) with the client address and port,
/* and returns a non-zero result (all errors including EPIPE).
/*
-/* PSC_SEND_REPLY() is a convenience wrapper for psc_send_reply().
-/* It is an unsafe macro that evaluates its arguments multiple
-/* times.
+/* PSC_SEND_REPLY() is a legacy wrapper for psc_send_reply().
+/* It will eventually be replaced by its expansion.
/*
/* psc_send_socket() sends the specified socket to the real
/* Postfix SMTP server. The socket is delivered in the background.
@@ -57,6 +55,10 @@
#include
#include
+/* Global library. */
+
+#include
+
/* Application-specific. */
#include
@@ -67,28 +69,53 @@
*/
#define PSC_SEND_SOCK_CONNECT_TIMEOUT 1
#define PSC_SEND_SOCK_NOTIFY_TIMEOUT 100
-#define PSC_SEND_TEXT_TIMEOUT 1
/* psc_send_reply - send reply to remote SMTP client */
-int psc_send_reply(int smtp_client_fd, const char *smtp_client_addr,
- const char *smtp_client_port, const char *text)
+int psc_send_reply(PSC_STATE *state, const char *text)
{
+ int start;
int ret;
if (msg_verbose)
- msg_info("> [%s]:%s: %.*s", smtp_client_addr, smtp_client_port,
- (int) strlen(text) - 2, text);
+ msg_info("> [%s]:%s: %.*s", state->smtp_client_addr,
+ state->smtp_client_port, (int) strlen(text) - 2, text);
/*
- * XXX Need to make sure that the TCP send buffer is large enough for any
- * response, so that a nasty client can't cause this process to block.
+ * Append the new text to earlier text that could not be sent because the
+ * output was throttled.
*/
- ret = (write_buf(smtp_client_fd, text, strlen(text),
- PSC_SEND_TEXT_TIMEOUT) < 0);
- if (ret != 0 && errno != EPIPE)
- msg_warn("write [%s]:%s: %m", smtp_client_addr, smtp_client_port);
- return (ret);
+ start = VSTRING_LEN(state->send_buf);
+ vstring_strcat(state->send_buf, text);
+
+ /*
+ * XXX For soft_bounce support, it is not sufficient to fix replies here.
+ * We also need to fix the REJECT messages that are logged by the dummy
+ * SMTP engine. Those messages are set with the PSC_DROP_SESSION_STATE
+ * and PSC_ENFORCE_SESSION_STATE macros, and we should not mess up all
+ * the code that invokes those macros.
+ */
+#if 0
+ if (var_soft_bounce) {
+ if (text[0] == '5')
+ STR(state->send_buf)[start + 0] = '4';
+ if (text[4] == '5')
+ STR(state->send_buf)[start + 4] = '4';
+ }
+#endif
+
+ /*
+ * Do a best effort sending text, but don't block when the output is
+ * throttled by a hostile peer.
+ */
+ ret = write(vstream_fileno(state->smtp_client_stream),
+ STR(state->send_buf), LEN(state->send_buf));
+ if (ret > 0)
+ vstring_truncate(state->send_buf, ret - LEN(state->send_buf));
+ if (ret < 0 && errno != EAGAIN && errno != EPIPE)
+ msg_warn("write [%s]:%s: %m", state->smtp_client_addr,
+ state->smtp_client_port);
+ return (ret < 0 && errno != EAGAIN);
}
/* psc_send_socket_close_event - file descriptor has arrived or timeout */
diff --git a/postfix/src/postscreen/postscreen_smtpd.c b/postfix/src/postscreen/postscreen_smtpd.c
index 8b529bc77..07ebc8ca8 100644
--- a/postfix/src/postscreen/postscreen_smtpd.c
+++ b/postfix/src/postscreen/postscreen_smtpd.c
@@ -260,7 +260,8 @@ 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)
+static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
+ /*, const char *sasl_mechanism_list */)
{
const char *myname = "psc_smtpd_format_ehlo_reply";
int saved_len = 0;
@@ -1063,6 +1064,9 @@ void psc_smtpd_init(void)
case TLS_LEV_SECURE:
case TLS_LEV_VERIFY:
case TLS_LEV_FPRINT:
+ msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
+ VAR_PSC_TLS_LEVEL, var_psc_tls_level);
+ /* FALLTHROUGH */
case TLS_LEV_ENCRYPT:
var_psc_enforce_tls = var_psc_use_tls = 1;
break;
diff --git a/postfix/src/postscreen/postscreen_state.c b/postfix/src/postscreen/postscreen_state.c
index 42e2f0aed..97ffae132 100644
--- a/postfix/src/postscreen/postscreen_state.c
+++ b/postfix/src/postscreen/postscreen_state.c
@@ -153,6 +153,7 @@ PSC_STATE *psc_new_session_state(VSTREAM *stream,
state->smtp_server_fd = (-1);
state->smtp_client_addr = mystrdup(addr);
state->smtp_client_port = mystrdup(port);
+ state->send_buf = vstring_alloc(100);
state->test_name = "TEST NAME HERE";
state->dnsbl_reply = 0;
state->final_reply = "421 4.3.2 Service currently unavailable\r\n";
@@ -212,6 +213,8 @@ void psc_free_session_state(PSC_STATE *state)
close(state->smtp_server_fd);
psc_post_queue_length--;
}
+ if (state->send_buf != 0)
+ state->send_buf = vstring_free(state->send_buf);
myfree(state->smtp_client_addr);
myfree(state->smtp_client_port);
if (state->dnsbl_reply)
diff --git a/postfix/src/tlsproxy/tlsproxy.c b/postfix/src/tlsproxy/tlsproxy.c
index 4e0b350eb..a7351e6a3 100644
--- a/postfix/src/tlsproxy/tlsproxy.c
+++ b/postfix/src/tlsproxy/tlsproxy.c
@@ -293,6 +293,7 @@ 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.
@@ -625,9 +626,13 @@ static void tlsp_ciphertext_event(int event, char *context)
if (event == EVENT_READ || event == EVENT_WRITE) {
tlsp_strategy(state);
} else {
- msg_warn("read/write %s for %s",
- event == EVENT_TIME ? "timeout" : "error",
- state->remote_endpt);
+ if (event == EVENT_TIME && state->ssl_last_err == SSL_ERROR_NONE)
+ msg_warn("deadlock on plaintext stream for %s",
+ state->remote_endpt);
+ else
+ msg_warn("read/write %s for %s",
+ event == EVENT_TIME ? "timeout" : "error",
+ state->remote_endpt);
tlsp_state_free(state);
}
}
@@ -645,8 +650,6 @@ static void tlsp_start_tls(TLSP_STATE *state)
* going to sanitize this because doing so surely will break things in
* unexpected ways.
*/
- state->tls_use_tls = var_tlsp_use_tls | var_tlsp_enforce_tls;
- state->tls_enforce_tls = var_tlsp_enforce_tls;
/*
* Perform the before-handshake portion of the per-session initalization.
@@ -680,7 +683,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
log_level = var_tlsp_tls_loglevel,
timeout = 0, /* unused */
requirecert = (var_tlsp_tls_req_ccert
- && state->tls_enforce_tls),
+ && tlsp_tls_enforce_tls),
serverid = state->service,
namaddr = state->remote_endpt,
cipher_grade = cipher_grade,
@@ -894,7 +897,39 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
* The code in this routine is pasted literally from smtpd(8). I am not
* going to sanitize this because doing so surely will break things in
* unexpected ways.
- *
+ */
+ if (*var_tlsp_tls_level) {
+ switch (tls_level_lookup(var_tlsp_tls_level)) {
+ default:
+ msg_fatal("Invalid TLS level \"%s\"", var_tlsp_tls_level);
+ /* NOTREACHED */
+ break;
+ case TLS_LEV_SECURE:
+ case TLS_LEV_VERIFY:
+ case TLS_LEV_FPRINT:
+ msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
+ VAR_TLSP_TLS_LEVEL, var_tlsp_tls_level);
+ /* FALLTHROUGH */
+ case TLS_LEV_ENCRYPT:
+ var_tlsp_enforce_tls = var_tlsp_use_tls = 1;
+ break;
+ case TLS_LEV_MAY:
+ var_tlsp_enforce_tls = 0;
+ var_tlsp_use_tls = 1;
+ break;
+ case TLS_LEV_NONE:
+ var_tlsp_enforce_tls = var_tlsp_use_tls = 0;
+ break;
+ }
+ }
+ tlsp_tls_enforce_tls = var_tlsp_enforce_tls;
+ if (!(var_tlsp_use_tls || var_tlsp_enforce_tls)) {
+ msg_warn("TLS service is requested, but disabled with %s or %s",
+ VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
+ return;
+ }
+
+ /*
* Load TLS keys before dropping privileges.
*
* Can't use anonymous ciphers if we want client certificates. Must use
diff --git a/postfix/src/tlsproxy/tlsproxy.h b/postfix/src/tlsproxy/tlsproxy.h
index e18e38a75..0c4d129c7 100644
--- a/postfix/src/tlsproxy/tlsproxy.h
+++ b/postfix/src/tlsproxy/tlsproxy.h
@@ -33,8 +33,6 @@ typedef struct {
char *remote_endpt; /* printable remote endpoint */
TLS_SESS_STATE *tls_context; /* llibtls state */
int ssl_last_err; /* TLS I/O state */
- int tls_use_tls; /* legacy libtls API */
- int tls_enforce_tls; /* legacy libtls API */
} TLSP_STATE;
#define TLSP_FLAG_DO_HANDSHAKE (1<<0)
diff --git a/postfix/src/util/vstring.c b/postfix/src/util/vstring.c
index 783730d92..f7794ae74 100644
--- a/postfix/src/util/vstring.c
+++ b/postfix/src/util/vstring.c
@@ -173,7 +173,8 @@
/* arguments more than once. The result is NOT null-terminated.
/*
/* vstring_truncate() truncates the named string to the specified
-/* length. The operation has no effect when the string is shorter.
+/* length. If length is negative, the trailing portion is kept.
+/* The operation has no effect when the string is shorter.
/* The string is not null-terminated.
/*
/* VSTRING_RESET() is a macro that resets the write position of its
@@ -393,8 +394,13 @@ void vstring_ctl(VSTRING *vp,...)
VSTRING *vstring_truncate(VSTRING *vp, ssize_t len)
{
- if (len < 0)
- msg_panic("vstring_truncate: bad length %ld", (long) len);
+ ssize_t move;
+
+ if (len < 0) {
+ len = (-len);
+ if ((move = VSTRING_LEN(vp) - len) > 0)
+ memmove(vstring_str(vp), vstring_str(vp) + move, len);
+ }
if (len < VSTRING_LEN(vp))
VSTRING_AT_OFFSET(vp, len);
return (vp);