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:
parent
d46974e068
commit
55ffb3828e
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user