]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: Fix infinite loop when client disconnects in initial state
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 18 Dec 2017 10:05:59 +0000 (12:05 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 18 Dec 2017 13:05:29 +0000 (15:05 +0200)
src/lib-smtp/smtp-command-parser.c
src/lib-smtp/smtp-command-parser.h
src/lib-smtp/test-smtp-command-parser.c

index f5b170ad888ad2ffa3d3ccad76cb4b0b69d2a2e5..f42c681302f0ef32d8967f15188673609aa0fbba 100644 (file)
@@ -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");
index 9fca210a1f23cb380e498b11805fe57c90f6b155..7ea9357ab673c4618566f49651791e7a035680f2 100644 (file)
@@ -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);
index d4dcc08a459da30c298d4224e9f02f8dde7794fb..70e958510bec6e128e4507366f01af69cc0339be 100644 (file)
@@ -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);