From: Wietse Venema Date: Sun, 12 May 2013 05:00:00 +0000 (-0500) Subject: postfix-2.11-20130512 X-Git-Tag: v2.11.0-RC1~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=385d226439913e8258a23d464d3725df99c34ec7;p=thirdparty%2Fpostfix.git postfix-2.11-20130512 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index e885287b7..bc63c9114 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -18431,3 +18431,13 @@ Apologies for any names omitted. 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. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 593f1d7c3..4ca9e12dc 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -14,6 +14,17 @@ specifies the release date of a stable release or snapshot release. 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 ==================================== diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 09d0cf166..426601d76 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -7405,6 +7405,25 @@ one-letter suffix that specifies the time unit). Time units: s

This feature is available in Postfix 2.8.

+ + +
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.

+ +

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.

+ +

This feature is available in Postfix 2.11.

+ +
postscreen_enforce_tls diff --git a/postfix/html/postscreen.8.html b/postfix/html/postscreen.8.html index 12f9b02f1..f746a4650 100644 --- a/postfix/html/postscreen.8.html +++ b/postfix/html/postscreen.8.html @@ -245,25 +245,33 @@ POSTSCREEN(8) POSTSCREEN(8) The internal service that postscreen(8) hands off allowed connections to. + Available in Postfix version 2.11 and later: + + postscreen_dnsbl_whitelist_threshold (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. + AFTER-GREETING TESTS - 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. postscreen_bare_newline_action (ignore) - The action that postscreen(8) takes when a remote - SMTP client sends a bare newline character, that + The action that postscreen(8) takes when a remote + 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_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_forbidden_commands ($smtpd_forbidden_commands) @@ -271,159 +279,159 @@ POSTSCREEN(8) POSTSCREEN(8) siders in violation of the SMTP protocol. 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 a remote - SMTP client sends non-SMTP commands as specified + The action that postscreen(8) takes when a remote + 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 a remote - SMTP client sends multiple commands instead of - sending one command and waiting for the server to + The action that postscreen(8) takes when a remote + 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. 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_direc- tory/postscreen_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 use the + The amount of time that postscreen(8) will use the result from a successful "bare newline" SMTP proto- col test. postscreen_dnsbl_ttl (1h) - The amount of time that postscreen(8) will use the + The amount of time that postscreen(8) will use the result from a successful DNS blocklist test. postscreen_greet_ttl (1d) - The amount of time that postscreen(8) will use the + The amount of time that postscreen(8) will use the result from a successful PREGREET test. postscreen_non_smtp_command_ttl (30d) - The amount of time that postscreen(8) will use the - result from a successful "non_smtp_command" SMTP + The amount of time that postscreen(8) will use the + result from a successful "non_smtp_command" SMTP protocol test. postscreen_pipelining_ttl (30d) - The amount of time that postscreen(8) will use the + The amount of time that postscreen(8) will use the result from a successful "pipelining" SMTP protocol 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 remote SMTP - client is allowed to have with the postscreen(8) + How many simultaneous connections any remote SMTP + 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 time limit to read an entire command line with + The time limit to read an entire command line with 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 Postfix 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 Postfix SMTP server process. postscreen_watchdog_timeout (10s) - How much time a postscreen(8) process may take to - respond to a remote SMTP client command or to per- + How much time a postscreen(8) 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. 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. tlsproxy_service_name (tlsproxy) - The name of the tlsproxy(8) service entry in mas- + The name of the tlsproxy(8) service entry in mas- ter.cf. 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 + Opportunistic TLS: announce STARTTLS support to remote SMTP clients, but do not require that clients use TLS encryption. postscreen_enforce_tls ($smtpd_enforce_tls) - 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. 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. 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 @@ -436,14 +444,14 @@ 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 This service was introduced with Postfix version 2.8. - 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/man5/postconf.5 b/postfix/man/man5/postconf.5 index 8d22aa22d..54d126311 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -4459,6 +4459,19 @@ one-letter suffix that specifies the time unit). Time units: s (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 diff --git a/postfix/man/man8/postscreen.8 b/postfix/man/man8/postscreen.8 index 821748de8..2aa1aacb2 100644 --- a/postfix/man/man8/postscreen.8 +++ b/postfix/man/man8/postscreen.8 @@ -242,6 +242,12 @@ up to 6 seconds otherwise). .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 diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 4c12073ae..4ae0b9964 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -964,6 +964,7 @@ while (<>) { s;\bpostscreen_dnsbl_reply_map\b;$&;g; s;\bpostscreen_dnsbl_sites\b;$&;g; s;\bpostscreen_dnsbl_thresh[-]*\n* *[]*old\b;$&;g; + s;\bpostscreen_dnsbl_whitelist_thresh[-]*\n* *[]*old\b;$&;g; s;\bpostscreen_dnsbl_action\b;$&;g; s;\bpostscreen_dnsbl_ttl\b;$&;g; s;\bpostscreen_for[-]*\n*[ ]*bidden_commands\b;$&;g; diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 9c8d9fd8c..35ca41555 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -13770,6 +13770,21 @@ parameter.

This feature is available in Postfix 2.8.

+%PARAM postscreen_dnsbl_whitelist_threshold 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.

+ +

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.

+ +

This feature is available in Postfix 2.11.

+ %PARAM postscreen_command_count_limit 20

The limit on the total number of commands per SMTP session for diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 1e368f8a5..274f654b8 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -3353,6 +3353,10 @@ extern char *var_psc_dnsbl_sites; #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; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 434e516e8..5245a0958 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 "20130405" +#define MAIL_RELEASE_DATE "20130512" #define MAIL_VERSION_NUMBER "2.11" #ifdef SNAPSHOT diff --git a/postfix/src/postscreen/Makefile.in b/postfix/src/postscreen/Makefile.in index 4d2f8265a..9c29a3d55 100644 --- a/postfix/src/postscreen/Makefile.in +++ b/postfix/src/postscreen/Makefile.in @@ -385,6 +385,7 @@ postscreen_tests.o: ../../include/match_list.h 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 diff --git a/postfix/src/postscreen/postscreen.c b/postfix/src/postscreen/postscreen.c index 0149b59ad..deff9abfa 100644 --- a/postfix/src/postscreen/postscreen.c +++ b/postfix/src/postscreen/postscreen.c @@ -214,6 +214,12 @@ /* .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 @@ -465,6 +471,7 @@ int var_psc_pregr_ttl; 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; @@ -1095,6 +1102,7 @@ int main(int argc, char **argv) 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, diff --git a/postfix/src/postscreen/postscreen.h b/postfix/src/postscreen/postscreen.h index 3fe0a9b6b..beb725fbb 100644 --- a/postfix/src/postscreen/postscreen.h +++ b/postfix/src/postscreen/postscreen.h @@ -35,6 +35,25 @@ */ #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. */ @@ -53,16 +72,11 @@ typedef struct { /* 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 */ @@ -76,10 +90,26 @@ typedef struct { 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! */ @@ -88,8 +118,11 @@ typedef struct { #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). * @@ -107,39 +140,74 @@ typedef struct { * 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. @@ -155,6 +223,8 @@ typedef struct { #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 \ @@ -195,7 +265,7 @@ typedef struct { * 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) @@ -209,7 +279,7 @@ typedef struct { (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 @@ -414,12 +484,12 @@ extern int psc_dnsbl_request(const char *, void (*) (int, char *), char *); * 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); \ @@ -430,6 +500,7 @@ extern void psc_parse_tests(PSC_STATE *, const char *, time_t); 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)) diff --git a/postfix/src/postscreen/postscreen_early.c b/postfix/src/postscreen/postscreen_early.c index cd77f5afd..54f0a5789 100644 --- a/postfix/src/postscreen/postscreen_early.c +++ b/postfix/src/postscreen/postscreen_early.c @@ -31,6 +31,7 @@ #include #include +#include /* Utility library. */ @@ -58,9 +59,7 @@ static void psc_early_event(int event, char *context) 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", @@ -91,7 +90,7 @@ static void psc_early_event(int event, char *context) * 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); @@ -108,30 +107,35 @@ static void psc_early_event(int event, char *context) */ #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: @@ -150,7 +154,9 @@ static void psc_early_event(int event, char *context) * 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); @@ -166,7 +172,8 @@ static void psc_early_event(int event, char *context) 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); @@ -182,7 +189,8 @@ static void psc_early_event(int event, char *context) 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; @@ -226,10 +234,45 @@ static void psc_early_dnsbl_event(int unused_event, char *context) { 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 @@ -272,6 +315,7 @@ void psc_early_tests(PSC_STATE *state) (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. diff --git a/postfix/src/postscreen/postscreen_state.c b/postfix/src/postscreen/postscreen_state.c index 5b97ce032..c7472cc62 100644 --- a/postfix/src/postscreen/postscreen_state.c +++ b/postfix/src/postscreen/postscreen_state.c @@ -268,9 +268,6 @@ const char *psc_print_state_flags(int flags, const char *context) /* 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, diff --git a/postfix/src/postscreen/postscreen_tests.c b/postfix/src/postscreen/postscreen_tests.c index 57bfd6999..17b7a3926 100644 --- a/postfix/src/postscreen/postscreen_tests.c +++ b/postfix/src/postscreen/postscreen_tests.c @@ -27,6 +27,9 @@ /* 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 @@ -54,6 +57,9 @@ /* 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 @@ -69,10 +75,12 @@ #include #include /* sscanf */ +#include /* strtoul */ /* Utility library. */ #include +#include /* Global library. */ @@ -132,7 +140,6 @@ void psc_new_tests(PSC_STATE *state) 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 @@ -156,17 +163,10 @@ void psc_parse_tests(PSC_STATE *state, 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. @@ -182,37 +182,19 @@ void psc_parse_tests(PSC_STATE *state, * 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 @@ -270,41 +252,6 @@ void psc_parse_tests(PSC_STATE *state, 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 */ @@ -319,25 +266,6 @@ char *psc_print_tests(VSTRING *buf, PSC_STATE *state) 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 @@ -354,13 +282,12 @@ char *psc_print_tests(VSTRING *buf, PSC_STATE *state) 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)); } @@ -373,3 +300,23 @@ char *psc_print_grey_key(VSTRING *buf, const char *client, 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); +}