From 2814b4731dacb25bed5e58efb5d08c90fe6714b9 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 18 Dec 2017 12:05:59 +0200 Subject: [PATCH] lib-smtp: server: Fix infinite loop when client disconnects in initial state --- src/lib-smtp/smtp-command-parser.c | 2 +- src/lib-smtp/smtp-command-parser.h | 4 ++++ src/lib-smtp/test-smtp-command-parser.c | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lib-smtp/smtp-command-parser.c b/src/lib-smtp/smtp-command-parser.c index f5b170ad88..f42c681302 100644 --- a/src/lib-smtp/smtp-command-parser.c +++ b/src/lib-smtp/smtp-command-parser.c @@ -362,7 +362,7 @@ static int smtp_command_parse(struct smtp_command_parser *parser) i_assert(parser->input->eof); if (parser->input->stream_errno == 0) { if (parser->state.state == SMTP_COMMAND_PARSE_STATE_INIT) - return 0; + ret = -2; smtp_command_parser_error(parser, SMTP_COMMAND_PARSE_ERROR_BROKEN_COMMAND, "Premature end of input"); diff --git a/src/lib-smtp/smtp-command-parser.h b/src/lib-smtp/smtp-command-parser.h index 9fca210a1f..7ea9357ab6 100644 --- a/src/lib-smtp/smtp-command-parser.h +++ b/src/lib-smtp/smtp-command-parser.h @@ -22,6 +22,9 @@ void smtp_command_parser_deinit(struct smtp_command_parser **_parser); void smtp_command_parser_set_stream(struct smtp_command_parser *parser, struct istream *input); +/* Returns 1 if a command was returned, 0 if more data is needed, -1 on error, + -2 if disconnected in SMTP_COMMAND_PARSE_STATE_INIT state. -2 is mainly for + unit tests - it can normally be treated the same as -1. */ int smtp_command_parse_next(struct smtp_command_parser *parser, const char **cmd_name_r, const char **cmd_params_r, enum smtp_command_parse_error *error_code_r, const char **error_r); @@ -33,6 +36,7 @@ struct istream * smtp_command_parse_data_with_dot(struct smtp_command_parser *parser); bool smtp_command_parser_pending_data(struct smtp_command_parser *parser); +/* Returns the same as smtp_command_parse_next() */ int smtp_command_parse_auth_response(struct smtp_command_parser *parser, const char **line_r, enum smtp_command_parse_error *error_code_r, const char **error_r); diff --git a/src/lib-smtp/test-smtp-command-parser.c b/src/lib-smtp/test-smtp-command-parser.c index d4dcc08a45..70e958510b 100644 --- a/src/lib-smtp/test-smtp-command-parser.c +++ b/src/lib-smtp/test-smtp-command-parser.c @@ -85,7 +85,7 @@ static void test_smtp_command_parse_valid(void) while ((ret=smtp_command_parse_next(parser, &cmd_name, &cmd_params, &error_code, &error)) > 0); - test_out_reason("parse success", ret == 0, error); + test_out_reason("parse success", ret == -2, error); if (ret == 0) { /* verify last response only */ @@ -167,7 +167,7 @@ static void test_smtp_command_parse_invalid(void) while ((ret=smtp_command_parse_next(parser, &cmd_name, &cmd_params, &error_code, &error)) > 0); test_out_reason(t_strdup_printf("parse(\"%s\")", - str_sanitize(command_text, 28)), ret < 0, error); + str_sanitize(command_text, 28)), ret == -1, error); test_out_quiet("error code", error_code == test->error_code); @@ -232,7 +232,7 @@ static void test_smtp_auth_response_parse_valid(void) while ((ret=smtp_command_parse_auth_response(parser, &line, &error_code, &error)) > 0); - test_out_reason("parse success", ret == 0, error); + test_out_reason("parse success", ret == -2, error); if (ret == 0) { /* verify last response only */ @@ -302,7 +302,7 @@ static void test_smtp_auth_response_parse_invalid(void) while ((ret=smtp_command_parse_auth_response(parser, &line, &error_code, &error)) > 0); test_out_reason(t_strdup_printf("parse(\"%s\")", - str_sanitize(response_text, 28)), ret < 0, error); + str_sanitize(response_text, 28)), ret == -1, error); test_out_quiet("error code", error_code == test->error_code); -- 2.47.3