2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 05:07:58 +00:00

postfix-2.5.1-RC2

This commit is contained in:
Wietse Venema 2008-02-10 00:00:00 -05:00 committed by Viktor Dukhovni
parent d46974e068
commit 55ffb3828e
10 changed files with 113 additions and 41 deletions

View File

@ -14300,3 +14300,15 @@ Apologies for any names omitted.
Workaround (introduced 20071204): update the wrong proxywrite
process limit when upgrading an already installed default
master.cf file. File: conf/post-install.
20080207
Cleanup: soft_bounce support for multi-line Milter replies.
File: src/milter/milter8.c.
Cleanup: preserve multi-line format of header/body Milter
replies. Files: cleanup/cleanup_milter.c, smtpd/smtpd.c.
Cleanup: multi-line support in SMTP server replies. File:
smtpd/smtpd_chat.c.

View File

@ -491,8 +491,10 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
status = cleanup_flush(state); /* in case state is modified */
attr_print(src, ATTR_FLAG_NONE,
ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
ATTR_TYPE_STR, MAIL_ATTR_WHY, state->reason ?
state->reason : "",
ATTR_TYPE_STR, MAIL_ATTR_WHY,
(state->flags & CLEANUP_FLAG_SMTP_REPLY)
&& state->smtp_reply ? state->smtp_reply :
state->reason ? state->reason : "",
ATTR_TYPE_END);
cleanup_free(state);

View File

@ -78,6 +78,7 @@ typedef struct CLEANUP_STATE {
off_t append_hdr_pt_target; /* target of above record */
ssize_t rcpt_count; /* recipient count */
char *reason; /* failure reason */
char *smtp_reply; /* failure reason, SMTP-style */
NVTABLE *attr; /* queue file attribute list */
MIME_STATE *mime_state; /* MIME state engine */
int mime_errs; /* MIME error flags */

View File

@ -216,6 +216,29 @@
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/*
* Milter replies.
*/
#define CLEANUP_MILTER_SET_REASON(__state, __reason) do { \
if ((__state)->reason) \
myfree((__state)->reason); \
(__state)->reason = mystrdup(__reason); \
if ((__state)->smtp_reply) { \
myfree((__state)->smtp_reply); \
(__state)->smtp_reply = 0; \
} \
} while (0)
#define CLEANUP_MILTER_SET_SMTP_REPLY(__state, __smtp_reply) do { \
if ((__state)->reason) \
myfree((__state)->reason); \
(__state)->reason = mystrdup(__smtp_reply + 4); \
printable((__state)->reason, '_'); \
if ((__state)->smtp_reply) \
myfree((__state)->smtp_reply); \
(__state)->smtp_reply = mystrdup(__smtp_reply); \
} while (0)
/* cleanup_milter_set_error - set error flag from errno */
static void cleanup_milter_set_error(CLEANUP_STATE *state, int err)
@ -1402,25 +1425,17 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
* CLEANUP_STAT_CONT and CLEANUP_STAT_DEFER both update the reason
* attribute, but CLEANUP_STAT_DEFER takes precedence. It terminates
* queue record processing, and prevents bounces from being sent.
*
* XXX Multi-line replies are messy, We should eliminate not only the
* CRLF, but also the SMTP status and the enhanced status code that
* follows.
*/
case '4':
if (state->reason)
myfree(state->reason);
ret = state->reason = mystrdup(resp + 4);
printable(state->reason, '_');
CLEANUP_MILTER_SET_SMTP_REPLY(state, resp);
ret = state->reason;
state->errs |= CLEANUP_STAT_DEFER;
action = "milter-reject";
text = resp + 4;
break;
case '5':
if (state->reason)
myfree(state->reason);
ret = state->reason = mystrdup(resp + 4);
printable(state->reason, '_');
CLEANUP_MILTER_SET_SMTP_REPLY(state, resp);
ret = state->reason;
state->errs |= CLEANUP_STAT_CONT;
action = "milter-reject";
text = resp + 4;
@ -1596,9 +1611,7 @@ void cleanup_milter_emul_rcpt(CLEANUP_STATE *state,
msg_warn("%s: milter configuration error: can't reject recipient "
"in non-smtpd(8) submission", state->queue_id);
msg_warn("%s: deferring delivery of this message", state->queue_id);
if (state->reason)
myfree(state->reason);
state->reason = mystrdup("4.3.5 Server configuration error");
CLEANUP_MILTER_SET_REASON(state, "4.3.5 Server configuration error");
state->errs |= CLEANUP_STAT_DEFER;
}
}

