2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 18:07:41 +00:00

postfix-2.9-20111025

This commit is contained in:
Wietse Venema 2011-10-25 00:00:00 -05:00 committed by Viktor Dukhovni
parent 02fa92e7b7
commit 550f5dd6c9
6 changed files with 65 additions and 12 deletions

View File

@ -17020,3 +17020,15 @@ Apologies for any names omitted.
EAI Future-proofing: don't apply strict_mime_encoding_domain EAI Future-proofing: don't apply strict_mime_encoding_domain
checks to unknown message subtypes such as message/global*. checks to unknown message subtypes such as message/global*.
File: global/mime_state.c. File: global/mime_state.c.
20111025
Bugfix (introduced: Postfix 2.8): postscreen sent non-compliant
SMTP responses (220- followed by 421) when it could not
hand off a connection to a real smtpd process, causing
undefined behavior in the remote SMTP client. The fix
redirects the client to the dummy SMTP engine which sends
the 421 reply at the first legitimate opportunity. Problem
reported by Ralf Hildebrandt. Files: postscreen/postscreen_send.c,
postscreen/postscreen_smtpd.c, postscreen/postscreen.h.

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20111024" #define MAIL_RELEASE_DATE "20111025"
#define MAIL_VERSION_NUMBER "2.9" #define MAIL_VERSION_NUMBER "2.9"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -635,7 +635,7 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
(void) rec_fprintf(stream, REC_TYPE_MILT_COUNT, "%d", count); (void) rec_fprintf(stream, REC_TYPE_MILT_COUNT, "%d", count);
if (msg_verbose) if (msg_verbose)
msg_info("send %d milters"); msg_info("send %d milters", count);
/* /*
* XXX Optimization: don't send or receive further information when there * XXX Optimization: don't send or receive further information when there

View File

@ -81,7 +81,7 @@ typedef struct {
#define PSC_STATE_FLAG_NEW (1<<3) /* some test was never passed */ #define PSC_STATE_FLAG_NEW (1<<3) /* some test was never passed */
#define PSC_STATE_FLAG_BLIST_FAIL (1<<4) /* blacklisted */ #define PSC_STATE_FLAG_BLIST_FAIL (1<<4) /* blacklisted */
#define PSC_STATE_FLAG_HANGUP (1<<5) /* NOT a test failure */ #define PSC_STATE_FLAG_HANGUP (1<<5) /* NOT a test failure */
/* unused */ #define PSC_STATE_FLAG_SMTPD_421 (1<<6) /* hang up after command */
#define PSC_STATE_FLAG_WLIST_FAIL (1<<7) /* do not whitelist */ #define PSC_STATE_FLAG_WLIST_FAIL (1<<7) /* do not whitelist */
/* /*
@ -435,6 +435,12 @@ extern void psc_smtpd_tests(PSC_STATE *);
extern void psc_smtpd_init(void); extern void psc_smtpd_init(void);
extern void psc_smtpd_pre_jail_init(void); extern void psc_smtpd_pre_jail_init(void);
#define PSC_SMTPD_421(state, reply) do { \
(state)->flags |= PSC_STATE_FLAG_SMTPD_421; \
(state)->final_reply = (reply); \
psc_smtpd_tests(state); \
} while (0)
/* /*
* postscreen_misc.c * postscreen_misc.c
*/ */

View File

