From: Stephan Bosch Date: Mon, 31 Aug 2020 12:58:44 +0000 (+0200) Subject: lib-smtp: smtp-server-command - Always call the NEXT_TO_REPLY hook. X-Git-Tag: 2.3.13~236 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=55a8b332c01f6392f105bd47d2dcf88c16f151d9;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: smtp-server-command - Always call the NEXT_TO_REPLY hook. Before, it wasn't called when a reply was submitted before the command became next to reply. --- diff --git a/src/lib-smtp/smtp-server-cmd-mail.c b/src/lib-smtp/smtp-server-cmd-mail.c index b46609c1a0..7fcebb1fa6 100644 --- a/src/lib-smtp/smtp-server-cmd-mail.c +++ b/src/lib-smtp/smtp-server-cmd-mail.c @@ -14,6 +14,12 @@ static bool cmd_mail_check_state(struct smtp_server_cmd_ctx *cmd) { struct smtp_server_connection *conn = cmd->conn; + struct smtp_server_command *command = cmd->cmd; + + if (smtp_server_command_is_replied(command) && + !smtp_server_command_replied_success(command) && + !smtp_server_command_reply_is_forwarded(command)) + return FALSE; if (conn->state.trans != NULL) { smtp_server_reply(cmd, 503, "5.5.0", "MAIL already given"); @@ -33,10 +39,11 @@ cmd_mail_completed(struct smtp_server_cmd_ctx *cmd, conn->state.pending_mail_cmds--; i_assert(smtp_server_command_is_replied(command)); + i_assert(conn->state.state == SMTP_SERVER_STATE_MAIL_FROM || + !smtp_server_command_replied_success(command)); + if (!smtp_server_command_replied_success(command)) { - /* Failure; substitute our own error if predictable */ - if (smtp_server_command_reply_is_forwarded(command)) - (void)cmd_mail_check_state(cmd); + /* Failure */ return; } diff --git a/src/lib-smtp/smtp-server-cmd-rcpt.c b/src/lib-smtp/smtp-server-cmd-rcpt.c index 2be4f6aee4..1a4a0014dd 100644 --- a/src/lib-smtp/smtp-server-cmd-rcpt.c +++ b/src/lib-smtp/smtp-server-cmd-rcpt.c @@ -26,8 +26,14 @@ cmd_rcpt_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, static bool cmd_rcpt_check_state(struct smtp_server_cmd_ctx *cmd) { struct smtp_server_connection *conn = cmd->conn; + struct smtp_server_command *command = cmd->cmd; struct smtp_server_transaction *trans = conn->state.trans; + if (smtp_server_command_is_replied(command) && + !smtp_server_command_replied_success(command) && + !smtp_server_command_reply_is_forwarded(command)) + return FALSE; + if (conn->state.pending_mail_cmds == 0 && trans == NULL) { smtp_server_reply(cmd, 503, "5.5.0", "MAIL needed first"); @@ -55,21 +61,13 @@ cmd_rcpt_completed(struct smtp_server_cmd_ctx *cmd, i_assert(conn->state.pending_rcpt_cmds > 0); conn->state.pending_rcpt_cmds--; - if (conn->state.state < SMTP_SERVER_STATE_RCPT_TO) { - i_assert(conn->state.state == SMTP_SERVER_STATE_MAIL_FROM); - smtp_server_connection_set_state( - conn, SMTP_SERVER_STATE_RCPT_TO, - smtp_address_encode(data->rcpt->path)); - } - i_assert(smtp_server_command_is_replied(command)); + i_assert(conn->state.state == SMTP_SERVER_STATE_RCPT_TO || + !smtp_server_command_replied_success(command)); + if (!smtp_server_command_replied_success(command)) { + /* Failure */ conn->state.denied_rcpt_cmds++; - - /* Failure; substitute our own error if predictable */ - if (smtp_server_command_reply_is_forwarded(command)) - (void)cmd_rcpt_check_state(cmd); - smtp_server_recipient_denied( rcpt, smtp_server_command_get_reply(cmd->cmd, 0)); return; diff --git a/src/lib-smtp/smtp-server-command.c b/src/lib-smtp/smtp-server-command.c index 6edabf46c0..8281d18b6d 100644 --- a/src/lib-smtp/smtp-server-command.c +++ b/src/lib-smtp/smtp-server-command.c @@ -465,8 +465,12 @@ bool smtp_server_command_next_to_reply(struct smtp_server_command **_cmd) e_debug(cmd->context.event, "Next to reply"); - return smtp_server_command_call_hooks( - _cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, TRUE); + if (!smtp_server_command_call_hooks( + _cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, TRUE)) + return FALSE; + + smtp_server_command_remove_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_NEXT); + return TRUE; } void smtp_server_command_ready_to_reply(struct smtp_server_command *cmd) @@ -568,8 +572,6 @@ void smtp_server_command_submit_reply(struct smtp_server_command *cmd) i_assert(submitted == cmd->replies_submitted); - smtp_server_command_remove_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_NEXT); - /* Limit number of consecutive bad commands */ if (is_bad) conn->bad_counter++; diff --git a/src/lib-smtp/smtp-server-connection.c b/src/lib-smtp/smtp-server-connection.c index ad70ad7f3d..3cd79cf0a6 100644 --- a/src/lib-smtp/smtp-server-connection.c +++ b/src/lib-smtp/smtp-server-connection.c @@ -638,10 +638,10 @@ smtp_server_connection_next_reply(struct smtp_server_connection *conn) return FALSE; } - if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY) { - (void)smtp_server_command_next_to_reply(&cmd); + if (!smtp_server_command_next_to_reply(&cmd)) + return FALSE; + if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY) return FALSE; - } i_assert(cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY && array_is_created(&cmd->replies));