mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-02 23:25:31 +00:00
postfix-3.8-20220421
This commit is contained in:
committed by
Viktor Dukhovni
parent
e3ead5dfac
commit
1b1cb925cd
@@ -26351,7 +26351,7 @@ Apologies for any names omitted.
|
|||||||
setting to be ignored. It is now a non-fatal error. The
|
setting to be ignored. It is now a non-fatal error. The
|
||||||
same client is used by many Postfix clients (smtpd_proxy,
|
same client is used by many Postfix clients (smtpd_proxy,
|
||||||
dovecot auth, tcp_table, memcache, socketmap, and so on).
|
dovecot auth, tcp_table, memcache, socketmap, and so on).
|
||||||
File: util/inet_connect.c.
|
Problem reported by Christian Degenkolb. File: util/inet_connect.c.
|
||||||
|
|
||||||
20220407
|
20220407
|
||||||
|
|
||||||
@@ -26365,7 +26365,8 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Cleanup (problem introduced: Postfix 2.7): milter_header_checks
|
Cleanup (problem introduced: Postfix 2.7): milter_header_checks
|
||||||
maps are now opened before the cleanup server enters the
|
maps are now opened before the cleanup server enters the
|
||||||
chroot jail. Files: cleanup/cleanup.h, cleanup/cleanup_init.c,
|
chroot jail. Problem reported by Jesper Dybdal. Files:
|
||||||
|
cleanup/cleanup.h, cleanup/cleanup_init.c,
|
||||||
cleanup/cleanup_milter.c, cleanup/cleanup_state.c.
|
cleanup/cleanup_milter.c, cleanup/cleanup_state.c.
|
||||||
|
|
||||||
20220407
|
20220407
|
||||||
@@ -26384,7 +26385,8 @@ Apologies for any names omitted.
|
|||||||
postfix-regexp package installed?" instead of "unsupported
|
postfix-regexp package installed?" instead of "unsupported
|
||||||
map type for this operation". This happened with all built-in
|
map type for this operation". This happened with all built-in
|
||||||
map types (static, cidr, etc.) that have no 'bulk create'
|
map types (static, cidr, etc.) that have no 'bulk create'
|
||||||
support. File: global/dynamicmaps.c.
|
support. Problem reported by Greg Klanderman. File:
|
||||||
|
global/dynamicmaps.c.
|
||||||
|
|
||||||
20220417
|
20220417
|
||||||
|
|
||||||
@@ -26393,3 +26395,13 @@ Apologies for any names omitted.
|
|||||||
message will not be applied to a later email message that is
|
message will not be applied to a later email message that is
|
||||||
handled by the same cleanup process. File:
|
handled by the same cleanup process. File:
|
||||||
cleanup/cleanup_milter.c.
|
cleanup/cleanup_milter.c.
|
||||||
|
|
||||||
|
20220421
|
||||||
|
|
||||||
|
Bugfix (introduced: Postfix 3.7): reverted an overly complex
|
||||||
|
change in the postscreen SMTP engine from 20211023, that
|
||||||
|
was segfaulting on malformed input, where the Postfix 3.6
|
||||||
|
implementation worked properly. The purpose of the change
|
||||||
|
was to prevent complaints about "malformed UTF8" from Postfix
|
||||||
|
lookup tables. Replaced the change with a trivial guard.
|
||||||
|
File: postscreen/postscreen_smtpd.c.
|
||||||
|
@@ -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 "20220417"
|
#define MAIL_RELEASE_DATE "20220421"
|
||||||
#define MAIL_VERSION_NUMBER "3.8"
|
#define MAIL_VERSION_NUMBER "3.8"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@@ -794,7 +794,6 @@ static void psc_smtpd_read_event(int event, void *context)
|
|||||||
char *command;
|
char *command;
|
||||||
const PSC_SMTPD_COMMAND *cmdp;
|
const PSC_SMTPD_COMMAND *cmdp;
|
||||||
int write_stat;
|
int write_stat;
|
||||||
int skip_command_processing;
|
|
||||||
|
|
||||||
if (msg_verbose > 1)
|
if (msg_verbose > 1)
|
||||||
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
|
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
|
||||||
@@ -930,39 +929,31 @@ static void psc_smtpd_read_event(int event, void *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As in smtpd(8), reject malformed UTF-8 when "smtputf8_enable =
|
* Avoid complaints from Postfix maps about malformed content.
|
||||||
* yes". This also avoids noisy "non-UTF-8 key" warnings from
|
|
||||||
* dict_utf8 infrastructure.
|
|
||||||
*
|
|
||||||
* Caution: do not skip all code in the remainder of this loop.
|
|
||||||
*/
|
*/
|
||||||
if ((skip_command_processing = (var_smtputf8_enable
|
#define PSC_BAD_UTF8(str, len) \
|
||||||
&& !valid_utf8_string(STR(state->cmd_buffer),
|
(var_smtputf8_enable && !valid_utf8_string((str), (len)))
|
||||||
LEN(state->cmd_buffer))))) {
|
|
||||||
write_stat = PSC_SEND_REPLY(state,
|
|
||||||
"500 5.5.2 Error: bad UTF-8 syntax");
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Terminate the command buffer, and apply the last-resort
|
* Terminate the command buffer, and apply the last-resort command
|
||||||
* command editing workaround.
|
* editing workaround.
|
||||||
*/
|
*/
|
||||||
VSTRING_TERMINATE(state->cmd_buffer);
|
VSTRING_TERMINATE(state->cmd_buffer);
|
||||||
if (psc_cmd_filter != 0) {
|
if (psc_cmd_filter != 0 && !PSC_BAD_UTF8(STR(state->cmd_buffer),
|
||||||
const char *cp;
|
LEN(state->cmd_buffer))) {
|
||||||
|
const char *cp;
|
||||||
|
|
||||||
for (cp = STR(state->cmd_buffer); *cp && IS_SPACE_TAB(*cp); cp++)
|
for (cp = STR(state->cmd_buffer); *cp && IS_SPACE_TAB(*cp); cp++)
|
||||||
/* void */ ;
|
/* void */ ;
|
||||||
if ((cp = psc_dict_get(psc_cmd_filter, cp)) != 0) {
|
if ((cp = psc_dict_get(psc_cmd_filter, cp)) != 0) {
|
||||||
msg_info("[%s]:%s: replacing command \"%.100s\" with \"%.100s\"",
|
msg_info("[%s]:%s: replacing command \"%.100s\" with \"%.100s\"",
|
||||||
state->smtp_client_addr, state->smtp_client_port,
|
state->smtp_client_addr, state->smtp_client_port,
|
||||||
STR(state->cmd_buffer), cp);
|
STR(state->cmd_buffer), cp);
|
||||||
vstring_strcpy(state->cmd_buffer, cp);
|
vstring_strcpy(state->cmd_buffer, cp);
|
||||||
} else if (psc_cmd_filter->error != 0) {
|
} else if (psc_cmd_filter->error != 0) {
|
||||||
msg_fatal("%s:%s lookup error for \"%.100s\"",
|
msg_fatal("%s:%s lookup error for \"%.100s\"",
|
||||||
psc_cmd_filter->type, psc_cmd_filter->name,
|
psc_cmd_filter->type, psc_cmd_filter->name,
|
||||||
STR(state->cmd_buffer));
|
STR(state->cmd_buffer));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,180 +966,175 @@ static void psc_smtpd_read_event(int event, void *context)
|
|||||||
state->read_state = PSC_SMTPD_CMD_ST_ANY;
|
state->read_state = PSC_SMTPD_CMD_ST_ANY;
|
||||||
VSTRING_RESET(state->cmd_buffer);
|
VSTRING_RESET(state->cmd_buffer);
|
||||||
|
|
||||||
if (skip_command_processing == 0) {
|
/*
|
||||||
|
* Process the command line.
|
||||||
|
*
|
||||||
|
* Caution: some command handlers terminate the session and destroy the
|
||||||
|
* session state structure. When this happens we must leave the SMTP
|
||||||
|
* engine to avoid a dangling pointer problem.
|
||||||
|
*/
|
||||||
|
cmd_buffer_ptr = STR(state->cmd_buffer);
|
||||||
|
if (msg_verbose)
|
||||||
|
msg_info("< [%s]:%s: %s", state->smtp_client_addr,
|
||||||
|
state->smtp_client_port, cmd_buffer_ptr);
|
||||||
|
|
||||||
/*
|
/* Parse the command name. */
|
||||||
* Process the command line.
|
if ((command = PSC_SMTPD_NEXT_TOKEN(cmd_buffer_ptr)) == 0)
|
||||||
*
|
command = "";
|
||||||
* Caution: some command handlers terminate the session and destroy
|
|
||||||
* the session state structure. When this happens we must leave
|
|
||||||
* the SMTP engine to avoid a dangling pointer problem.
|
|
||||||
*/
|
|
||||||
cmd_buffer_ptr = STR(state->cmd_buffer);
|
|
||||||
if (msg_verbose)
|
|
||||||
msg_info("< [%s]:%s: %s", state->smtp_client_addr,
|
|
||||||
state->smtp_client_port, cmd_buffer_ptr);
|
|
||||||
|
|
||||||
/* Parse the command name. */
|
/*
|
||||||
if ((command = PSC_SMTPD_NEXT_TOKEN(cmd_buffer_ptr)) == 0)
|
* The non-SMTP, PIPELINING and command COUNT tests depend on the
|
||||||
command = "";
|
* client command handler.
|
||||||
|
*
|
||||||
/*
|
* Caution: cmdp->name and cmdp->action may be null on loop exit.
|
||||||
* The non-SMTP, PIPELINING and command COUNT tests depend on the
|
*/
|
||||||
* client command handler.
|
saved_where = state->where;
|
||||||
*
|
state->where = PSC_SMTPD_CMD_UNIMPL;
|
||||||
* Caution: cmdp->name and cmdp->action may be null on loop exit.
|
for (cmdp = command_table; cmdp->name != 0; cmdp++) {
|
||||||
*/
|
if (strcasecmp(command, cmdp->name) == 0) {
|
||||||
saved_where = state->where;
|
state->where = cmdp->name;
|
||||||
state->where = PSC_SMTPD_CMD_UNIMPL;
|
break;
|
||||||
for (cmdp = command_table; cmdp->name != 0; cmdp++) {
|
|
||||||
if (strcasecmp(command, cmdp->name) == 0) {
|
|
||||||
state->where = cmdp->name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((state->flags & PSC_STATE_FLAG_SMTPD_X21)
|
if ((state->flags & PSC_STATE_FLAG_SMTPD_X21)
|
||||||
&& cmdp->action != psc_quit_cmd) {
|
&& cmdp->action != psc_quit_cmd) {
|
||||||
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state, psc_smtpd_time_event,
|
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state, psc_smtpd_time_event,
|
||||||
state->final_reply);
|
state->final_reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Non-SMTP command test. */
|
||||||
|
if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_SKIP)
|
||||||
|
== PSC_STATE_FLAG_NSMTP_TODO && cmdp->name == 0
|
||||||
|
&& (is_header(command)
|
||||||
|
|| PSC_BAD_UTF8(command, strlen(command))
|
||||||
|
/* Ignore forbid_cmds lookup errors. Non-critical feature. */
|
||||||
|
|| (*var_psc_forbid_cmds
|
||||||
|
&& string_list_match(psc_forbid_cmds, command)))) {
|
||||||
|
printable(command, '?');
|
||||||
|
PSC_SMTPD_ESCAPE_TEXT(psc_temp, cmd_buffer_ptr,
|
||||||
|
strlen(cmd_buffer_ptr), 100);
|
||||||
|
msg_info("NON-SMTP COMMAND from [%s]:%s after %s: %.100s %s",
|
||||||
|
PSC_CLIENT_ADDR_PORT(state), saved_where,
|
||||||
|
command, STR(psc_temp));
|
||||||
|
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_NSMTP_FAIL);
|
||||||
|
PSC_UNPASS_SESSION_STATE(state, PSC_STATE_FLAG_NSMTP_PASS);
|
||||||
|
expire_time[PSC_TINDX_NSMTP] = PSC_TIME_STAMP_DISABLED; /* XXX */
|
||||||
|
/* Skip this test for the remainder of this SMTP session. */
|
||||||
|
PSC_SKIP_SESSION_STATE(state, "non-smtp test",
|
||||||
|
PSC_STATE_FLAG_NSMTP_SKIP);
|
||||||
|
switch (psc_nsmtp_action) {
|
||||||
|
case PSC_ACT_DROP:
|
||||||
|
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
|
||||||
|
psc_smtpd_time_event,
|
||||||
|
"521 5.7.0 Error: I can break rules, too. Goodbye.\r\n");
|
||||||
return;
|
return;
|
||||||
|
case PSC_ACT_ENFORCE:
|
||||||
|
PSC_ENFORCE_SESSION_STATE(state,
|
||||||
|
"550 5.5.1 Protocol error\r\n");
|
||||||
|
break;
|
||||||
|
case PSC_ACT_IGNORE:
|
||||||
|
PSC_UNFAIL_SESSION_STATE(state,
|
||||||
|
PSC_STATE_FLAG_NSMTP_FAIL);
|
||||||
|
/* Temporarily allowlist until something else expires. */
|
||||||
|
PSC_PASS_SESSION_STATE(state, "non-smtp test",
|
||||||
|
PSC_STATE_FLAG_NSMTP_PASS);
|
||||||
|
expire_time[PSC_TINDX_NSMTP] = event_time() + psc_min_ttl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg_panic("%s: unknown non_smtp_command action value %d",
|
||||||
|
myname, psc_nsmtp_action);
|
||||||
}
|
}
|
||||||
/* Non-SMTP command test. */
|
}
|
||||||
if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_SKIP)
|
/* Command PIPELINING test. */
|
||||||
== PSC_STATE_FLAG_NSMTP_TODO && cmdp->name == 0
|
if ((cmdp->flags & PSC_SMTPD_CMD_FLAG_HAS_PAYLOAD) == 0
|
||||||
&& (is_header(command)
|
&& (state->flags & PSC_STATE_MASK_PIPEL_TODO_SKIP)
|
||||||
/* Ignore forbid_cmds lookup errors. Non-critical feature. */
|
|
||||||
|| (*var_psc_forbid_cmds
|
|
||||||
&& string_list_match(psc_forbid_cmds, command)))) {
|
|
||||||
printable(command, '?');
|
|
||||||
PSC_SMTPD_ESCAPE_TEXT(psc_temp, cmd_buffer_ptr,
|
|
||||||
strlen(cmd_buffer_ptr), 100);
|
|
||||||
msg_info("NON-SMTP COMMAND from [%s]:%s after %s: %.100s %s",
|
|
||||||
PSC_CLIENT_ADDR_PORT(state), saved_where,
|
|
||||||
command, STR(psc_temp));
|
|
||||||
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_NSMTP_FAIL);
|
|
||||||
PSC_UNPASS_SESSION_STATE(state, PSC_STATE_FLAG_NSMTP_PASS);
|
|
||||||
expire_time[PSC_TINDX_NSMTP] = PSC_TIME_STAMP_DISABLED; /* XXX */
|
|
||||||
/* Skip this test for the remainder of this SMTP session. */
|
|
||||||
PSC_SKIP_SESSION_STATE(state, "non-smtp test",
|
|
||||||
PSC_STATE_FLAG_NSMTP_SKIP);
|
|
||||||
switch (psc_nsmtp_action) {
|
|
||||||
case PSC_ACT_DROP:
|
|
||||||
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
|
|
||||||
psc_smtpd_time_event,
|
|
||||||
"521 5.7.0 Error: I can break rules, too. Goodbye.\r\n");
|
|
||||||
return;
|
|
||||||
case PSC_ACT_ENFORCE:
|
|
||||||
PSC_ENFORCE_SESSION_STATE(state,
|
|
||||||
"550 5.5.1 Protocol error\r\n");
|
|
||||||
break;
|
|
||||||
case PSC_ACT_IGNORE:
|
|
||||||
PSC_UNFAIL_SESSION_STATE(state,
|
|
||||||
PSC_STATE_FLAG_NSMTP_FAIL);
|
|
||||||
/* Temporarily allowlist until something else expires. */
|
|
||||||
PSC_PASS_SESSION_STATE(state, "non-smtp test",
|
|
||||||
PSC_STATE_FLAG_NSMTP_PASS);
|
|
||||||
expire_time[PSC_TINDX_NSMTP] = event_time() + psc_min_ttl;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
msg_panic("%s: unknown non_smtp_command action value %d",
|
|
||||||
myname, psc_nsmtp_action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Command PIPELINING test. */
|
|
||||||
if ((cmdp->flags & PSC_SMTPD_CMD_FLAG_HAS_PAYLOAD) == 0
|
|
||||||
&& (state->flags & PSC_STATE_MASK_PIPEL_TODO_SKIP)
|
|
||||||
== PSC_STATE_FLAG_PIPEL_TODO && !PSC_SMTPD_BUFFER_EMPTY(state)) {
|
== PSC_STATE_FLAG_PIPEL_TODO && !PSC_SMTPD_BUFFER_EMPTY(state)) {
|
||||||
printable(command, '?');
|
printable(command, '?');
|
||||||
PSC_SMTPD_ESCAPE_TEXT(psc_temp, PSC_SMTPD_PEEK_DATA(state),
|
PSC_SMTPD_ESCAPE_TEXT(psc_temp, PSC_SMTPD_PEEK_DATA(state),
|
||||||
PSC_SMTPD_PEEK_LEN(state), 100);
|
PSC_SMTPD_PEEK_LEN(state), 100);
|
||||||
msg_info("COMMAND PIPELINING from [%s]:%s after %.100s: %s",
|
msg_info("COMMAND PIPELINING from [%s]:%s after %.100s: %s",
|
||||||
PSC_CLIENT_ADDR_PORT(state), command, STR(psc_temp));
|
PSC_CLIENT_ADDR_PORT(state), command, STR(psc_temp));
|
||||||
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_PIPEL_FAIL);
|
PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_PIPEL_FAIL);
|
||||||
PSC_UNPASS_SESSION_STATE(state, PSC_STATE_FLAG_PIPEL_PASS);
|
PSC_UNPASS_SESSION_STATE(state, PSC_STATE_FLAG_PIPEL_PASS);
|
||||||
expire_time[PSC_TINDX_PIPEL] = PSC_TIME_STAMP_DISABLED; /* XXX */
|
expire_time[PSC_TINDX_PIPEL] = PSC_TIME_STAMP_DISABLED; /* XXX */
|
||||||
/* Skip this test for the remainder of this SMTP session. */
|
/* Skip this test for the remainder of this SMTP session. */
|
||||||
PSC_SKIP_SESSION_STATE(state, "pipelining test",
|
PSC_SKIP_SESSION_STATE(state, "pipelining test",
|
||||||
PSC_STATE_FLAG_PIPEL_SKIP);
|
PSC_STATE_FLAG_PIPEL_SKIP);
|
||||||
switch (psc_pipel_action) {
|
switch (psc_pipel_action) {
|
||||||
case PSC_ACT_DROP:
|
case PSC_ACT_DROP:
|
||||||
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
|
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
|
||||||
psc_smtpd_time_event,
|
psc_smtpd_time_event,
|
||||||
"521 5.5.1 Protocol error\r\n");
|
"521 5.5.1 Protocol error\r\n");
|
||||||
return;
|
|
||||||
case PSC_ACT_ENFORCE:
|
|
||||||
PSC_ENFORCE_SESSION_STATE(state,
|
|
||||||
"550 5.5.1 Protocol error\r\n");
|
|
||||||
break;
|
|
||||||
case PSC_ACT_IGNORE:
|
|
||||||
PSC_UNFAIL_SESSION_STATE(state,
|
|
||||||
PSC_STATE_FLAG_PIPEL_FAIL);
|
|
||||||
/* Temporarily allowlist until something else expires. */
|
|
||||||
PSC_PASS_SESSION_STATE(state, "pipelining test",
|
|
||||||
PSC_STATE_FLAG_PIPEL_PASS);
|
|
||||||
expire_time[PSC_TINDX_PIPEL] = event_time() + psc_min_ttl;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
msg_panic("%s: unknown pipelining action value %d",
|
|
||||||
myname, psc_pipel_action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following tests don't pass until the client gets all the
|
|
||||||
* way to the RCPT TO command. However, the client can still fail
|
|
||||||
* these tests with some later command.
|
|
||||||
*/
|
|
||||||
if (cmdp->action == psc_rcpt_cmd) {
|
|
||||||
if ((state->flags & PSC_STATE_MASK_BARLF_TODO_PASS_FAIL)
|
|
||||||
== PSC_STATE_FLAG_BARLF_TODO) {
|
|
||||||
PSC_PASS_SESSION_STATE(state, "bare newline test",
|
|
||||||
PSC_STATE_FLAG_BARLF_PASS);
|
|
||||||
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
|
||||||
expire_time[PSC_TINDX_BARLF] = event_time()
|
|
||||||
+ var_psc_barlf_ttl;
|
|
||||||
}
|
|
||||||
if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_PASS_FAIL)
|
|
||||||
== PSC_STATE_FLAG_NSMTP_TODO) {
|
|
||||||
PSC_PASS_SESSION_STATE(state, "non-smtp test",
|
|
||||||
PSC_STATE_FLAG_NSMTP_PASS);
|
|
||||||
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
|
||||||
expire_time[PSC_TINDX_NSMTP] = event_time()
|
|
||||||
+ var_psc_nsmtp_ttl;
|
|
||||||
}
|
|
||||||
if ((state->flags & PSC_STATE_MASK_PIPEL_TODO_PASS_FAIL)
|
|
||||||
== PSC_STATE_FLAG_PIPEL_TODO) {
|
|
||||||
PSC_PASS_SESSION_STATE(state, "pipelining test",
|
|
||||||
PSC_STATE_FLAG_PIPEL_PASS);
|
|
||||||
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
|
||||||
expire_time[PSC_TINDX_PIPEL] = event_time()
|
|
||||||
+ var_psc_pipel_ttl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Command COUNT limit test. */
|
|
||||||
if (++state->command_count > var_psc_cmd_count
|
|
||||||
&& cmdp->action != psc_quit_cmd) {
|
|
||||||
msg_info("COMMAND COUNT LIMIT from [%s]:%s after %s",
|
|
||||||
PSC_CLIENT_ADDR_PORT(state), saved_where);
|
|
||||||
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state, psc_smtpd_time_event,
|
|
||||||
psc_smtpd_421_reply);
|
|
||||||
return;
|
return;
|
||||||
|
case PSC_ACT_ENFORCE:
|
||||||
|
PSC_ENFORCE_SESSION_STATE(state,
|
||||||
|
"550 5.5.1 Protocol error\r\n");
|
||||||
|
break;
|
||||||
|
case PSC_ACT_IGNORE:
|
||||||
|
PSC_UNFAIL_SESSION_STATE(state,
|
||||||
|
PSC_STATE_FLAG_PIPEL_FAIL);
|
||||||
|
/* Temporarily allowlist until something else expires. */
|
||||||
|
PSC_PASS_SESSION_STATE(state, "pipelining test",
|
||||||
|
PSC_STATE_FLAG_PIPEL_PASS);
|
||||||
|
expire_time[PSC_TINDX_PIPEL] = event_time() + psc_min_ttl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg_panic("%s: unknown pipelining action value %d",
|
||||||
|
myname, psc_pipel_action);
|
||||||
}
|
}
|
||||||
/* Finally, execute the command. */
|
}
|
||||||
if (cmdp->name == 0 || (cmdp->flags & PSC_SMTPD_CMD_FLAG_ENABLE) == 0) {
|
|
||||||
write_stat = PSC_SEND_REPLY(state,
|
/*
|
||||||
|
* The following tests don't pass until the client gets all the way
|
||||||
|
* to the RCPT TO command. However, the client can still fail these
|
||||||
|
* tests with some later command.
|
||||||
|
*/
|
||||||
|
if (cmdp->action == psc_rcpt_cmd) {
|
||||||
|
if ((state->flags & PSC_STATE_MASK_BARLF_TODO_PASS_FAIL)
|
||||||
|
== PSC_STATE_FLAG_BARLF_TODO) {
|
||||||
|
PSC_PASS_SESSION_STATE(state, "bare newline test",
|
||||||
|
PSC_STATE_FLAG_BARLF_PASS);
|
||||||
|
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
||||||
|
expire_time[PSC_TINDX_BARLF] = event_time() + var_psc_barlf_ttl;
|
||||||
|
}
|
||||||
|
if ((state->flags & PSC_STATE_MASK_NSMTP_TODO_PASS_FAIL)
|
||||||
|
== PSC_STATE_FLAG_NSMTP_TODO) {
|
||||||
|
PSC_PASS_SESSION_STATE(state, "non-smtp test",
|
||||||
|
PSC_STATE_FLAG_NSMTP_PASS);
|
||||||
|
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
||||||
|
expire_time[PSC_TINDX_NSMTP] = event_time() + var_psc_nsmtp_ttl;
|
||||||
|
}
|
||||||
|
if ((state->flags & PSC_STATE_MASK_PIPEL_TODO_PASS_FAIL)
|
||||||
|
== PSC_STATE_FLAG_PIPEL_TODO) {
|
||||||
|
PSC_PASS_SESSION_STATE(state, "pipelining test",
|
||||||
|
PSC_STATE_FLAG_PIPEL_PASS);
|
||||||
|
/* XXX Reset to PSC_TIME_STAMP_DISABLED on failure. */
|
||||||
|
expire_time[PSC_TINDX_PIPEL] = event_time() + var_psc_pipel_ttl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Command COUNT limit test. */
|
||||||
|
if (++state->command_count > var_psc_cmd_count
|
||||||
|
&& cmdp->action != psc_quit_cmd) {
|
||||||
|
msg_info("COMMAND COUNT LIMIT from [%s]:%s after %s",
|
||||||
|
PSC_CLIENT_ADDR_PORT(state), saved_where);
|
||||||
|
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state, psc_smtpd_time_event,
|
||||||
|
psc_smtpd_421_reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Finally, execute the command. */
|
||||||
|
if (cmdp->name == 0 || (cmdp->flags & PSC_SMTPD_CMD_FLAG_ENABLE) == 0) {
|
||||||
|
write_stat = PSC_SEND_REPLY(state,
|
||||||
"502 5.5.2 Error: command not recognized\r\n");
|
"502 5.5.2 Error: command not recognized\r\n");
|
||||||
} else if (var_psc_enforce_tls
|
} else if (var_psc_enforce_tls
|
||||||
&& (state->flags & PSC_STATE_FLAG_USING_TLS) == 0
|
&& (state->flags & PSC_STATE_FLAG_USING_TLS) == 0
|
||||||
&& (cmdp->flags & PSC_SMTPD_CMD_FLAG_PRE_TLS) == 0) {
|
&& (cmdp->flags & PSC_SMTPD_CMD_FLAG_PRE_TLS) == 0) {
|
||||||
write_stat = PSC_SEND_REPLY(state,
|
write_stat = PSC_SEND_REPLY(state,
|
||||||
"530 5.7.0 Must issue a STARTTLS command first\r\n");
|
"530 5.7.0 Must issue a STARTTLS command first\r\n");
|
||||||
} else {
|
} else {
|
||||||
write_stat = cmdp->action(state, cmd_buffer_ptr);
|
write_stat = cmdp->action(state, cmd_buffer_ptr);
|
||||||
if (cmdp->flags & PSC_SMTPD_CMD_FLAG_DESTROY)
|
if (cmdp->flags & PSC_SMTPD_CMD_FLAG_DESTROY)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user