Workaround: better handling of pregreeting spambots. The
postscreen built-in SMTP engine no longer sends a 220 banner
to a client that falls into the pregeet trap. This eliminates
- many "non-SMTP command" records in postscreen logging, as
+ many "NON-SMTP COMMAND" records in postscreen logging, as
the SMTP client and server no longer get out of sync. It
also results in better logging of sender/recipient information.
- file: postscreen/postscreen-smtpd.c.
+ File: postscreen/postscreen_smtpd.c.
+
+20100916
+
+ Cleanup: postscreen now uses the first responding DNSBL
+ name in the "5.7.1 Service unavailable" reply, instead of
+ the last responding one. File: postscreen/postscreen_dnsbl.c.
+
+ Cleanup: the 20100914 "postscreen_greet_wait" speedup did
+ not happen as often as it should, because some older code
+ still turned on PREGREET tests gratuitously, causing a full
+ greet-wait delay. File: postscreen/postscreen_tests.c.
+
+ Cleanup: to avoid "address in use" problems, postscreen now
+ closes the listening socket after "postfix stop". It also
+ closes the socket after "postfix reload" but that does not
+ hurt. Files: master/event_server.c, master/multi_server.c.
+
+ Cleanup: postscreen now logs CONNECT and DISCONNECT events.
+ Files: postscreen/postscreen.c, postscreen/postscreen_misc.c.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20100916"
+#define MAIL_RELEASE_DATE "20100917"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
int event_server_drain(void)
{
+ const char *myname = "event_server_drain";
int fd;
switch (fork()) {
case 0:
(void) msg_cleanup((MSG_CLEANUP_FN) 0);
event_fork();
- for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++)
+ for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++) {
event_disable_readwrite(fd);
+ (void) close(fd);
+ /* Play safe - don't reuse this file number. */
+ if (DUP2(STDIN_FILENO, fd) < 0)
+ msg_warn("%s: dup2(%d, %d): %m", myname, STDIN_FILENO, fd);
+ }
var_use_limit = 1;
return (0);
/* Let the master start a new process. */
int multi_server_drain(void)
{
+ const char *myname = "multi_server_drain";
int fd;
switch (fork()) {
case 0:
(void) msg_cleanup((MSG_CLEANUP_FN) 0);
event_fork();
- for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++)
+ for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++) {
event_disable_readwrite(fd);
+ (void) close(fd);
+ /* Play safe - don't reuse this file number. */
+ if (DUP2(STDIN_FILENO, fd) < 0)
+ msg_warn("%s: dup2(%d, %d): %m", myname, STDIN_FILENO, fd);
+ }
var_use_limit = 1;
return (0);
/* Let the master start a new process. */
*/
if (getpeername(vstream_fileno(smtp_client_stream), (struct sockaddr *)
& addr_storage, &addr_storage_len) < 0) {
- msg_warn("getpeername: %m");
+ msg_warn("getpeername: %m -- dropping this connection");
ps_send_reply(vstream_fileno(smtp_client_stream),
"unknown_address", "unknown_port",
"421 4.3.2 No system resources\r\n");
if ((aierr = sockaddr_to_hostaddr((struct sockaddr *) & addr_storage,
addr_storage_len, &smtp_client_addr,
&smtp_client_port, 0)) != 0) {
- msg_warn("cannot convert client address/port to string: %s",
+ msg_warn("cannot convert client address/port to string: %s"
+ " -- dropping this connection",
MAI_STRERROR(aierr));
ps_send_reply(vstream_fileno(smtp_client_stream),
"unknown_address", "unknown_port",
myname, ps_post_queue_length, ps_check_queue_length,
smtp_client_addr.buf, smtp_client_port.buf);
+ msg_info("CONNECT from %s", smtp_client_addr.buf);
+
/*
* Bundle up all the loose session pieces. This zeroes all flags and time
* stamps.
if (site->filter == 0
|| ps_dnsbl_match(site->filter, reply_argv ? reply_argv :
(reply_argv = argv_split(STR(reply_addr), " ")))) {
- score->dnsbl = head->safe_dnsbl;
+ if (score->dnsbl == 0)
+ score->dnsbl = head->safe_dnsbl;
score->total += site->weight;
if (msg_verbose > 1)
msg_info("%s: filter=\"%s\" weight=%d score=%d",
if (msg_verbose > 1)
msg_info("%s: create blocklist score for %s", myname, client_addr);
score = (PS_DNSBL_SCORE *) mymalloc(sizeof(*score));
+ score->dnsbl = 0;
score->total = 0;
score->refcount = 1;
score->pending_lookups = 0;
if ((state->flags & PS_STATE_FLAG_NOFORWARD) == 0) {
ps_send_socket(state);
} else {
- if ((state->flags & PS_STATE_FLAG_HANGUP) == 0)
+ if ((state->flags & PS_STATE_FLAG_HANGUP) == 0)
(void) ps_send_reply(vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port,
state->final_reply);
+ msg_info("DISCONNECT %s", state->smtp_client_addr);
ps_free_session_state(state);
}
}
/*
* Gratuitously make postscreen logging more useful by turning on all
* enabled pre-handshake tests when any pre-handshake test is turned on.
+ *
+ * XXX Don't enable PREGREET gratuitously before the test expires. With a
+ * short TTL for DNSBL whitelisting, turning on PREGREET would force a
+ * full postscreen_greet_wait too frequently.
*/
+#if 0
if (state->flags & PS_STATE_FLAG_EARLY_TODO) {
if (PS_PREGR_TEST_ENABLE())
state->flags |= PS_STATE_FLAG_PREGR_TODO;
if (PS_DNSBL_TEST_ENABLE())
state->flags |= PS_STATE_FLAG_DNSBL_TODO;
}
+#endif
}
/* ps_print_tests - print postscreen cache record */