@ -35,7 +35,10 @@
/* work is finished including postscreen cache updates. /* work is finished including postscreen cache updates.
/* /*
/* In case of an immediate error, psc_send_socket() sends a 421 /* In case of an immediate error, psc_send_socket() sends a 421
/* reply to the remote SMTP client and closes the connection. /* reply to the remote SMTP client and closes the connection
/* if no partial SMTP greeting was sent. Otherwise, it redirects
/* the SMTP client to the dummy protocol engine which sends
/* 421 at the first legitimate opportunity and hangs up.
/* LICENSE /* LICENSE
/* .ad /* .ad
/* .fi /* .fi
@ -182,22 +185,35 @@ void psc_send_socket(PSC_STATE *state)
* suspicious. Alternatively, we could send attributes along with the * suspicious. Alternatively, we could send attributes along with the
* socket with client reputation information, making everything even more * socket with client reputation information, making everything even more
* Postfix-specific. * Postfix-specific.
*
* If the operation fails after the partial SMTP handshake was sent,
* redirect the client to the dummy SMTP engine, which finishes the
* partial SMTP handshake sends the bad news after the first client
* command.
*/ */
if ((server_fd = if ((server_fd =
PASS_CONNECT(psc_smtpd_service_name, NON_BLOCKING, PASS_CONNECT(psc_smtpd_service_name, NON_BLOCKING,
PSC_SEND_SOCK_CONNECT_TIMEOUT)) < 0) { PSC_SEND_SOCK_CONNECT_TIMEOUT)) < 0) {
msg_warn("cannot connect to service %s: %m", psc_smtpd_service_name); msg_warn("cannot connect to service %s: %m", psc_smtpd_service_name);
if (state->flags & PSC_STATE_FLAG_PREGR_TODO) {
PSC_SMTPD_421(state, "421 4.3.2 No system resources\r\n");
} else {
PSC_SEND_REPLY(state, "421 4.3.2 All server ports are busy\r\n"); PSC_SEND_REPLY(state, "421 4.3.2 All server ports are busy\r\n");
psc_free_session_state(state); psc_free_session_state(state);
}
return; return;
} }
PSC_ADD_SERVER_STATE(state, server_fd); if (LOCAL_SEND_FD(server_fd,
if (LOCAL_SEND_FD(state->smtp_server_fd,
vstream_fileno(state->smtp_client_stream)) < 0) { vstream_fileno(state->smtp_client_stream)) < 0) {
msg_warn("cannot pass connection to service %s: %m", msg_warn("cannot pass connection to service %s: %m",
psc_smtpd_service_name); psc_smtpd_service_name);
(void) close(server_fd);
if (state->flags & PSC_STATE_FLAG_PREGR_TODO) {
PSC_SMTPD_421(state, "421 4.3.2 No system resources\r\n");
} else {
PSC_SEND_REPLY(state, "421 4.3.2 No system resources\r\n"); PSC_SEND_REPLY(state, "421 4.3.2 No system resources\r\n");
psc_free_session_state(state); psc_free_session_state(state);
}
return; return;
} else { } else {
@ -209,6 +225,7 @@ void psc_send_socket(PSC_STATE *state)
#if 0 #if 0
PSC_DEL_CLIENT_STATE(state); PSC_DEL_CLIENT_STATE(state);
#endif #endif
PSC_ADD_SERVER_STATE(state, server_fd);
PSC_READ_EVENT_REQUEST(state->smtp_server_fd, psc_send_socket_close_event, PSC_READ_EVENT_REQUEST(state->smtp_server_fd, psc_send_socket_close_event,
(char *) state, PSC_SEND_SOCK_NOTIFY_TIMEOUT); (char *) state, PSC_SEND_SOCK_NOTIFY_TIMEOUT);
return; return;

View File

@ -12,6 +12,10 @@
/* /*
/* void psc_smtpd_tests(state) /* void psc_smtpd_tests(state)
/* PSC_STATE *state; /* PSC_STATE *state;
/*
/* void PSC_SMTPD_421(state, final_reply)
/* PSC_STATE *state;
/* const char *final_reply;
/* DESCRIPTION /* DESCRIPTION
/* psc_smtpd_pre_jail_init() performs one-time per-process /* psc_smtpd_pre_jail_init() performs one-time per-process
/* initialization during the "before chroot" execution phase. /* initialization during the "before chroot" execution phase.
@ -22,6 +26,12 @@
/* protocol tests and for collecting helo/sender/recipient /* protocol tests and for collecting helo/sender/recipient
/* information. /* information.
/* /*
/* PSC_SMTPD_421() redirects the SMTP client to the dummy SMTP
/* protocol engine, completes the SMTP protocol handshake,
/* sends the specified final reply after the first non-QUIT
/* client command, and hangs up without doing any protocol
/* tests. The final reply must end in <CR><LF>.
/*
/* Unlike the Postfix SMTP server, this engine does not announce /* Unlike the Postfix SMTP server, this engine does not announce
/* PIPELINING support. This exposes spambots that pipeline /* PIPELINING support. This exposes spambots that pipeline
/* their commands anyway. Like the Postfix SMTP server, this /* their commands anyway. Like the Postfix SMTP server, this
@ -904,6 +914,12 @@ static void psc_smtpd_read_event(int event, char *context)
if (strcasecmp(command, cmdp->name) == 0) if (strcasecmp(command, cmdp->name) == 0)
break; break;
if ((state->flags & PSC_STATE_FLAG_SMTPD_421)
&& cmdp->action != psc_quit_cmd) {
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state, psc_smtpd_time_event,
state->final_reply);
return;
}
/* Non-SMTP command test. */ /* Non-SMTP command test. */
if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_SKIP) if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_SKIP)
== PSC_STATE_FLAG_NSMTP_TODO && cmdp->name == 0 == PSC_STATE_FLAG_NSMTP_TODO && cmdp->name == 0
@ -1088,7 +1104,9 @@ void psc_smtpd_tests(PSC_STATE *state)
* *
* XXX Make "opportunistically" configurable for each test. * XXX Make "opportunistically" configurable for each test.
*/ */
state->flags |= (PSC_STATE_FLAG_PIPEL_TODO | PSC_STATE_FLAG_NSMTP_TODO | \ if ((state->flags & PSC_STATE_FLAG_SMTPD_421) == 0)
state->flags |= (PSC_STATE_FLAG_PIPEL_TODO | \
PSC_STATE_FLAG_NSMTP_TODO | \
PSC_STATE_FLAG_BARLF_TODO); PSC_STATE_FLAG_BARLF_TODO);
/* /*