View File

@ -97,6 +97,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
state->append_hdr_pt_target = -1;
state->rcpt_count = 0;
state->reason = 0;
state->smtp_reply = 0;
state->attr = nvtable_create(10);
nvtable_update(state->attr, MAIL_ATTR_LOG_ORIGIN, MAIL_ATTR_ORG_LOCAL);
state->mime_state = 0;
@ -150,6 +151,8 @@ void cleanup_state_free(CLEANUP_STATE *state)
been_here_free(state->dups);
if (state->reason)
myfree(state->reason);
if (state->smtp_reply)
myfree(state->smtp_reply);
nvtable_free(state->attr);
if (state->mime_state)
mime_state_free(state->mime_state);

View File

@ -22,6 +22,7 @@
#define CLEANUP_FLAG_BCC_OK (1<<4) /* Ok to add auto-BCC addresses */
#define CLEANUP_FLAG_MAP_OK (1<<5) /* Ok to map addresses */
#define CLEANUP_FLAG_MILTER (1<<6) /* Enable Milter applications */
#define CLEANUP_FLAG_SMTP_REPLY (1<<7) /* Enable SMTP reply */
#define CLEANUP_FLAG_FILTER_ALL (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_MILTER)
/*

View File

@ -20,8 +20,8 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20080123"
#define MAIL_VERSION_NUMBER "2.5.1-RC1"
#define MAIL_RELEASE_DATE "20080210"
#define MAIL_VERSION_NUMBER "2.5.1-RC2"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE

View File

@ -83,7 +83,7 @@
/* Global library. */
#include <mail_params.h> /* var_line_limit */
#include <mail_params.h>
#include <mail_proto.h>
#include <rec_type.h>
#include <record.h>
@ -1094,6 +1094,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
char *cp;
char *rp;
char ch;
char *next;
if (milter8_read_resp(milter, event, &cmd, &data_size) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
@ -1266,6 +1267,18 @@ static const char *milter8_event(MILTER8 *milter, int event,
break;
}
}
if (var_soft_bounce) {
for (cp = STR(milter->buf); /* void */ ; cp = next) {
if (cp[0] == '5') {
cp[0] = '4';
if (cp[4] == '5')
cp[4] = '4';
}
if ((next = strstr(cp, "\r\n")) == 0)
break;
next += 2;
}
}
if (IN_CONNECT_EVENT(event)) {
#ifdef LIBMILTER_AUTO_DISCONNECT
milter8_close_stream(milter);

View File

@ -1633,7 +1633,8 @@ static int mail_open_stream(SMTPD_STATE *state)
smtpd_check_rewrite(state);
cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
smtpd_input_transp_mask);
smtpd_input_transp_mask)
| CLEANUP_FLAG_SMTP_REPLY;
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
var_cleanup_service);
if (state->dest == 0
@ -2864,6 +2865,11 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
*
* See also: qmqpd.c
*/
#define IS_SMTP_REJECT(s) \
(((s)[0] == '4' || (s)[0] == '5') \
&& ISDIGIT((s)[1]) && ISDIGIT((s)[2]) \
&& ((s)[3] == '\0' || (s)[3] == ' ' || (s)[3] == '-'))
if (state->err == CLEANUP_STAT_OK) {
state->error_count = 0;
state->error_mask = 0;
@ -2873,6 +2879,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
"250 2.0.0 Ok: queued as %s", state->queue_id);
else
smtpd_chat_reply(state, "%s", STR(state->proxy_buffer));
} else if (why && IS_SMTP_REJECT(STR(why))) {
state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "%s", STR(why));
} else if ((state->err & CLEANUP_STAT_DEFER) != 0) {
state->error_mask |= MAIL_ERROR_POLICY;
detail = cleanup_stat_detail(CLEANUP_STAT_DEFER);
@ -3766,7 +3775,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
* we exclude xclient authorized hosts from event count/rate control.
*/
if (var_smtpd_cntls_limit > 0
&& (state->tls_context == 0 || state->tls_context->session_reused == 0)
&& (state->tls_context == 0 || state->tls_context->session_reused == 0)
&& SMTPD_STAND_ALONE(state) == 0
&& !xclient_allowed
&& anvil_clnt
@ -3779,7 +3788,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
rate, state->namaddr, state->service);
if (state->tls_context)
smtpd_chat_reply(state,
"421 4.7.0 %s Error: too many new TLS sessions from %s",
"421 4.7.0 %s Error: too many new TLS sessions from %s",
var_myhostname, state->namaddr);
/* XXX Use regular return to signal end of session. */
vstream_longjmp(state->client, SMTP_ERR_QUIET);

View File

@ -104,7 +104,8 @@ void smtpd_chat_reset(SMTPD_STATE *state)
/* smtp_chat_append - append record to SMTP transaction log */
static void smtp_chat_append(SMTPD_STATE *state, char *direction)
static void smtp_chat_append(SMTPD_STATE *state, char *direction,
const char *text)
{
char *line;
@ -113,7 +114,7 @@ static void smtp_chat_append(SMTPD_STATE *state, char *direction)
if (state->history == 0)
state->history = argv_alloc(10);
line = concatenate(direction, STR(state->buffer), (char *) 0);
line = concatenate(direction, text, (char *) 0);
argv_add(state->history, line, (char *) 0);
myfree(line);
}
@ -125,7 +126,7 @@ void smtpd_chat_query(SMTPD_STATE *state)
int last_char;
last_char = smtp_get(state->buffer, state->client, var_line_limit);
smtp_chat_append(state, "In: ");
smtp_chat_append(state, "In: ", STR(state->buffer));
if (last_char != '\n')
msg_warn("%s: request longer than %d: %.30s...",
state->namaddr, var_line_limit,
@ -141,20 +142,9 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
{
va_list ap;
int delay = 0;
va_start(ap, format);
vstring_vsprintf(state->buffer, format, ap);
va_end(ap);
/* All 5xx replies must have a 5.xx.xx detail code. */
if (var_soft_bounce && STR(state->buffer)[0] == '5') {
STR(state->buffer)[0] = '4';
if (STR(state->buffer)[4] == '5')
STR(state->buffer)[4] = '4';
}
smtp_chat_append(state, "Out: ");
if (msg_verbose)
msg_info("> %s: %s", state->namaddr, STR(state->buffer));
char *cp;
char *next;
char *end;
/*
* Slow down clients that make errors. Sleep-on-anything slows down
@ -163,7 +153,35 @@ void smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
if (state->error_count >= var_smtpd_soft_erlim)
sleep(delay = var_smtpd_err_sleep);
smtp_fputs(STR(state->buffer), LEN(state->buffer), state->client);
va_start(ap, format);
vstring_vsprintf(state->buffer, format, ap);
va_end(ap);
/* All 5xx replies must have a 5.xx.xx detail code. */
for (cp = STR(state->buffer), end = cp + strlen(STR(state->buffer));;) {
if (var_soft_bounce) {
if (cp[0] == '5') {
cp[0] = '4';
if (cp[4] == '5')
cp[4] = '4';
}
}
/* This is why we use strlen() above instead of VSTRING_LEN(). */
if ((next = strstr(cp, "\r\n")) != 0) {
*next = 0;
} else {
next = end;
}
smtp_chat_append(state, "Out: ", cp);
if (msg_verbose)
msg_info("> %s: %s", state->namaddr, cp);
smtp_fputs(cp, next - cp, state->client);
if (next < end)
cp = next + 2;
else
break;
}
/*
* Flush unsent output if no I/O happened for a while. This avoids