src/qmgr/qmgr_message.c, src/smtpd/smtpd.c,
src/smtpd/smtpd_check.c, src/trivial-rewrite/transport.c,
src/trivial-rewrite/trivial-rewrite.c.
+
+20130512
+
+ Feature: allow an SMTP client to skip postscreen(8) tests
+ before or after the 220 greeting, based on its DNSBL score.
+ Suggested by Rob McGee (/dev/rob0). Files: mantools/postlink,
+ proto/postconf.proto, global/mail_params.h,
+ postscreen/postscreen.c, postscreen/postscreen.h,
+ postscreen/postscreen_early.c, postscreen/postscreen_state.c,
+ postscreen/postscreen_tests.c.
If you upgrade from Postfix 2.9 or earlier, read RELEASE_NOTES-2.10
before proceeding.
+Major changes with snapshot 20130512
+====================================
+
+Allow an SMTP client to skip postscreen(8) tests based on its
+postscreen_dnsbl_sites score.
+
+Specify a negative "postscreen_dnsbl_whitelist_threshold" to enable
+this feature. When a client passes the threshold value without
+having failed other tests, all pending or disabled tests are flagged
+as completed.
+
Major changes with snapshot 20130405
====================================
<p> This feature is available in Postfix 2.8. </p>
+</DD>
+
+<DT><b><a name="postscreen_dnsbl_whitelist_threshold">postscreen_dnsbl_whitelist_threshold</a>
+(default: 0)</b></DT><DD>
+
+<p> Allow a remote SMTP client to skip "before" and "after 220
+greeting" protocol tests, based on its combined DNSBL score as
+defined with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter. </p>
+
+<p> Specify a negative value to enable this feature. When a client
+passes the <a href="postconf.5.html#postscreen_dnsbl_whitelist_threshold">postscreen_dnsbl_whitelist_threshold</a> without having
+failed other tests, all pending or disabled tests are flagged as
+completed with a time-to-live value equal to <a href="postconf.5.html#postscreen_dnsbl_ttl">postscreen_dnsbl_ttl</a>.
+When a test was already completed, its time-to-live value is updated
+if it was less than <a href="postconf.5.html#postscreen_dnsbl_ttl">postscreen_dnsbl_ttl</a>. </p>
+
+<p> This feature is available in Postfix 2.11. </p>
+
+
</DD>
<DT><b><a name="postscreen_enforce_tls">postscreen_enforce_tls</a>
The internal service that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> hands off
allowed connections to.
+ Available in Postfix version 2.11 and later:
+
+ <b><a href="postconf.5.html#postscreen_dnsbl_whitelist_threshold">postscreen_dnsbl_whitelist_threshold</a> (0)</b>
+ Allow a remote SMTP client to skip "before" and
+ "after 220 greeting" protocol tests, based on its
+ combined DNSBL score as defined with the
+ <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter.
+
<b>AFTER-GREETING TESTS</b>
- These tests are executed after the remote SMTP client
+ These tests are executed after the remote SMTP client
receives the "220 servername" greeting. If a client passes
- all tests during this phase, it will receive a 4XX
- response to RCPT TO commands until the client hangs up.
+ all tests during this phase, it will receive a 4XX
+ response to RCPT TO commands until the client hangs up.
After this, the client will be allowed to talk directly to
a Postfix SMTP server process.
<b><a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> (ignore)</b>
- The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
- SMTP client sends a bare newline character, that
+ The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
+ SMTP client sends a bare newline character, that
is, a newline not preceded by carriage return.
<b><a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> (no)</b>
- Enable "bare newline" SMTP protocol tests in the
+ Enable "bare newline" SMTP protocol tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b><a href="postconf.5.html#postscreen_disable_vrfy_command">postscreen_disable_vrfy_command</a> ($<a href="postconf.5.html#disable_vrfy_command">disable_vrfy_command</a>)</b>
- Disable the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+ Disable the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
daemon.
<b><a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> ($<a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>)</b>
siders in violation of the SMTP protocol.
<b><a href="postconf.5.html#postscreen_helo_required">postscreen_helo_required</a> ($<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a>)</b>
- Require that a remote SMTP client sends HELO or
+ Require that a remote SMTP client sends HELO or
EHLO before commencing a MAIL transaction.
<b><a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> (drop)</b>
- The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
- SMTP client sends non-SMTP commands as specified
+ The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
+ SMTP client sends non-SMTP commands as specified
with the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> parameter.
<b><a href="postconf.5.html#postscreen_non_smtp_command_enable">postscreen_non_smtp_command_enable</a> (no)</b>
- Enable "non-SMTP command" tests in the
+ Enable "non-SMTP command" tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b><a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a> (enforce)</b>
- The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
- SMTP client sends multiple commands instead of
- sending one command and waiting for the server to
+ The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when a remote
+ SMTP client sends multiple commands instead of
+ sending one command and waiting for the server to
respond.
<b><a href="postconf.5.html#postscreen_pipelining_enable">postscreen_pipelining_enable</a> (no)</b>
- Enable "pipelining" SMTP protocol tests in the
+ Enable "pipelining" SMTP protocol tests in the
<a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
<b>CACHE CONTROLS</b>
<b><a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> (12h)</b>
- The amount of time between <a href="postscreen.8.html"><b>postscreen</b>(8)</a> cache
+ The amount of time between <a href="postscreen.8.html"><b>postscreen</b>(8)</a> cache
cleanup runs.
<b><a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> (btree:$data_direc-</b>
<b>tory/postscreen_cache)</b>
- Persistent storage for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server
+ Persistent storage for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server
decisions.
<b><a href="postconf.5.html#postscreen_cache_retention_time">postscreen_cache_retention_time</a> (7d)</b>
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache an
- expired temporary whitelist entry before it is
+ expired temporary whitelist entry before it is
removed.
<b><a href="postconf.5.html#postscreen_bare_newline_ttl">postscreen_bare_newline_ttl</a> (30d)</b>
- The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
+ The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
result from a successful "bare newline" SMTP proto-
col test.
<b><a href="postconf.5.html#postscreen_dnsbl_ttl">postscreen_dnsbl_ttl</a> (1h)</b>
- The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
+ The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
result from a successful DNS blocklist test.
<b><a href="postconf.5.html#postscreen_greet_ttl">postscreen_greet_ttl</a> (1d)</b>
- The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
+ The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
result from a successful PREGREET test.
<b><a href="postconf.5.html#postscreen_non_smtp_command_ttl">postscreen_non_smtp_command_ttl</a> (30d)</b>
- The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
- result from a successful "non_smtp_command" SMTP
+ The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
+ result from a successful "non_smtp_command" SMTP
protocol test.
<b><a href="postconf.5.html#postscreen_pipelining_ttl">postscreen_pipelining_ttl</a> (30d)</b>
- The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
+ The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will use the
result from a successful "pipelining" SMTP protocol
test.
<b>RESOURCE CONTROLS</b>
<b><a href="postconf.5.html#line_length_limit">line_length_limit</a> (2048)</b>
- Upon input, long lines are chopped up into pieces
- of at most this length; upon delivery, long lines
+ Upon input, long lines are chopped up into pieces
+ of at most this length; upon delivery, long lines
are reconstructed.
<b><a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a></b>
<b>($<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b>
- How many simultaneous connections any remote SMTP
- client is allowed to have with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+ How many simultaneous connections any remote SMTP
+ client is allowed to have with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
daemon.
<b><a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> (20)</b>
- The limit on the total number of commands per SMTP
- session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol
+ The limit on the total number of commands per SMTP
+ session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol
engine.
<b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (${stress?10}${stress:300}s)</b>
- The time limit to read an entire command line with
+ The time limit to read an entire command line with
<a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol engine.
<b><a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
- The number of clients that can be waiting for ser-
+ The number of clients that can be waiting for ser-
vice from a real Postfix SMTP server process.
<b><a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
- The number of non-whitelisted clients that can be
- waiting for a decision whether they will receive
+ The number of non-whitelisted clients that can be
+ waiting for a decision whether they will receive
service from a real Postfix SMTP server process.
<b><a href="postconf.5.html#postscreen_watchdog_timeout">postscreen_watchdog_timeout</a> (10s)</b>
- How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
- respond to a remote SMTP client command or to per-
+ How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
+ respond to a remote SMTP client command or to per-
form a cache operation before it is terminated by a
built-in watchdog timer.
<b>STARTTLS CONTROLS</b>
<b><a href="postconf.5.html#postscreen_tls_security_level">postscreen_tls_security_level</a> ($<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a>)</b>
- The SMTP TLS security level for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
- server; when a non-empty value is specified, this
+ The SMTP TLS security level for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+ server; when a non-empty value is specified, this
overrides the obsolete parameters
<a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> and <a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a>.
<b><a href="postconf.5.html#tlsproxy_service_name">tlsproxy_service_name</a> (tlsproxy)</b>
- The name of the <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> service entry in mas-
+ The name of the <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> service entry in mas-
ter.cf.
<b>OBSOLETE STARTTLS SUPPORT CONTROLS</b>
- These parameters are supported for compatibility with
+ These parameters are supported for compatibility with
<a href="smtpd.8.html"><b>smtpd</b>(8)</a> legacy parameters.
<b><a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> ($<a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a>)</b>
- Opportunistic TLS: announce STARTTLS support to
+ Opportunistic TLS: announce STARTTLS support to
remote SMTP clients, but do not require that
clients use TLS encryption.
<b><a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a> ($<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>)</b>
- Mandatory TLS: announce STARTTLS support to remote
- SMTP clients, and require that clients use TLS
+ Mandatory TLS: announce STARTTLS support to remote
+ SMTP clients, and require that clients use TLS
encryption.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal
+ The maximal number of digits after the decimal
point when logging sub-second delay values.
<b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix
- daemon process waits for an incoming connection
+ The maximum amount of time that an idle Postfix
+ daemon process waits for an incoming connection
before terminating voluntarily.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the
- process name in syslog records, so that "smtpd"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<b>SEE ALSO</b>
<a href="POSTSCREEN_README.html">POSTSCREEN_README</a>, Postfix Postscreen Howto
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>HISTORY</b>
This service was introduced with Postfix version 2.8.
- Many ideas in <a href="postscreen.8.html"><b>postscreen</b>(8)</a> were explored in earlier work
- by Michael Tokarev, in OpenBSD spamd, and in MailChannels
+ Many ideas in <a href="postscreen.8.html"><b>postscreen</b>(8)</a> were explored in earlier work
+ by Michael Tokarev, in OpenBSD spamd, and in MailChannels
Traffic Control.
<b>AUTHOR(S)</b>
(seconds), m (minutes), h (hours), d (days), w (weeks).
.PP
This feature is available in Postfix 2.8.
+.SH postscreen_dnsbl_whitelist_threshold (default: 0)
+Allow a remote SMTP client to skip "before" and "after 220
+greeting" protocol tests, based on its combined DNSBL score as
+defined with the postscreen_dnsbl_sites parameter.
+.PP
+Specify a negative value to enable this feature. When a client
+passes the postscreen_dnsbl_whitelist_threshold without having
+failed other tests, all pending or disabled tests are flagged as
+completed with a time-to-live value equal to postscreen_dnsbl_ttl.
+When a test was already completed, its time-to-live value is updated
+if it was less than postscreen_dnsbl_ttl.
+.PP
+This feature is available in Postfix 2.11.
.SH postscreen_enforce_tls (default: $smtpd_enforce_tls)
Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
require that clients use TLS encryption. See smtpd_postscreen_enforce_tls
.IP "\fBsmtpd_service_name (smtpd)\fR"
The internal service that \fBpostscreen\fR(8) hands off allowed
connections to.
+.PP
+Available in Postfix version 2.11 and later:
+.IP "\fBpostscreen_dnsbl_whitelist_threshold (0)\fR"
+Allow a remote SMTP client to skip "before" and "after 220
+greeting" protocol tests, based on its combined DNSBL score as
+defined with the postscreen_dnsbl_sites parameter.
.SH "AFTER-GREETING TESTS"
.na
.nf
s;\bpostscreen_dnsbl_reply_map\b;<a href="postconf.5.html#postscreen_dnsbl_reply_map">$&</a>;g;
s;\bpostscreen_dnsbl_sites\b;<a href="postconf.5.html#postscreen_dnsbl_sites">$&</a>;g;
s;\bpostscreen_dnsbl_thresh[-</bB>]*\n* *[<bB>]*old\b;<a href="postconf.5.html#postscreen_dnsbl_threshold">$&</a>;g;
+ s;\bpostscreen_dnsbl_whitelist_thresh[-</bB>]*\n* *[<bB>]*old\b;<a href="postconf.5.html#postscreen_dnsbl_whitelist_threshold">$&</a>;g;
s;\bpostscreen_dnsbl_action\b;<a href="postconf.5.html#postscreen_dnsbl_action">$&</a>;g;
s;\bpostscreen_dnsbl_ttl\b;<a href="postconf.5.html#postscreen_dnsbl_ttl">$&</a>;g;
s;\bpostscreen_for[-</bB>]*\n*[ <bB>]*bidden_commands\b;<a href="postconf.5.html#postscreen_forbidden_commands">$&</a>;g;
<p> This feature is available in Postfix 2.8. </p>
+%PARAM postscreen_dnsbl_whitelist_threshold 0
+
+<p> Allow a remote SMTP client to skip "before" and "after 220
+greeting" protocol tests, based on its combined DNSBL score as
+defined with the postscreen_dnsbl_sites parameter. </p>
+
+<p> Specify a negative value to enable this feature. When a client
+passes the postscreen_dnsbl_whitelist_threshold without having
+failed other tests, all pending or disabled tests are flagged as
+completed with a time-to-live value equal to postscreen_dnsbl_ttl.
+When a test was already completed, its time-to-live value is updated
+if it was less than postscreen_dnsbl_ttl. </p>
+
+<p> This feature is available in Postfix 2.11. </p>
+
%PARAM postscreen_command_count_limit 20
<p> The limit on the total number of commands per SMTP session for
#define DEF_PSC_DNSBL_THRESH 1
extern int var_psc_dnsbl_thresh;
+#define VAR_PSC_DNSBL_WTHRESH "postscreen_dnsbl_whitelist_threshold"
+#define DEF_PSC_DNSBL_WTHRESH 0
+extern int var_psc_dnsbl_wthresh;
+
#define VAR_PSC_DNSBL_ENABLE "postscreen_dnsbl_enable"
#define DEF_PSC_DNSBL_ENABLE 0
extern char *var_psc_dnsbl_enable;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20130405"
+#define MAIL_RELEASE_DATE "20130512"
#define MAIL_VERSION_NUMBER "2.11"
#ifdef SNAPSHOT
postscreen_tests.o: ../../include/msg.h
postscreen_tests.o: ../../include/myaddrinfo.h
postscreen_tests.o: ../../include/myflock.h
+postscreen_tests.o: ../../include/name_code.h
postscreen_tests.o: ../../include/server_acl.h
postscreen_tests.o: ../../include/string_list.h
postscreen_tests.o: ../../include/sys_defs.h
/* .IP "\fBsmtpd_service_name (smtpd)\fR"
/* The internal service that \fBpostscreen\fR(8) hands off allowed
/* connections to.
+/* .PP
+/* Available in Postfix version 2.11 and later:
+/* .IP "\fBpostscreen_dnsbl_whitelist_threshold (0)\fR"
+/* Allow a remote SMTP client to skip "before" and "after 220
+/* greeting" protocol tests, based on its combined DNSBL score as
+/* defined with the postscreen_dnsbl_sites parameter.
/* AFTER-GREETING TESTS
/* .ad
/* .fi
char *var_psc_dnsbl_sites;
char *var_psc_dnsbl_reply;
int var_psc_dnsbl_thresh;
+int var_psc_dnsbl_wthresh;
char *var_psc_dnsbl_action;
int var_psc_dnsbl_ttl;
static const CONFIG_INT_TABLE int_table[] = {
VAR_PROC_LIMIT, DEF_PROC_LIMIT, &var_proc_limit, 1, 0,
VAR_PSC_DNSBL_THRESH, DEF_PSC_DNSBL_THRESH, &var_psc_dnsbl_thresh, 0, 0,
+ VAR_PSC_DNSBL_WTHRESH, DEF_PSC_DNSBL_WTHRESH, &var_psc_dnsbl_wthresh, 0, 0,
VAR_PSC_CMD_COUNT, DEF_PSC_CMD_COUNT, &var_psc_cmd_count, 1, 0,
VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
0,
*/
#define PSC_READ_BUF_SIZE 1024
+ /*
+ * Numeric indices and symbolic names for tests whose time stamps and status
+ * flags can be accessed by numeric index.
+ */
+#define PSC_TINDX_PREGR 0 /* pregreet */
+#define PSC_TINDX_DNSBL 1 /* dnsbl */
+#define PSC_TINDX_PIPEL 2 /* pipelining */
+#define PSC_TINDX_NSMTP 3 /* non-smtp command */
+#define PSC_TINDX_BARLF 4 /* bare newline */
+#define PSC_TINDX_COUNT 5 /* number of tests */
+
+#define PSC_TNAME_PREGR "pregreet"
+#define PSC_TNAME_DNSBL "dnsbl"
+#define PSC_TNAME_PIPEL "pipelining"
+#define PSC_TNAME_NSMTP "non-smtp command"
+#define PSC_TNAME_BARLF "bare newline"
+
+#define PSC_TINDX_BYTNAME(tname) (PSC_TINDX_ ## tname)
+
/*
* Per-session state.
*/
/* Test context. */
struct timeval start_time; /* start of current test */
const char *test_name; /* name of current test */
- /* Before-handshake tests. */
- time_t pregr_stamp; /* pregreet expiration time */
- time_t dnsbl_stamp; /* dnsbl expiration time */
+ time_t expire_time[PSC_TINDX_COUNT]; /* per-test expiration */
VSTRING *dnsbl_reply; /* dnsbl reject text */
+ int dnsbl_score; /* saved DNSBL score */
+ const char *dnsbl_name; /* DNSBL name with largest weight */
int dnsbl_index; /* dnsbl request index */
- time_t penal_stamp; /* penalty expiration time */
- /* Built-in SMTP protocol engine. */
- time_t pipel_stamp; /* pipelining expiration time */
- time_t nsmtp_stamp; /* non-smtp command expiration time */
- time_t barlf_stamp; /* bare newline expiration time */
const char *rcpt_reply; /* how to reject recipients */
int command_count; /* error + junk command count */
const char *protocol; /* SMTP or ESMTP */
const char *where; /* SMTP protocol state */
} PSC_STATE;
+ /*
+ * Emulate legacy ad-hoc variables on top of indexable time stamps. This
+ * avoids massive scar tissue during initial feature development.
+ */
+#define pregr_stamp expire_time[PSC_TINDX_PREGR]
+#define dnsbl_stamp expire_time[PSC_TINDX_DNSBL]
+#define pipel_stamp expire_time[PSC_TINDX_PIPEL]
+#define nsmtp_stamp expire_time[PSC_TINDX_NSMTP]
+#define barlf_stamp expire_time[PSC_TINDX_BARLF]
+
+ /*
+ * Special expiration time values.
+ */
#define PSC_TIME_STAMP_NEW (0) /* test was never passed */
#define PSC_TIME_STAMP_DISABLED (1) /* never passed but disabled */
#define PSC_TIME_STAMP_INVALID (-1) /* must not be cached */
+ /*
+ * Status flags.
+ */
#define PSC_STATE_FLAG_NOFORWARD (1<<0) /* don't forward this session */
#define PSC_STATE_FLAG_USING_TLS (1<<1) /* using the TLS proxy */
#define PSC_STATE_FLAG_UNUSED2 (1<<2) /* use me! */
#define PSC_STATE_FLAG_HANGUP (1<<5) /* NOT a test failure */
#define PSC_STATE_FLAG_SMTPD_X21 (1<<6) /* hang up after command */
#define PSC_STATE_FLAG_WLIST_FAIL (1<<7) /* do not whitelist */
+#define PSC_STATE_FLAG_TEST_BASE (8) /* start of indexable flags */
/*
+ * Tests whose flags and expiration time can be accessed by numerical index.
+ *
* Important: every MUMBLE_TODO flag must have a MUMBLE_PASS flag, such that
* MUMBLE_PASS == PSC_STATE_FLAGS_TODO_TO_PASS(MUMBLE_TODO).
*
* the result was ignored. MUMBLE_FAIL, on the other hand, is always final.
* We use MUMBLE_SKIP to indicate that a decision was either "fail" or
* forced "pass".
+ *
+ * The difference between DONE and SKIP is in the beholder's eye. These flags
+ * share the same bit.
*/
#define PSC_STATE_FLAGS_TODO_TO_PASS(todo_flags) ((todo_flags) >> 1)
#define PSC_STATE_FLAGS_TODO_TO_DONE(todo_flags) ((todo_flags) << 1)
-#define PSC_STATE_FLAG_PENAL_UPDATE (1<<6) /* save new penalty */
-#define PSC_STATE_FLAG_PENAL_FAIL (1<<7) /* penalty is active */
-
-#define PSC_STATE_FLAG_PREGR_FAIL (1<<8) /* failed pregreet test */
-#define PSC_STATE_FLAG_PREGR_PASS (1<<9) /* passed pregreet test */
-#define PSC_STATE_FLAG_PREGR_TODO (1<<10) /* pregreet test expired */
-#define PSC_STATE_FLAG_PREGR_DONE (1<<11) /* decision is final */
-
-#define PSC_STATE_FLAG_DNSBL_FAIL (1<<12) /* failed DNSBL test */
-#define PSC_STATE_FLAG_DNSBL_PASS (1<<13) /* passed DNSBL test */
-#define PSC_STATE_FLAG_DNSBL_TODO (1<<14) /* DNSBL test expired */
-#define PSC_STATE_FLAG_DNSBL_DONE (1<<15) /* decision is final */
+#define PSC_STATE_FLAG_SHIFT_FAIL (0) /* failed test */
+#define PSC_STATE_FLAG_SHIFT_PASS (1) /* passed test */
+#define PSC_STATE_FLAG_SHIFT_TODO (2) /* expired test */
+#define PSC_STATE_FLAG_SHIFT_DONE (3) /* decision is final */
+#define PSC_STATE_FLAG_SHIFT_SKIP (3) /* action is already logged */
+#define PSC_STATE_FLAG_SHIFT_STRIDE (4) /* nr of flags per test */
- /* Room here for one more after-handshake test. */
+#define PSC_STATE_FLAG_SHIFT_BYFNAME(fname) (PSC_STATE_FLAG_SHIFT_ ## fname)
-#define PSC_STATE_FLAG_PIPEL_FAIL (1<<20) /* failed pipelining test */
-#define PSC_STATE_FLAG_PIPEL_PASS (1<<21) /* passed pipelining test */
-#define PSC_STATE_FLAG_PIPEL_TODO (1<<22) /* pipelining test expired */
-#define PSC_STATE_FLAG_PIPEL_SKIP (1<<23) /* action is already logged */
-
-#define PSC_STATE_FLAG_NSMTP_FAIL (1<<24) /* failed non-SMTP test */
-#define PSC_STATE_FLAG_NSMTP_PASS (1<<25) /* passed non-SMTP test */
-#define PSC_STATE_FLAG_NSMTP_TODO (1<<26) /* non-SMTP test expired */
-#define PSC_STATE_FLAG_NSMTP_SKIP (1<<27) /* action is already logged */
+ /*
+ * Indexable per-test flags. These are used for DNS whitelisting multiple
+ * tests, without needing per-test ad-hoc code.
+ */
+#define PSC_STATE_FLAG_BYTINDX_FNAME(tindx, fname) \
+ (1U << (PSC_STATE_FLAG_TEST_BASE \
+ + PSC_STATE_FLAG_SHIFT_STRIDE * (tindx) \
+ + PSC_STATE_FLAG_SHIFT_BYFNAME(fname)))
+
+#define PSC_STATE_FLAG_BYTINDX_FAIL(tindx) \
+ PSC_STATE_FLAG_BYTINDX_FNAME((tindx), FAIL)
+#define PSC_STATE_FLAG_BYTINDX_PASS(tindx) \
+ PSC_STATE_FLAG_BYTINDX_FNAME((tindx), PASS)
+#define PSC_STATE_FLAG_BYTINDX_TODO(tindx) \
+ PSC_STATE_FLAG_BYTINDX_FNAME((tindx), TODO)
+#define PSC_STATE_FLAG_BYTINDX_DONE(tindx) \
+ PSC_STATE_FLAG_BYTINDX_FNAME((tindx), DONE)
+#define PSC_STATE_FLAG_BYTINDX_SKIP(tindx) \
+ PSC_STATE_FLAG_BYTINDX_FNAME((tindx), SKIP)
-#define PSC_STATE_FLAG_BARLF_FAIL (1<<28) /* failed bare newline test */
-#define PSC_STATE_FLAG_BARLF_PASS (1<<29) /* passed bare newline test */
-#define PSC_STATE_FLAG_BARLF_TODO (1<<30) /* bare newline test expired */
-#define PSC_STATE_FLAG_BARLF_SKIP (1<<31) /* action is already logged */
+ /*
+ * Flags with distinct names. These are used in the per-test ad-hoc code.
+ */
+#define PSC_STATE_FLAG_BYTNAME_FNAME(tname, fname) \
+ (1U << (PSC_STATE_FLAG_TEST_BASE \
+ + PSC_STATE_FLAG_SHIFT_STRIDE * PSC_TINDX_BYTNAME(tname) \
+ + PSC_STATE_FLAG_SHIFT_BYFNAME(fname)))
+
+#define PSC_STATE_FLAG_PREGR_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, FAIL)
+#define PSC_STATE_FLAG_PREGR_PASS PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, PASS)
+#define PSC_STATE_FLAG_PREGR_TODO PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, TODO)
+#define PSC_STATE_FLAG_PREGR_DONE PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, DONE)
+
+#define PSC_STATE_FLAG_DNSBL_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, FAIL)
+#define PSC_STATE_FLAG_DNSBL_PASS PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, PASS)
+#define PSC_STATE_FLAG_DNSBL_TODO PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, TODO)
+#define PSC_STATE_FLAG_DNSBL_DONE PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, DONE)
+
+#define PSC_STATE_FLAG_PIPEL_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, FAIL)
+#define PSC_STATE_FLAG_PIPEL_PASS PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, PASS)
+#define PSC_STATE_FLAG_PIPEL_TODO PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, TODO)
+#define PSC_STATE_FLAG_PIPEL_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, SKIP)
+
+#define PSC_STATE_FLAG_NSMTP_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, FAIL)
+#define PSC_STATE_FLAG_NSMTP_PASS PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, PASS)
+#define PSC_STATE_FLAG_NSMTP_TODO PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, TODO)
+#define PSC_STATE_FLAG_NSMTP_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, SKIP)
+
+#define PSC_STATE_FLAG_BARLF_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, FAIL)
+#define PSC_STATE_FLAG_BARLF_PASS PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, PASS)
+#define PSC_STATE_FLAG_BARLF_TODO PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, TODO)
+#define PSC_STATE_FLAG_BARLF_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, SKIP)
/*
* Aggregates for individual tests.
#define PSC_STATE_MASK_BARLF_TODO_FAIL \
(PSC_STATE_FLAG_BARLF_TODO | PSC_STATE_FLAG_BARLF_FAIL)
+#define PSC_STATE_MASK_PREGR_TODO_DONE \
+ (PSC_STATE_FLAG_PREGR_TODO | PSC_STATE_FLAG_PREGR_DONE)
#define PSC_STATE_MASK_PIPEL_TODO_SKIP \
(PSC_STATE_FLAG_PIPEL_TODO | PSC_STATE_FLAG_PIPEL_SKIP)
#define PSC_STATE_MASK_NSMTP_TODO_SKIP \
* Super-aggregates for all tests combined.
*/
#define PSC_STATE_MASK_ANY_FAIL \
- (PSC_STATE_FLAG_BLIST_FAIL | PSC_STATE_FLAG_PENAL_FAIL | \
+ (PSC_STATE_FLAG_BLIST_FAIL | \
PSC_STATE_MASK_EARLY_FAIL | PSC_STATE_MASK_SMTPD_FAIL | \
PSC_STATE_FLAG_WLIST_FAIL)
(PSC_STATE_MASK_ANY_TODO | PSC_STATE_MASK_ANY_FAIL)
#define PSC_STATE_MASK_ANY_UPDATE \
- (PSC_STATE_MASK_ANY_PASS | PSC_STATE_FLAG_PENAL_UPDATE)
+ (PSC_STATE_MASK_ANY_PASS)
/*
* Meta-commands for state->where that reflect the initial command processor
* postscreen_tests.c
*/
#define PSC_INIT_TESTS(dst) do { \
+ time_t *_it_stamp_p; \
(dst)->flags = 0; \
- (dst)->pregr_stamp = PSC_TIME_STAMP_INVALID; \
- (dst)->dnsbl_stamp = PSC_TIME_STAMP_INVALID; \
- (dst)->pipel_stamp = PSC_TIME_STAMP_INVALID; \
- (dst)->barlf_stamp = PSC_TIME_STAMP_INVALID; \
- (dst)->penal_stamp = PSC_TIME_STAMP_INVALID; \
+ for (_it_stamp_p = (dst)->expire_time; \
+ _it_stamp_p < (dst)->expire_time + PSC_TINDX_COUNT; \
+ _it_stamp_p++) \
+ *_it_stamp_p = PSC_TIME_STAMP_INVALID; \
} while (0)
#define PSC_BEGIN_TESTS(state, name) do { \
(state)->test_name = (name); \
extern char *psc_print_tests(VSTRING *, PSC_STATE *);
extern char *psc_print_grey_key(VSTRING *, const char *, const char *,
const char *, const char *);
+extern const char *psc_test_name(int);
#define PSC_MIN(x, y) ((x) < (y) ? (x) : (y))
#define PSC_MAX(x, y) ((x) > (y) ? (x) : (y))
#include <sys_defs.h>
#include <sys/socket.h>
+#include <limits.h>
/* Utility library. */
PSC_STATE *state = (PSC_STATE *) context;
char read_buf[PSC_READ_BUF_SIZE];
int read_count;
- int dnsbl_score;
DELTA_TIME elapsed;
- const char *dnsbl_name;
if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
* Check if the SMTP client spoke before its turn.
*/
if ((state->flags & PSC_STATE_MASK_PREGR_TODO_FAIL)
- == PSC_STATE_FLAG_PREGR_TODO) {
+ == (state->flags & PSC_STATE_MASK_PREGR_TODO_DONE)) {
state->pregr_stamp = event_time() + var_psc_pregr_ttl;
PSC_PASS_SESSION_STATE(state, "pregreet test",
PSC_STATE_FLAG_PREGR_PASS);
*/
#define PSC_DNSBL_FORMAT \
"%s 5.7.1 Service unavailable; client [%s] blocked using %s\r\n"
+#define NO_DNSBL_SCORE INT_MAX
if (state->flags & PSC_STATE_FLAG_DNSBL_TODO) {
- dnsbl_score =
- psc_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
- state->dnsbl_index);
- if (dnsbl_score < var_psc_dnsbl_thresh) {
+ if (state->dnsbl_score == NO_DNSBL_SCORE)
+ state->dnsbl_score =
+ psc_dnsbl_retrieve(state->smtp_client_addr,
+ &state->dnsbl_name,
+ state->dnsbl_index);
+ if (state->dnsbl_score < var_psc_dnsbl_thresh) {
state->dnsbl_stamp = event_time() + var_psc_dnsbl_ttl;
PSC_PASS_SESSION_STATE(state, "dnsbl test",
PSC_STATE_FLAG_DNSBL_PASS);
} else {
msg_info("DNSBL rank %d for [%s]:%s",
- dnsbl_score, PSC_CLIENT_ADDR_PORT(state));
+ state->dnsbl_score, PSC_CLIENT_ADDR_PORT(state));
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNSBL_FAIL);
switch (psc_dnsbl_action) {
case PSC_ACT_DROP:
state->dnsbl_reply = vstring_sprintf(vstring_alloc(100),
PSC_DNSBL_FORMAT, "521",
- state->smtp_client_addr, dnsbl_name);
+ state->smtp_client_addr,
+ state->dnsbl_name);
PSC_DROP_SESSION_STATE(state, STR(state->dnsbl_reply));
return;
case PSC_ACT_ENFORCE:
state->dnsbl_reply = vstring_sprintf(vstring_alloc(100),
PSC_DNSBL_FORMAT, "550",
- state->smtp_client_addr, dnsbl_name);
+ state->smtp_client_addr,
+ state->dnsbl_name);
PSC_ENFORCE_SESSION_STATE(state, STR(state->dnsbl_reply));
break;
case PSC_ACT_IGNORE:
* Pass the connection to a real SMTP server, or enter the dummy
* engine for deep tests.
*/
- if (state->flags & (PSC_STATE_FLAG_NOFORWARD | PSC_STATE_MASK_SMTPD_TODO))
+ if ((state->flags & PSC_STATE_FLAG_NOFORWARD) != 0
+ || ((state->flags & PSC_STATE_MASK_SMTPD_PASS)
+ != PSC_STATE_FLAGS_TODO_TO_PASS(state->flags & PSC_STATE_MASK_SMTPD_TODO)))
psc_smtpd_tests(state);
else
psc_conclude(state);
read_buf, sizeof(read_buf) - 1, MSG_PEEK)) <= 0) {
/* Avoid memory leak. */
if (state->flags & PSC_STATE_FLAG_DNSBL_TODO)
- (void) psc_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
+ (void) psc_dnsbl_retrieve(state->smtp_client_addr,
+ &state->dnsbl_name,
state->dnsbl_index);
/* XXX Wait for DNS replies to come in. */
psc_hangup_event(state);
case PSC_ACT_DROP:
/* Avoid memory leak. */
if (state->flags & PSC_STATE_FLAG_DNSBL_TODO)
- (void) psc_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
+ (void) psc_dnsbl_retrieve(state->smtp_client_addr,
+ &state->dnsbl_name,
state->dnsbl_index);
PSC_DROP_SESSION_STATE(state, "521 5.5.1 Protocol error\r\n");
return;
{
const char *myname = "psc_early_dnsbl_event";
PSC_STATE *state = (PSC_STATE *) context;
+ time_t now;
+ int tindx;
if (msg_verbose)
msg_info("%s: notify [%s]:%s", myname, PSC_CLIENT_ADDR_PORT(state));
+ /*
+ * Collect the DNSBL score. If no tests failed (we can't undo those), and
+ * if the whitelist threshold is met, flag all other pending or disabled
+ * tests as successfully completed, and set their expiration times equal
+ * to the DNSBL expiration time, except for tests that would expire
+ * later.
+ */
+ state->dnsbl_score =
+ psc_dnsbl_retrieve(state->smtp_client_addr, &state->dnsbl_name,
+ state->dnsbl_index);
+ if (var_psc_dnsbl_wthresh < 0
+ && (state->flags & PSC_STATE_MASK_ANY_FAIL) == 0
+ && state->dnsbl_score <= var_psc_dnsbl_wthresh) {
+ now = event_time();
+ for (tindx = 0; tindx < PSC_TINDX_COUNT; tindx++) {
+ if (tindx == PSC_TINDX_DNSBL)
+ continue;
+ if ((state->flags & PSC_STATE_FLAG_BYTINDX_TODO(tindx))
+ && !(state->flags & PSC_STATE_FLAG_BYTINDX_PASS(tindx))) {
+ if (msg_verbose)
+ msg_info("skip %s test for [%s]:%s",
+ psc_test_name(tindx), PSC_CLIENT_ADDR_PORT(state));
+ /* Wrong for deep protocol tests, but we disable those. */
+ state->flags |= PSC_STATE_FLAG_BYTINDX_DONE(tindx);
+ /* This also disables pending deep protocol tests. */
+ state->flags |= PSC_STATE_FLAG_BYTINDX_PASS(tindx);
+ }
+ /* Update expiration even if the test was completed or disabled. */
+ if (state->expire_time[tindx] < now + var_psc_dnsbl_ttl)
+ state->expire_time[tindx] = now + var_psc_dnsbl_ttl;
+ }
+ }
+
/*
* Terminate the greet delay if we're just waiting for DNSBL lookup to
* complete. Don't call psc_early_event directly, that would result in a
(char *) state);
else
state->dnsbl_index = -1;
+ state->dnsbl_score = NO_DNSBL_SCORE;
/*
* Wait for the client to respond or for DNS lookup to complete.
/* unused */
"WLIST_FAIL", PSC_STATE_FLAG_WLIST_FAIL,
- "PENAL_UPDATE", PSC_STATE_FLAG_PENAL_UPDATE,
- "PENAL_FAIL", PSC_STATE_FLAG_PENAL_FAIL,
-
"PREGR_FAIL", PSC_STATE_FLAG_PREGR_FAIL,
"PREGR_PASS", PSC_STATE_FLAG_PREGR_PASS,
"PREGR_TODO", PSC_STATE_FLAG_PREGR_TODO,
/* const char *helo;
/* const char *sender;
/* const char *rcpt;
+/*
+/* const char *psc_test_name(tindx)
+/* int tindx;
/* DESCRIPTION
/* The functions in this module overwrite the per-test expiration
/* time stamps and all flags bits. Some functions are implemented
/* This may modify the time stamps for disabled tests.
/*
/* psc_print_grey_key() prints a greylist lookup key.
+/*
+/* psc_test_name() returns the name for the specified text
+/* index.
/* LICENSE
/* .ad
/* .fi
#include <sys_defs.h>
#include <stdio.h> /* sscanf */
+#include <stdlib.h> /* strtoul */
/* Utility library. */
#include <msg.h>
+#include <name_code.h>
/* Global library. */
state->pipel_stamp = PSC_TIME_STAMP_NEW;
state->nsmtp_stamp = PSC_TIME_STAMP_NEW;
state->barlf_stamp = PSC_TIME_STAMP_NEW;
- state->penal_stamp = PSC_TIME_STAMP_NEW;
/*
* Don't flag disabled tests as "todo", because there would be no way to
const char *stamp_str,
time_t time_value)
{
- unsigned long pregr_stamp;
- unsigned long dnsbl_stamp;
- unsigned long pipel_stamp;
- unsigned long nsmtp_stamp;
- unsigned long barlf_stamp;
- unsigned long penal_stamp;
-
-#ifdef NONPROD
- time_t penalty_left;
-
-#endif
+ const char *start = stamp_str;
+ char *cp;
+ time_t *time_stamps = state->expire_time;
+ time_t *sp;
/*
* We don't know what tests have expired or have never passed.
* enabled tests, but the remote SMTP client has not yet passed all those
* tests.
*/
- switch (sscanf(stamp_str, "%lu;%lu;%lu;%lu;%lu;%lu",
- &pregr_stamp, &dnsbl_stamp, &pipel_stamp, &nsmtp_stamp,
- &barlf_stamp, &penal_stamp)) {
- case 0:
- pregr_stamp = PSC_TIME_STAMP_DISABLED;
- case 1:
- dnsbl_stamp = PSC_TIME_STAMP_DISABLED;
- case 2:
- pipel_stamp = PSC_TIME_STAMP_DISABLED;
- case 3:
- nsmtp_stamp = PSC_TIME_STAMP_DISABLED;
- case 4:
- barlf_stamp = PSC_TIME_STAMP_DISABLED;
- case 5:
- penal_stamp = PSC_TIME_STAMP_DISABLED;
- default:
- break;
+ for (sp = time_stamps; sp < time_stamps + PSC_TINDX_COUNT; sp++) {
+ *sp = strtoul(start, &cp, 10);
+ if (*start == 0 || (*cp != '\0' && *cp != ';') || errno == ERANGE)
+ *sp = PSC_TIME_STAMP_DISABLED;
+ if (*sp == PSC_TIME_STAMP_NEW)
+ state->flags |= PSC_STATE_FLAG_NEW;
+ if (msg_verbose)
+ msg_info("%s -> %lu", start, (unsigned long) *sp);
+ if (*cp == ';')
+ start = cp + 1;
+ else
+ start = cp;
}
- state->pregr_stamp = pregr_stamp;
- state->dnsbl_stamp = dnsbl_stamp;
- state->pipel_stamp = pipel_stamp;
- state->nsmtp_stamp = nsmtp_stamp;
- state->barlf_stamp = barlf_stamp;
- state->penal_stamp = penal_stamp;
-
- if (pregr_stamp == PSC_TIME_STAMP_NEW
- || dnsbl_stamp == PSC_TIME_STAMP_NEW
- || pipel_stamp == PSC_TIME_STAMP_NEW
- || nsmtp_stamp == PSC_TIME_STAMP_NEW
- || barlf_stamp == PSC_TIME_STAMP_NEW)
- state->flags |= PSC_STATE_FLAG_NEW;
/*
* Don't flag disabled tests as "todo", because there would be no way to
state->flags |= PSC_STATE_FLAG_DNSBL_TODO;
}
#endif
-
- /*
- * Apply unexpired penalty for past behavior.
- *
- * XXX Before we can drop connections, change this function to return
- * success/fail, to inform the caller that the state object no longer
- * exists.
- */
-#ifdef NONPROD
- if ((penalty_left = state->penal_stamp - event_time()) > 0) {
- msg_info("PENALTY %ld for %s",
- (long) penalty_left, state->smtp_client_addr);
- PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_PENAL_FAIL);
-#if 0
- switch (psc_penal_action) {
- case PSC_ACT_DROP:
- PSC_DROP_SESSION_STATE(state,
- "421 4.3.2 Service currently unavailable\r\n");
- break;
- case PSC_ACT_ENFORCE:
-#endif
- PSC_ENFORCE_SESSION_STATE(state,
- "450 4.3.2 Service currently unavailable\r\n");
-#if 0
- break;
- case PSC_ACT_IGNORE:
- PSC_UNFAIL_SESSION_STATE(state, PSC_STATE_FLAG_PENAL_FAIL);
- break;
- default:
- msg_panic("%s: unknown penalty action value %d",
- myname, psc_penal_action);
- }
-#endif
- }
-#endif /* NONPROD */
}
/* psc_print_tests - print postscreen cache record */
if ((state->flags & PSC_STATE_MASK_ANY_UPDATE) == 0)
msg_panic("%s: attempt to save a no-update record", myname);
- /*
- * Don't record a client as "passed" while subject to penalty. Be sure to
- * produce correct PASS OLD/NEW logging.
- *
- * XXX This needs to be refined - we should not reset the result of tests
- * that were passed in previous sessions, otherwise a client may never
- * pass a multi-stage test such as greylisting. One solution is to keep
- * the original and updated time stamps around, and to save an updated
- * time stamp only when the corresponding "pass" flag is raised.
- */
-#ifdef NONPROD
- if (state->flags & PSC_STATE_FLAG_PENAL_FAIL) {
- state->pregr_stamp = state->dnsbl_stamp = state->pipel_stamp =
- state->nsmtp_stamp = state->barlf_stamp =
- ((state->flags & PSC_STATE_FLAG_NEW) ?
- PSC_TIME_STAMP_NEW : PSC_TIME_STAMP_DISABLED);
- }
-#endif
-
/*
* Give disabled tests a dummy time stamp so that we don't log a client
* with "pass new" when some disabled test becomes enabled at some later
if (var_psc_barlf_enable == 0 && state->barlf_stamp == PSC_TIME_STAMP_NEW)
state->barlf_stamp = PSC_TIME_STAMP_DISABLED;
- vstring_sprintf(buf, "%lu;%lu;%lu;%lu;%lu;%lu",
+ vstring_sprintf(buf, "%lu;%lu;%lu;%lu;%lu",
(unsigned long) state->pregr_stamp,
(unsigned long) state->dnsbl_stamp,
(unsigned long) state->pipel_stamp,
(unsigned long) state->nsmtp_stamp,
- (unsigned long) state->barlf_stamp,
- (unsigned long) state->penal_stamp);
+ (unsigned long) state->barlf_stamp);
return (STR(buf));
}
return (STR(vstring_sprintf(buf, "%s/%s/%s/%s",
client, helo, sender, rcpt)));
}
+
+/* psc_test_name - map test index to symbolic name */
+
+const char *psc_test_name(int tindx)
+{
+ const char *myname = "psc_test_name";
+ const NAME_CODE test_name_map[] = {
+ PSC_TNAME_PREGR, PSC_TINDX_PREGR,
+ PSC_TNAME_DNSBL, PSC_TINDX_DNSBL,
+ PSC_TNAME_PIPEL, PSC_TINDX_PIPEL,
+ PSC_TNAME_NSMTP, PSC_TINDX_NSMTP,
+ PSC_TNAME_BARLF, PSC_TINDX_BARLF,
+ 0, -1,
+ };
+ const char *result;
+
+ if ((result = str_name_code(test_name_map, tindx)) == 0)
+ msg_panic("%s: bad index %d", myname, tindx);
+ return (result);
+}