From eb6ccfb24ba91fac89895ae9256fc96058a94dff Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2020 11:59:24 +0000 Subject: import dovecot-2.3.8-4.el8 --- diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957,10958,10967.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957,10958,10967.patch new file mode 100644 index 0000000..67a810d --- /dev/null +++ b/SOURCES/dovecot-2.3.10-CVE_2020_10957,10958,10967.patch @@ -0,0 +1,1090 @@ +diff -up dovecot-2.3.8/src/lib-smtp/Makefile.am.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/Makefile.am +--- dovecot-2.3.8/src/lib-smtp/Makefile.am.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/Makefile.am 2020-05-29 19:11:53.357162340 +0200 +@@ -72,6 +72,7 @@ pkginc_libdir=$(pkgincludedir) + pkginc_lib_HEADERS = $(headers) + + test_programs = \ ++ test-smtp-syntax \ + test-smtp-address \ + test-smtp-params \ + test-smtp-reply \ +@@ -121,6 +122,10 @@ if BUILD_OPENSSL + test_libs_ssl += ../lib-ssl-iostream/libssl_iostream_openssl.la + endif + ++test_smtp_syntax_SOURCES = test-smtp-syntax.c ++test_smtp_syntax_LDADD = $(test_libs) ++test_smtp_syntax_DEPENDENCIES = $(test_deps) ++ + test_smtp_address_SOURCES = test-smtp-address.c + test_smtp_address_LDFLAGS = -export-dynamic + test_smtp_address_LDADD = $(test_libs) +diff -up dovecot-2.3.8/src/lib-smtp/smtp-address.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-address.c +--- dovecot-2.3.8/src/lib-smtp/smtp-address.c.CVE_2020_10957,10958,10967 2020-05-29 19:11:53.356162354 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-address.c 2020-05-29 19:13:33.310813425 +0200 +@@ -625,13 +625,13 @@ smtp_address_clone(pool_t pool, const st + size_t size, lpsize = 0, dsize = 0; + char *data, *localpart = NULL, *domain = NULL; + +- if (smtp_address_isnull(src)) ++ if (src == NULL) + return NULL; + + /* @UNSAFE */ + + size = sizeof(struct smtp_address); +- if (src->localpart != NULL && *src->localpart != '\0') { ++ if (!smtp_address_isnull(src)) { + lpsize = strlen(src->localpart) + 1; + size = MALLOC_ADD(size, lpsize); + } +@@ -686,7 +686,7 @@ smtp_address_clone_temp(const struct smt + { + struct smtp_address *new; + +- if (smtp_address_isnull(src)) ++ if (src == NULL) + return NULL; + + new = t_new(struct smtp_address, 1); +diff -up dovecot-2.3.8/src/lib-smtp/smtp-address.h.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-address.h +--- dovecot-2.3.8/src/lib-smtp/smtp-address.h.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-address.h 2020-05-29 19:11:53.358162327 +0200 +@@ -122,8 +122,14 @@ smtp_address_equals(const struct smtp_ad + static inline bool ATTR_NULL(1) ATTR_PURE + smtp_address_isnull(const struct smtp_address *address) + { +- return (address == NULL || address->localpart == NULL || +- *address->localpart == '\0'); ++ return (address == NULL || address->localpart == NULL); + } + ++static inline bool ATTR_NULL(1) ATTR_PURE ++smtp_address_is_broken(const struct smtp_address *address) ++{ ++ return (address != NULL && ++ smtp_address_isnull(address) /*&& ++ (address->raw != NULL && *address->raw != '\0')*/); ++} + #endif +diff -up dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-noop.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-noop.c +--- dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-noop.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-noop.c 2020-05-29 19:11:53.358162327 +0200 +@@ -13,11 +13,15 @@ void smtp_server_cmd_noop(struct smtp_se + struct smtp_server_connection *conn = cmd->conn; + struct smtp_server_command *command = cmd->cmd; + const struct smtp_server_callbacks *callbacks = conn->callbacks; ++ const char *param, *error; + int ret; + + /* "NOOP" [ SP String ] CRLF */ +- if (*params != '\0' && smtp_string_parse(params, NULL, NULL) < 0) { +- smtp_server_reply(cmd, 501, "5.5.4", "Invalid parameters"); ++ ret = smtp_string_parse(params, ¶m, &error); ++ if (ret < 0) { ++ smtp_server_reply(cmd, 501, "5.5.4", ++ "Invalid string parameter: %s", ++ error); + return; + } + +diff -up dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-vrfy.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-vrfy.c +--- dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-vrfy.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-server-cmd-vrfy.c 2020-05-29 19:11:53.358162327 +0200 +@@ -17,15 +17,13 @@ void smtp_server_cmd_vrfy(struct smtp_se + int ret; + + /* vrfy = "VRFY" SP String CRLF */ +- if ((ret=smtp_string_parse(params, ¶m, &error)) <= 0) { +- if (ret < 0) { +- smtp_server_reply(cmd, +- 501, "5.5.4", +- "Invalid string parameter: %s", error); +- } else { +- smtp_server_reply(cmd, +- 501, "5.5.4", "Invalid parameters"); +- } ++ ret = smtp_string_parse(params, ¶m, &error); ++ if (ret < 0) { ++ smtp_server_reply(cmd, 501, "5.5.4", ++ "Invalid string parameter: %s", error); ++ return; ++ } else if (ret == 0) { ++ smtp_server_reply(cmd, 501, "5.5.4", "Invalid parameters"); + return; + } + +diff -up dovecot-2.3.8/src/lib-smtp/smtp-server-command.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-server-command.c +--- dovecot-2.3.8/src/lib-smtp/smtp-server-command.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-server-command.c 2020-05-29 19:11:53.358162327 +0200 +@@ -179,14 +179,15 @@ smtp_server_command_new_invalid(struct s + + struct smtp_server_command * + smtp_server_command_new(struct smtp_server_connection *conn, +- const char *name, const char *params) ++ const char *name) + { + struct smtp_server *server = conn->server; +- const struct smtp_server_command_reg *cmd_reg; + struct smtp_server_command *cmd; + + cmd = smtp_server_command_alloc(conn); + cmd->context.name = p_strdup(cmd->context.pool, name); ++ cmd->reg = smtp_server_command_find(server, name); ++ + smtp_server_command_update_event(cmd); + + struct event_passthrough *e = +@@ -194,7 +195,15 @@ smtp_server_command_new(struct smtp_serv + set_name("smtp_server_command_started"); + e_debug(e->event(), "New command"); + +- if ((cmd_reg=smtp_server_command_find(server, name)) == NULL) { ++ return cmd; ++} ++ ++void smtp_server_command_execute(struct smtp_server_command *cmd, ++ const char *params) ++{ ++ struct smtp_server_connection *conn = cmd->context.conn; ++ ++ if (cmd->reg == NULL) { + /* RFC 5321, Section 4.2.4: Reply Code 502 + + Questions have been raised as to when reply code 502 (Command +@@ -207,7 +216,7 @@ smtp_server_command_new(struct smtp_serv + 500, "5.5.1", "Unknown command"); + + } else if (!conn->ssl_secured && conn->set.tls_required && +- (cmd_reg->flags & SMTP_SERVER_CMD_FLAG_PRETLS) == 0) { ++ (cmd->reg->flags & SMTP_SERVER_CMD_FLAG_PRETLS) == 0) { + /* RFC 3207, Section 4: + + A SMTP server that is not publicly referenced may choose to +@@ -226,7 +235,7 @@ smtp_server_command_new(struct smtp_serv + 530, "5.7.0", "TLS required."); + + } else if (!conn->authenticated && !conn->set.auth_optional && +- (cmd_reg->flags & SMTP_SERVER_CMD_FLAG_PREAUTH) == 0) { ++ (cmd->reg->flags & SMTP_SERVER_CMD_FLAG_PREAUTH) == 0) { + /* RFC 4954, Section 6: Status Codes + + 530 5.7.0 Authentication required +@@ -242,16 +251,14 @@ smtp_server_command_new(struct smtp_serv + } else { + struct smtp_server_command *tmp_cmd = cmd; + +- i_assert(cmd_reg->func != NULL); ++ i_assert(cmd->reg->func != NULL); + smtp_server_command_ref(tmp_cmd); +- tmp_cmd->reg = cmd_reg; +- cmd_reg->func(&tmp_cmd->context, params); ++ cmd->reg->func(&tmp_cmd->context, params); + if (tmp_cmd->state == SMTP_SERVER_COMMAND_STATE_NEW) + tmp_cmd->state = SMTP_SERVER_COMMAND_STATE_PROCESSING; + if (!smtp_server_command_unref(&tmp_cmd)) + cmd = NULL; + } +- return cmd; + } + + void smtp_server_command_ref(struct smtp_server_command *cmd) +@@ -389,8 +396,11 @@ bool smtp_server_command_call_hooks(stru + struct smtp_server_command *cmd = *_cmd; + struct smtp_server_command_hook *hook; + +- if (type != SMTP_SERVER_COMMAND_HOOK_DESTROY) ++ if (type != SMTP_SERVER_COMMAND_HOOK_DESTROY) { ++ if (cmd->state >= SMTP_SERVER_COMMAND_STATE_FINISHED) ++ return FALSE; + smtp_server_command_ref(cmd); ++ } + + hook = cmd->hooks_head; + while (hook != NULL) { +diff -up dovecot-2.3.8/src/lib-smtp/smtp-server-connection.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-server-connection.c +--- dovecot-2.3.8/src/lib-smtp/smtp-server-connection.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-server-connection.c 2020-05-29 19:11:53.358162327 +0200 +@@ -293,20 +293,28 @@ smtp_server_connection_handle_command(st + { + struct smtp_server_connection *tmp_conn = conn; + struct smtp_server_command *cmd; ++ bool finished; ++ ++ cmd = smtp_server_command_new(tmp_conn, cmd_name); ++ ++ smtp_server_command_ref(cmd); + + smtp_server_connection_ref(tmp_conn); +- cmd = smtp_server_command_new(tmp_conn, cmd_name, cmd_params); ++ smtp_server_command_execute(cmd, cmd_params); + if (!smtp_server_connection_unref(&tmp_conn)) { + /* the command start callback managed to get this connection + destroyed */ ++ smtp_server_command_unref(&cmd); + return FALSE; + } + +- if (cmd != NULL && conn->command_queue_head == cmd) ++ if (conn->command_queue_head == cmd) + (void)smtp_server_command_next_to_reply(&cmd); + + smtp_server_connection_timeout_update(conn); +- return (cmd == NULL || !cmd->input_locked); ++ ++ finished = !cmd->input_locked; ++ return (!smtp_server_command_unref(&cmd) || finished); + } + + static int +diff -up dovecot-2.3.8/src/lib-smtp/smtp-server-private.h.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-server-private.h +--- dovecot-2.3.8/src/lib-smtp/smtp-server-private.h.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-server-private.h 2020-05-29 19:11:53.358162327 +0200 +@@ -241,8 +241,11 @@ void smtp_server_command_debug(struct sm + struct smtp_server_command * + smtp_server_command_new_invalid(struct smtp_server_connection *conn); + struct smtp_server_command * +-smtp_server_command_new(struct smtp_server_connection *conn, +- const char *name, const char *params); ++smtp_server_command_new(struct smtp_server_connection *conn, const char *name); ++ ++void smtp_server_command_execute(struct smtp_server_command *cmd, ++ const char *params); ++ + void smtp_server_command_ref(struct smtp_server_command *cmd); + bool smtp_server_command_unref(struct smtp_server_command **_cmd); + void smtp_server_command_abort(struct smtp_server_command **_cmd); +diff -up dovecot-2.3.8/src/lib-smtp/smtp-syntax.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/smtp-syntax.c +--- dovecot-2.3.8/src/lib-smtp/smtp-syntax.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-syntax.c 2020-05-29 19:11:53.358162327 +0200 +@@ -17,18 +17,19 @@ int smtp_string_parse(const char *string + const char **value_r, const char **error_r) + { + struct smtp_parser parser; +- int ret; ++ ++ *value_r = NULL; ++ *error_r = NULL; + + if (string == NULL || *string == '\0') { + *value_r = ""; +- return 1; ++ return 0; + } + + smtp_parser_init(&parser, pool_datastack_create(), string); + +- if ((ret=smtp_parser_parse_string(&parser, value_r)) < 0) { +- if (error_r != NULL) +- *error_r = parser.error; ++ if (smtp_parser_parse_string(&parser, value_r) < 0) { ++ *error_r = parser.error; + return -1; + } + if (parser.cur < parser.end) { +@@ -85,20 +86,20 @@ int smtp_xtext_parse(const char *xtext, + { + struct smtp_parser parser; + string_t *value = NULL; +- int ret; ++ ++ *value_r = NULL; ++ *error_r = NULL; + + if (xtext == NULL || *xtext == '\0') { + *value_r = ""; + return 1; + } + +- if (value_r != NULL) +- value = t_str_new(256); ++ value = t_str_new(256); + smtp_parser_init(&parser, pool_datastack_create(), xtext); + +- if ((ret=smtp_parser_parse_xtext(&parser, value)) < 0) { +- if (error_r != NULL) +- *error_r = parser.error; ++ if (smtp_parser_parse_xtext(&parser, value) < 0) { ++ *error_r = parser.error; + return -1; + } + if (parser.cur < parser.end) { +@@ -109,8 +110,7 @@ int smtp_xtext_parse(const char *xtext, + if (value_r != NULL) { + *value_r = str_c(value); + if (strlen(*value_r) != str_len(value)) { +- if (*error_r != NULL) +- *error_r = "Encountered NUL character in xtext"; ++ *error_r = "Encountered NUL character in xtext"; + return -1; + } + } +@@ -249,12 +249,10 @@ static int smtp_parse_ehlo_line(struct s + (i_isalnum(*parser->cur) || *parser->cur == '-')) + parser->cur++; + +- if (key_r != NULL) +- *key_r = p_strdup_until(parser->pool, pbegin, parser->cur); ++ *key_r = p_strdup_until(parser->pool, pbegin, parser->cur); + + if (parser->cur >= parser->end) { +- if (params_r != NULL) +- *params_r = p_new(parser->pool, const char *, 1); ++ *params_r = p_new(parser->pool, const char *, 1); + return 1; + } + if (*parser->cur != ' ') { +@@ -264,18 +262,16 @@ static int smtp_parse_ehlo_line(struct s + parser->cur++; + + pbegin = parser->cur; +- if (params_r != NULL) +- p_array_init(¶ms, parser->pool, 32); ++ p_array_init(¶ms, parser->pool, 32); + while (parser->cur < parser->end) { + if (*parser->cur == ' ') { + if (parser->cur+1 >= parser->end || *(parser->cur+1) == ' ') { + parser->error = "Missing EHLO parameter after ' '"; + return -1; + } +- if (params_r != NULL) { +- param = p_strdup_until(parser->pool, pbegin, parser->cur); +- array_push_back(¶ms, ¶m); +- } ++ param = p_strdup_until(parser->pool, pbegin, ++ parser->cur); ++ array_push_back(¶ms, ¶m); + pbegin = parser->cur + 1; + } else if (!smtp_char_is_ehlo_param(*parser->cur)) { + parser->error = "Unexpected character in EHLO parameter"; +@@ -284,12 +280,10 @@ static int smtp_parse_ehlo_line(struct s + parser->cur++; + } + +- if (params_r != NULL) { +- param = p_strdup_until(parser->pool, pbegin, parser->cur); +- array_push_back(¶ms, ¶m); +- array_append_zero(¶ms); +- *params_r = array_front(¶ms); +- } ++ param = p_strdup_until(parser->pool, pbegin, parser->cur); ++ array_push_back(¶ms, ¶m); ++ array_append_zero(¶ms); ++ *params_r = array_front(¶ms); + return 1; + } + +@@ -297,19 +291,20 @@ int smtp_ehlo_line_parse(const char *ehl + const char *const **params_r, const char **error_r) + { + struct smtp_parser parser; +- int ret; ++ ++ *key_r = NULL; ++ *params_r = NULL; ++ *error_r = NULL; + + if (ehlo_line == NULL || *ehlo_line == '\0') { +- if (error_r != NULL) +- *error_r = "Parameter is empty"; ++ *error_r = "Parameter is empty"; + return -1; + } + + smtp_parser_init(&parser, pool_datastack_create(), ehlo_line); + +- if ((ret=smtp_parse_ehlo_line(&parser, key_r, params_r)) <= 0) { +- if (error_r != NULL) +- *error_r = parser.error; ++ if (smtp_parse_ehlo_line(&parser, key_r, params_r) <= 0) { ++ *error_r = parser.error; + return -1; + } + return 1; +diff -up dovecot-2.3.8/src/lib-smtp/test-smtp-server-errors.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/test-smtp-server-errors.c +--- dovecot-2.3.8/src/lib-smtp/test-smtp-server-errors.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/test-smtp-server-errors.c 2020-05-29 19:11:53.359162313 +0200 +@@ -574,6 +574,174 @@ static void test_bad_command(void) + } + + /* ++ * Many bad commands ++ */ ++ ++/* client */ ++ ++struct _many_bad_commands_client { ++ struct smtp_reply_parser *parser; ++ unsigned int reply; ++ bool replied:1; ++}; ++ ++static void ++test_many_bad_commands_client_input(struct client_connection *conn) ++{ ++ struct _many_bad_commands_client *ctx = conn->context; ++ struct smtp_reply *reply; ++ const char *error; ++ int ret; ++ ++ while ((ret=smtp_reply_parse_next(ctx->parser, FALSE, ++ &reply, &error)) > 0) { ++ if (debug) ++ i_debug("REPLY: %s", smtp_reply_log(reply)); ++ ++ switch (ctx->reply++) { ++ /* greeting */ ++ case 0: ++ i_assert(reply->status == 220); ++ break; ++ /* bad command reply */ ++ case 1: case 2: case 3: case 4: case 5: ++ case 6: case 7: case 8: case 9: case 10: ++ i_assert(reply->status == 500); ++ break; ++ case 11: ++ i_assert(reply->status == 421); ++ ctx->replied = TRUE; ++ io_loop_stop(ioloop); ++ connection_disconnect(&conn->conn); ++ return; ++ default: ++ i_unreached(); ++ } ++ } ++ ++ i_assert(ret >= 0); ++} ++ ++static void ++test_many_bad_commands_client_connected(struct client_connection *conn) ++{ ++ struct _many_bad_commands_client *ctx; ++ ++ ctx = p_new(conn->pool, struct _many_bad_commands_client, 1); ++ ctx->parser = smtp_reply_parser_init(conn->conn.input, (size_t)-1); ++ conn->context = ctx; ++ ++ switch (client_index) { ++ case 0: ++ o_stream_nsend_str(conn->conn.output, ++ "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); ++ break; ++ case 1: ++ o_stream_nsend_str(conn->conn.output, ++ "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\ng\r\nh\r\n" ++ "i\r\nj\r\nk\r\nl\r\nm\r\nn\r\no\r\np\r\n"); ++ break; ++ default: ++ i_unreached(); ++ } ++} ++ ++static void ++test_many_bad_commands_client_deinit(struct client_connection *conn) ++{ ++ struct _many_bad_commands_client *ctx = conn->context; ++ ++ i_assert(ctx->replied); ++ smtp_reply_parser_deinit(&ctx->parser); ++} ++ ++static void test_client_many_bad_commands(unsigned int index) ++{ ++ test_client_input = test_many_bad_commands_client_input; ++ test_client_connected = test_many_bad_commands_client_connected; ++ test_client_deinit = test_many_bad_commands_client_deinit; ++ test_client_run(index); ++} ++ ++/* server */ ++ ++struct _many_bad_commands { ++ struct istream *payload_input; ++ struct io *io; ++ ++ bool serviced:1; ++}; ++ ++static void ++test_server_many_bad_commands_disconnect(void *context ATTR_UNUSED, ++ const char *reason) ++{ ++ if (debug) ++ i_debug("Disconnect: %s", reason); ++ io_loop_stop(ioloop); ++} ++ ++static int ++test_server_many_bad_commands_helo( ++ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_cmd_helo *data ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static int ++test_server_many_bad_commands_rcpt( ++ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_recipient *rcpt ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static int ++test_server_many_bad_commands_data_begin( ++ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_transaction *trans ATTR_UNUSED, ++ struct istream *data_input ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static void test_server_many_bad_commands ++(const struct smtp_server_settings *server_set) ++{ ++ server_callbacks.conn_disconnect = ++ test_server_many_bad_commands_disconnect; ++ ++ server_callbacks.conn_cmd_helo = ++ test_server_many_bad_commands_helo; ++ server_callbacks.conn_cmd_rcpt = ++ test_server_many_bad_commands_rcpt; ++ server_callbacks.conn_cmd_data_begin = ++ test_server_many_bad_commands_data_begin; ++ test_server_run(server_set); ++} ++ ++/* test */ ++ ++static void test_many_bad_commands(void) ++{ ++ struct smtp_server_settings smtp_server_set; ++ ++ test_server_defaults(&smtp_server_set); ++ smtp_server_set.max_client_idle_time_msecs = 1000; ++ smtp_server_set.max_bad_commands = 10; ++ ++ test_begin("many bad commands"); ++ test_run_client_server(&smtp_server_set, ++ test_server_many_bad_commands, ++ test_client_many_bad_commands, 2); ++ test_end(); ++} ++ ++/* + * Long command + */ + +@@ -1274,6 +1442,316 @@ static void test_bad_rcpt(void) + } + + /* ++ * Bad VRFY ++ */ ++ ++/* client */ ++ ++struct _bad_vrfy_client { ++ struct smtp_reply_parser *parser; ++ unsigned int reply; ++ ++ bool replied:1; ++}; ++ ++static void ++test_bad_vrfy_client_input(struct client_connection *conn) ++{ ++ struct _bad_vrfy_client *ctx = conn->context; ++ struct smtp_reply *reply; ++ const char *error; ++ int ret; ++ ++ while ((ret = smtp_reply_parse_next(ctx->parser, FALSE, ++ &reply, &error)) > 0) { ++ if (debug) ++ i_debug("REPLY: %s", smtp_reply_log(reply)); ++ ++ switch (ctx->reply++) { ++ case 0: /* greeting */ ++ i_assert(reply->status == 220); ++ break; ++ case 1: /* bad command reply */ ++ switch (client_index) { ++ case 0: case 1: case 2: ++ i_assert(reply->status == 501); ++ break; ++ case 3: ++ i_assert(smtp_reply_is_success(reply)); ++ break; ++ default: ++ i_unreached(); ++ } ++ ctx->replied = TRUE; ++ io_loop_stop(ioloop); ++ connection_disconnect(&conn->conn); ++ return; ++ default: ++ i_unreached(); ++ } ++ } ++ ++ i_assert(ret == 0); ++} ++ ++static void ++test_bad_vrfy_client_connected(struct client_connection *conn) ++{ ++ struct _bad_vrfy_client *ctx; ++ ++ ctx = p_new(conn->pool, struct _bad_vrfy_client, 1); ++ ctx->parser = smtp_reply_parser_init(conn->conn.input, (size_t)-1); ++ conn->context = ctx; ++ ++ switch (client_index) { ++ case 0: ++ o_stream_nsend_str(conn->conn.output, ++ "VRFY\r\n"); ++ break; ++ case 1: ++ o_stream_nsend_str(conn->conn.output, ++ "VRFY \"hendrik\r\n"); ++ break; ++ case 2: ++ o_stream_nsend_str(conn->conn.output, ++ "VRFY hen\"drik\r\n"); ++ break; ++ case 3: ++ o_stream_nsend_str(conn->conn.output, ++ "VRFY \"hendrik\"\r\n"); ++ break; ++ default: ++ i_unreached(); ++ } ++} ++ ++static void ++test_bad_vrfy_client_deinit(struct client_connection *conn) ++{ ++ struct _bad_vrfy_client *ctx = conn->context; ++ ++ i_assert(ctx->replied); ++ smtp_reply_parser_deinit(&ctx->parser); ++} ++ ++static void test_client_bad_vrfy(unsigned int index) ++{ ++ test_client_input = test_bad_vrfy_client_input; ++ test_client_connected = test_bad_vrfy_client_connected; ++ test_client_deinit = test_bad_vrfy_client_deinit; ++ test_client_run(index); ++} ++ ++/* server */ ++ ++static void ++test_server_bad_vrfy_disconnect(void *context ATTR_UNUSED, const char *reason) ++{ ++ if (debug) ++ i_debug("Disconnect: %s", reason); ++} ++ ++static int ++test_server_bad_vrfy_rcpt(void *conn_ctx ATTR_UNUSED, ++ struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_recipient *rcpt ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static int ++test_server_bad_vrfy_data_begin( ++ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_transaction *trans ATTR_UNUSED, ++ struct istream *data_input ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static void ++test_server_bad_vrfy(const struct smtp_server_settings *server_set) ++{ ++ server_callbacks.conn_disconnect = test_server_bad_vrfy_disconnect; ++ ++ server_callbacks.conn_cmd_rcpt = test_server_bad_vrfy_rcpt; ++ server_callbacks.conn_cmd_data_begin = test_server_bad_vrfy_data_begin; ++ test_server_run(server_set); ++} ++ ++/* test */ ++ ++static void test_bad_vrfy(void) ++{ ++ struct smtp_server_settings smtp_server_set; ++ ++ test_server_defaults(&smtp_server_set); ++ smtp_server_set.max_client_idle_time_msecs = 1000; ++ ++ test_begin("bad VRFY"); ++ test_run_client_server(&smtp_server_set, ++ test_server_bad_vrfy, ++ test_client_bad_vrfy, 4); ++ test_end(); ++} ++ ++/* ++ * Bad NOOP ++ */ ++ ++/* client */ ++ ++struct _bad_noop_client { ++ struct smtp_reply_parser *parser; ++ unsigned int reply; ++ ++ bool replied:1; ++}; ++ ++static void ++test_bad_noop_client_input(struct client_connection *conn) ++{ ++ struct _bad_noop_client *ctx = conn->context; ++ struct smtp_reply *reply; ++ const char *error; ++ int ret; ++ ++ while ((ret = smtp_reply_parse_next(ctx->parser, FALSE, ++ &reply, &error)) > 0) { ++ if (debug) ++ i_debug("REPLY: %s", smtp_reply_log(reply)); ++ ++ switch (ctx->reply++) { ++ case 0: /* greeting */ ++ i_assert(reply->status == 220); ++ break; ++ case 1: /* bad command reply */ ++ switch (client_index) { ++ case 1: case 2: ++ i_assert(reply->status == 501); ++ break; ++ case 0: case 3: ++ i_assert(smtp_reply_is_success(reply)); ++ break; ++ default: ++ i_unreached(); ++ } ++ ctx->replied = TRUE; ++ io_loop_stop(ioloop); ++ connection_disconnect(&conn->conn); ++ return; ++ default: ++ i_unreached(); ++ } ++ } ++ ++ i_assert(ret == 0); ++} ++ ++static void ++test_bad_noop_client_connected(struct client_connection *conn) ++{ ++ struct _bad_noop_client *ctx; ++ ++ ctx = p_new(conn->pool, struct _bad_noop_client, 1); ++ ctx->parser = smtp_reply_parser_init(conn->conn.input, (size_t)-1); ++ conn->context = ctx; ++ ++ switch (client_index) { ++ case 0: ++ o_stream_nsend_str(conn->conn.output, ++ "NOOP\r\n"); ++ break; ++ case 1: ++ o_stream_nsend_str(conn->conn.output, ++ "NOOP \"frop\r\n"); ++ break; ++ case 2: ++ o_stream_nsend_str(conn->conn.output, ++ "NOOP fr\"op\r\n"); ++ break; ++ case 3: ++ o_stream_nsend_str(conn->conn.output, ++ "NOOP \"frop\"\r\n"); ++ break; ++ default: ++ i_unreached(); ++ } ++} ++ ++static void ++test_bad_noop_client_deinit(struct client_connection *conn) ++{ ++ struct _bad_noop_client *ctx = conn->context; ++ ++ i_assert(ctx->replied); ++ smtp_reply_parser_deinit(&ctx->parser); ++} ++ ++static void test_client_bad_noop(unsigned int index) ++{ ++ test_client_input = test_bad_noop_client_input; ++ test_client_connected = test_bad_noop_client_connected; ++ test_client_deinit = test_bad_noop_client_deinit; ++ test_client_run(index); ++} ++ ++/* server */ ++ ++static void ++test_server_bad_noop_disconnect(void *context ATTR_UNUSED, const char *reason) ++{ ++ if (debug) ++ i_debug("Disconnect: %s", reason); ++} ++ ++static int ++test_server_bad_noop_rcpt(void *conn_ctx ATTR_UNUSED, ++ struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_recipient *rcpt ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static int ++test_server_bad_noop_data_begin( ++ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, ++ struct smtp_server_transaction *trans ATTR_UNUSED, ++ struct istream *data_input ATTR_UNUSED) ++{ ++ test_assert(FALSE); ++ return 1; ++} ++ ++static void ++test_server_bad_noop(const struct smtp_server_settings *server_set) ++{ ++ server_callbacks.conn_disconnect = test_server_bad_noop_disconnect; ++ ++ server_callbacks.conn_cmd_rcpt = test_server_bad_noop_rcpt; ++ server_callbacks.conn_cmd_data_begin = test_server_bad_noop_data_begin; ++ test_server_run(server_set); ++} ++ ++/* test */ ++ ++static void test_bad_noop(void) ++{ ++ struct smtp_server_settings smtp_server_set; ++ ++ test_server_defaults(&smtp_server_set); ++ smtp_server_set.max_client_idle_time_msecs = 1000; ++ ++ test_begin("bad NOOP"); ++ test_run_client_server(&smtp_server_set, ++ test_server_bad_noop, ++ test_client_bad_noop, 4); ++ test_end(); ++} ++ ++/* + * MAIL workarounds + */ + +@@ -2023,11 +2501,14 @@ static void (*const test_functions[])(vo + test_slow_client, + test_hanging_command_payload, + test_bad_command, ++ test_many_bad_commands, + test_long_command, + test_big_data, + test_bad_ehlo, + test_bad_mail, + test_bad_rcpt, ++ test_bad_vrfy, ++ test_bad_noop, + test_mail_workarounds, + test_rcpt_workarounds, + test_too_many_recipients, +diff -up dovecot-2.3.8/src/lib-smtp/test-smtp-syntax.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lib-smtp/test-smtp-syntax.c +--- dovecot-2.3.8/src/lib-smtp/test-smtp-syntax.c.CVE_2020_10957,10958,10967 2020-05-29 19:11:53.359162313 +0200 ++++ dovecot-2.3.8/src/lib-smtp/test-smtp-syntax.c 2020-05-29 19:11:53.359162313 +0200 +@@ -0,0 +1,150 @@ ++/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */ ++ ++#include "lib.h" ++#include "str.h" ++#include "str-sanitize.h" ++#include "test-common.h" ++#include "smtp-syntax.h" ++ ++/* ++ * Valid string parse tests ++ */ ++ ++struct valid_string_parse_test { ++ const char *input, *parsed, *output; ++}; ++ ++static const struct valid_string_parse_test ++valid_string_parse_tests[] = { ++ { ++ .input = "", ++ .parsed = "", ++ }, ++ { ++ .input = "atom", ++ .parsed = "atom", ++ }, ++ { ++ .input = "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "0123456789!#$%&'*+-/=?^_`{|}~", ++ .parsed = "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "0123456789!#$%&'*+-/=?^_`{|}~", ++ }, ++ { ++ .input = "\"quoted-string\"", ++ .parsed = "quoted-string", ++ .output = "quoted-string", ++ }, ++ { ++ .input = "\"quoted \\\"string\\\"\"", ++ .parsed = "quoted \"string\"", ++ }, ++ { ++ .input = "\"quoted \\\\string\\\\\"", ++ .parsed = "quoted \\string\\", ++ }, ++}; ++ ++static const unsigned int valid_string_parse_test_count = ++ N_ELEMENTS(valid_string_parse_tests); ++ ++static void test_smtp_string_parse_valid(void) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < valid_string_parse_test_count; i++) T_BEGIN { ++ const struct valid_string_parse_test *test = ++ &valid_string_parse_tests[i]; ++ const char *parsed, *error = NULL; ++ int ret; ++ ++ ret = smtp_string_parse(test->input, &parsed, &error); ++ ++ test_begin(t_strdup_printf("smtp string valid [%d]", i)); ++ test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), ++ ret >= 0, error); ++ test_assert(ret != 0 || *test->input == '\0'); ++ ++ if (!test_has_failed()) { ++ string_t *encoded; ++ const char *output; ++ ++ test_out(t_strdup_printf("parsed = \"%s\"", parsed), ++ null_strcmp(parsed, test->parsed) == 0); ++ ++ encoded = t_str_new(255); ++ smtp_string_write(encoded, parsed); ++ output = (test->output == NULL ? ++ test->input : test->output); ++ test_out(t_strdup_printf("write() = \"%s\"", ++ str_c(encoded)), ++ strcmp(str_c(encoded), output) == 0); ++ } ++ test_end(); ++ } T_END; ++} ++ ++/* ++ * Invalid string parse tests ++ */ ++ ++struct invalid_string_parse_test { ++ const char *input; ++}; ++ ++static const struct invalid_string_parse_test ++invalid_string_parse_tests[] = { ++ { ++ .input = " ", ++ }, ++ { ++ .input = "\\", ++ }, ++ { ++ .input = "\"", ++ }, ++ { ++ .input = "\"aa", ++ }, ++ { ++ .input = "aa\"", ++ }, ++}; ++ ++static const unsigned int invalid_string_parse_test_count = ++ N_ELEMENTS(invalid_string_parse_tests); ++ ++static void test_smtp_string_parse_invalid(void) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < invalid_string_parse_test_count; i++) T_BEGIN { ++ const struct invalid_string_parse_test *test = ++ &invalid_string_parse_tests[i]; ++ const char *parsed, *error; ++ int ret; ++ ++ ret = smtp_string_parse(test->input, &parsed, &error); ++ ++ test_begin(t_strdup_printf("smtp string invalid [%d]", i)); ++ test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), ++ ret < 0, error); ++ test_end(); ++ } T_END; ++} ++ ++/* ++ * Tests ++ */ ++ ++int main(void) ++{ ++ static void (*test_functions[])(void) = { ++ test_smtp_string_parse_valid, ++ test_smtp_string_parse_invalid, ++ NULL ++ }; ++ return test_run(test_functions); ++} +diff -up dovecot-2.3.8/src/lmtp/lmtp-commands.c.CVE_2020_10957,10958,10967 dovecot-2.3.8/src/lmtp/lmtp-commands.c +--- dovecot-2.3.8/src/lmtp/lmtp-commands.c.CVE_2020_10957,10958,10967 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lmtp/lmtp-commands.c 2020-05-29 19:11:53.359162313 +0200 +@@ -66,10 +66,18 @@ int client_default_cmd_rcpt(struct clien + char delim = '\0'; + int ret; + ++ i_assert(!smtp_address_isnull(rcpt->path)); ++ if (*rcpt->path->localpart == '\0' && rcpt->path->domain == NULL) { ++ smtp_server_recipient_reply( ++ rcpt, 550, "5.1.1", ++ "Unacceptable TO: Empty path not allowed"); ++ return -1; ++ } + + smtp_address_detail_parse_temp( + client->unexpanded_lda_set->recipient_delimiter, + rcpt->path, &username, &delim, &detail); ++ i_assert(*username != '\0'); + + /* Make user name and detail available in the recipient event. The + mail_user event (for local delivery) also adds the user field, but diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p1.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p1.patch deleted file mode 100644 index 70adc9a..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p1.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 606724bd528b92347dce580d3ab48fc1e3c2f4d7 Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 20:57:03 +0100 -Subject: [PATCH] lib-smtp: smtp-syntax - Do not allow NULL return parameters - for smtp_string_parse(). - ---- - src/lib-smtp/smtp-server-cmd-noop.c | 8 ++++++-- - src/lib-smtp/smtp-syntax.c | 9 +++++---- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/src/lib-smtp/smtp-server-cmd-noop.c b/src/lib-smtp/smtp-server-cmd-noop.c -index 4986f800c8..550d709eab 100644 ---- a/src/lib-smtp/smtp-server-cmd-noop.c -+++ b/src/lib-smtp/smtp-server-cmd-noop.c -@@ -13,11 +13,15 @@ void smtp_server_cmd_noop(struct smtp_server_cmd_ctx *cmd, - struct smtp_server_connection *conn = cmd->conn; - struct smtp_server_command *command = cmd->cmd; - const struct smtp_server_callbacks *callbacks = conn->callbacks; -+ const char *param, *error; - int ret; - - /* "NOOP" [ SP String ] CRLF */ -- if (*params != '\0' && smtp_string_parse(params, NULL, NULL) < 0) { -- smtp_server_reply(cmd, 501, "5.5.4", "Invalid parameters"); -+ ret = smtp_string_parse(params, ¶m, &error); -+ if (ret < 0) { -+ smtp_server_reply(cmd, 501, "5.5.4", -+ "Invalid string parameter: %s", -+ error); - return; - } - -diff --git a/src/lib-smtp/smtp-syntax.c b/src/lib-smtp/smtp-syntax.c -index 5d22445f72..6826682af1 100644 ---- a/src/lib-smtp/smtp-syntax.c -+++ b/src/lib-smtp/smtp-syntax.c -@@ -17,7 +17,9 @@ int smtp_string_parse(const char *string, - const char **value_r, const char **error_r) - { - struct smtp_parser parser; -- int ret; -+ -+ *value_r = NULL; -+ *error_r = NULL; - - if (string == NULL || *string == '\0') { - *value_r = ""; -@@ -26,9 +28,8 @@ int smtp_string_parse(const char *string, - - smtp_parser_init(&parser, pool_datastack_create(), string); - -- if ((ret=smtp_parser_parse_string(&parser, value_r)) < 0) { -- if (error_r != NULL) -- *error_r = parser.error; -+ if (smtp_parser_parse_string(&parser, value_r) < 0) { -+ *error_r = parser.error; - return -1; - } - if (parser.cur < parser.end) { diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p2.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p2.patch deleted file mode 100644 index 8aa5f8a..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p2.patch +++ /dev/null @@ -1,51 +0,0 @@ -From aedb205c79395de77127fb7166b29b09319df23c Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 21:11:01 +0100 -Subject: [PATCH] lib-smtp: smtp-syntax - Do not allow NULL return parameters - for smtp_xtext_parse(). - ---- - src/lib-smtp/smtp-syntax.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/src/lib-smtp/smtp-syntax.c b/src/lib-smtp/smtp-syntax.c -index 6826682af1..0b0a91ce07 100644 ---- a/src/lib-smtp/smtp-syntax.c -+++ b/src/lib-smtp/smtp-syntax.c -@@ -86,20 +86,20 @@ int smtp_xtext_parse(const char *xtext, - { - struct smtp_parser parser; - string_t *value = NULL; -- int ret; -+ -+ *value_r = NULL; -+ *error_r = NULL; - - if (xtext == NULL || *xtext == '\0') { - *value_r = ""; - return 1; - } - -- if (value_r != NULL) -- value = t_str_new(256); -+ value = t_str_new(256); - smtp_parser_init(&parser, pool_datastack_create(), xtext); - -- if ((ret=smtp_parser_parse_xtext(&parser, value)) < 0) { -- if (error_r != NULL) -- *error_r = parser.error; -+ if (smtp_parser_parse_xtext(&parser, value) < 0) { -+ *error_r = parser.error; - return -1; - } - if (parser.cur < parser.end) { -@@ -110,8 +110,7 @@ int smtp_xtext_parse(const char *xtext, - if (value_r != NULL) { - *value_r = str_c(value); - if (strlen(*value_r) != str_len(value)) { -- if (*error_r != NULL) -- *error_r = "Encountered NUL character in xtext"; -+ *error_r = "Encountered NUL character in xtext"; - return -1; - } - } diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p3.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p3.patch deleted file mode 100644 index c5a2fd7..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p3.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 874817b169d19a4ae51d80ad5798a396bfe90136 Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 21:14:34 +0100 -Subject: [PATCH] lib-smtp: smtp-syntax - Do not allow NULL return parameters - for smtp_ehlo_line_parse(). - ---- - src/lib-smtp/smtp-syntax.c | 39 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 22 deletions(-) - -diff --git a/src/lib-smtp/smtp-syntax.c b/src/lib-smtp/smtp-syntax.c -index 0b0a91ce07..5cca6c40fd 100644 ---- a/src/lib-smtp/smtp-syntax.c -+++ b/src/lib-smtp/smtp-syntax.c -@@ -249,12 +249,10 @@ static int smtp_parse_ehlo_line(struct smtp_parser *parser, - (i_isalnum(*parser->cur) || *parser->cur == '-')) - parser->cur++; - -- if (key_r != NULL) -- *key_r = p_strdup_until(parser->pool, pbegin, parser->cur); -+ *key_r = p_strdup_until(parser->pool, pbegin, parser->cur); - - if (parser->cur >= parser->end) { -- if (params_r != NULL) -- *params_r = p_new(parser->pool, const char *, 1); -+ *params_r = p_new(parser->pool, const char *, 1); - return 1; - } - if (*parser->cur != ' ') { -@@ -264,18 +262,16 @@ static int smtp_parse_ehlo_line(struct smtp_parser *parser, - parser->cur++; - - pbegin = parser->cur; -- if (params_r != NULL) -- p_array_init(¶ms, parser->pool, 32); -+ p_array_init(¶ms, parser->pool, 32); - while (parser->cur < parser->end) { - if (*parser->cur == ' ') { - if (parser->cur+1 >= parser->end || *(parser->cur+1) == ' ') { - parser->error = "Missing EHLO parameter after ' '"; - return -1; - } -- if (params_r != NULL) { -- param = p_strdup_until(parser->pool, pbegin, parser->cur); -- array_push_back(¶ms, ¶m); -- } -+ param = p_strdup_until(parser->pool, pbegin, -+ parser->cur); -+ array_push_back(¶ms, ¶m); - pbegin = parser->cur + 1; - } else if (!smtp_char_is_ehlo_param(*parser->cur)) { - parser->error = "Unexpected character in EHLO parameter"; -@@ -284,12 +280,10 @@ static int smtp_parse_ehlo_line(struct smtp_parser *parser, - parser->cur++; - } - -- if (params_r != NULL) { -- param = p_strdup_until(parser->pool, pbegin, parser->cur); -- array_push_back(¶ms, ¶m); -- array_append_zero(¶ms); -- *params_r = array_front(¶ms); -- } -+ param = p_strdup_until(parser->pool, pbegin, parser->cur); -+ array_push_back(¶ms, ¶m); -+ array_append_zero(¶ms); -+ *params_r = array_front(¶ms); - return 1; - } - -@@ -297,19 +291,20 @@ int smtp_ehlo_line_parse(const char *ehlo_line, const char **key_r, - const char *const **params_r, const char **error_r) - { - struct smtp_parser parser; -- int ret; -+ -+ *key_r = NULL; -+ *params_r = NULL; -+ *error_r = NULL; - - if (ehlo_line == NULL || *ehlo_line == '\0') { -- if (error_r != NULL) -- *error_r = "Parameter is empty"; -+ *error_r = "Parameter is empty"; - return -1; - } - - smtp_parser_init(&parser, pool_datastack_create(), ehlo_line); - -- if ((ret=smtp_parse_ehlo_line(&parser, key_r, params_r)) <= 0) { -- if (error_r != NULL) -- *error_r = parser.error; -+ if (smtp_parse_ehlo_line(&parser, key_r, params_r) <= 0) { -+ *error_r = parser.error; - return -1; - } - return 1; diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p4.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p4.patch deleted file mode 100644 index 70a1251..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p4.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 5efeccc10beccbf8d7700adec1278f97d416cbc6 Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 22:42:15 +0100 -Subject: [PATCH] lib-smtp: smtp-syntax - Return 0 for smtp_string_parse() with - empty input. - -This is what the current users of this function actually expect. ---- - src/lib-smtp/smtp-syntax.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lib-smtp/smtp-syntax.c b/src/lib-smtp/smtp-syntax.c -index 5cca6c40fd..cf86f87336 100644 ---- a/src/lib-smtp/smtp-syntax.c -+++ b/src/lib-smtp/smtp-syntax.c -@@ -23,7 +23,7 @@ int smtp_string_parse(const char *string, - - if (string == NULL || *string == '\0') { - *value_r = ""; -- return 1; -+ return 0; - } - - smtp_parser_init(&parser, pool_datastack_create(), string); diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p5.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p5.patch deleted file mode 100644 index 271c79f..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p5.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 363af76535f8137ba76d9de7935023bab9a045ef Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 22:24:20 +0100 -Subject: [PATCH] lib-smtp: Add tests for smtp_string_parse() and - smtp_string_write(). - ---- - src/lib-smtp/Makefile.am | 5 ++ - src/lib-smtp/test-smtp-syntax.c | 150 ++++++++++++++++++++++++++++++++ - 2 files changed, 155 insertions(+) - create mode 100644 src/lib-smtp/test-smtp-syntax.c - -diff --git a/src/lib-smtp/Makefile.am b/src/lib-smtp/Makefile.am -index b03761df8b..d87cd4e6d3 100644 ---- a/src/lib-smtp/Makefile.am -+++ b/src/lib-smtp/Makefile.am -@@ -72,6 +72,7 @@ pkginc_libdir=$(pkgincludedir) - pkginc_lib_HEADERS = $(headers) - - test_programs = \ -+ test-smtp-syntax \ - test-smtp-address \ - test-smtp-params \ - test-smtp-reply \ -@@ -121,6 +122,10 @@ if BUILD_OPENSSL - test_libs_ssl += ../lib-ssl-iostream/libssl_iostream_openssl.la - endif - -+test_smtp_syntax_SOURCES = test-smtp-syntax.c -+test_smtp_syntax_LDADD = $(test_libs) -+test_smtp_syntax_DEPENDENCIES = $(test_deps) -+ - test_smtp_address_SOURCES = test-smtp-address.c - test_smtp_address_LDFLAGS = -export-dynamic - test_smtp_address_LDADD = $(test_libs) -diff --git a/src/lib-smtp/test-smtp-syntax.c b/src/lib-smtp/test-smtp-syntax.c -new file mode 100644 -index 0000000000..735cd01220 ---- /dev/null -+++ b/src/lib-smtp/test-smtp-syntax.c -@@ -0,0 +1,150 @@ -+/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */ -+ -+#include "lib.h" -+#include "str.h" -+#include "str-sanitize.h" -+#include "test-common.h" -+#include "smtp-syntax.h" -+ -+/* -+ * Valid string parse tests -+ */ -+ -+struct valid_string_parse_test { -+ const char *input, *parsed, *output; -+}; -+ -+static const struct valid_string_parse_test -+valid_string_parse_tests[] = { -+ { -+ .input = "", -+ .parsed = "", -+ }, -+ { -+ .input = "atom", -+ .parsed = "atom", -+ }, -+ { -+ .input = "abcdefghijklmnopqrstuvwxyz" -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -+ "0123456789!#$%&'*+-/=?^_`{|}~", -+ .parsed = "abcdefghijklmnopqrstuvwxyz" -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -+ "0123456789!#$%&'*+-/=?^_`{|}~", -+ }, -+ { -+ .input = "\"quoted-string\"", -+ .parsed = "quoted-string", -+ .output = "quoted-string", -+ }, -+ { -+ .input = "\"quoted \\\"string\\\"\"", -+ .parsed = "quoted \"string\"", -+ }, -+ { -+ .input = "\"quoted \\\\string\\\\\"", -+ .parsed = "quoted \\string\\", -+ }, -+}; -+ -+static const unsigned int valid_string_parse_test_count = -+ N_ELEMENTS(valid_string_parse_tests); -+ -+static void test_smtp_string_parse_valid(void) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < valid_string_parse_test_count; i++) T_BEGIN { -+ const struct valid_string_parse_test *test = -+ &valid_string_parse_tests[i]; -+ const char *parsed, *error = NULL; -+ int ret; -+ -+ ret = smtp_string_parse(test->input, &parsed, &error); -+ -+ test_begin(t_strdup_printf("smtp string valid [%d]", i)); -+ test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), -+ ret >= 0, error); -+ test_assert(ret != 0 || *test->input == '\0'); -+ -+ if (!test_has_failed()) { -+ string_t *encoded; -+ const char *output; -+ -+ test_out(t_strdup_printf("parsed = \"%s\"", parsed), -+ null_strcmp(parsed, test->parsed) == 0); -+ -+ encoded = t_str_new(255); -+ smtp_string_write(encoded, parsed); -+ output = (test->output == NULL ? -+ test->input : test->output); -+ test_out(t_strdup_printf("write() = \"%s\"", -+ str_c(encoded)), -+ strcmp(str_c(encoded), output) == 0); -+ } -+ test_end(); -+ } T_END; -+} -+ -+/* -+ * Invalid string parse tests -+ */ -+ -+struct invalid_string_parse_test { -+ const char *input; -+}; -+ -+static const struct invalid_string_parse_test -+invalid_string_parse_tests[] = { -+ { -+ .input = " ", -+ }, -+ { -+ .input = "\\", -+ }, -+ { -+ .input = "\"", -+ }, -+ { -+ .input = "\"aa", -+ }, -+ { -+ .input = "aa\"", -+ }, -+}; -+ -+static const unsigned int invalid_string_parse_test_count = -+ N_ELEMENTS(invalid_string_parse_tests); -+ -+static void test_smtp_string_parse_invalid(void) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < invalid_string_parse_test_count; i++) T_BEGIN { -+ const struct invalid_string_parse_test *test = -+ &invalid_string_parse_tests[i]; -+ const char *parsed, *error; -+ int ret; -+ -+ ret = smtp_string_parse(test->input, &parsed, &error); -+ -+ test_begin(t_strdup_printf("smtp string invalid [%d]", i)); -+ test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), -+ ret < 0, error); -+ test_end(); -+ } T_END; -+} -+ -+/* -+ * Tests -+ */ -+ -+int main(void) -+{ -+ static void (*test_functions[])(void) = { -+ test_smtp_string_parse_valid, -+ test_smtp_string_parse_invalid, -+ NULL -+ }; -+ return test_run(test_functions); -+} diff --git a/SOURCES/dovecot-2.3.10-CVE_2020_10957p6.patch b/SOURCES/dovecot-2.3.10-CVE_2020_10957p6.patch deleted file mode 100644 index cffe0cf..0000000 --- a/SOURCES/dovecot-2.3.10-CVE_2020_10957p6.patch +++ /dev/null @@ -1,340 +0,0 @@ -From f206dc478d1b22183f645ea8c98ffe3712e106b2 Mon Sep 17 00:00:00 2001 -From: Stephan Bosch -Date: Tue, 24 Mar 2020 22:33:45 +0100 -Subject: [PATCH] lib-smtp: test-smtp-server-errors - Add tests for VRFY and - NOOP commands with invalid parameters. - ---- - src/lib-smtp/test-smtp-server-errors.c | 312 +++++++++++++++++++++++++ - 1 file changed, 312 insertions(+) - -diff --git a/src/lib-smtp/test-smtp-server-errors.c b/src/lib-smtp/test-smtp-server-errors.c -index 759c332d88..13d3b97def 100644 ---- a/src/lib-smtp/test-smtp-server-errors.c -+++ b/src/lib-smtp/test-smtp-server-errors.c -@@ -1273,6 +1273,316 @@ static void test_bad_rcpt(void) - test_end(); - } - -+/* -+ * Bad VRFY -+ */ -+ -+/* client */ -+ -+struct _bad_vrfy_client { -+ struct smtp_reply_parser *parser; -+ unsigned int reply; -+ -+ bool replied:1; -+}; -+ -+static void -+test_bad_vrfy_client_input(struct client_connection *conn) -+{ -+ struct _bad_vrfy_client *ctx = conn->context; -+ struct smtp_reply *reply; -+ const char *error; -+ int ret; -+ -+ while ((ret = smtp_reply_parse_next(ctx->parser, FALSE, -+ &reply, &error)) > 0) { -+ if (debug) -+ i_debug("REPLY: %s", smtp_reply_log(reply)); -+ -+ switch (ctx->reply++) { -+ case 0: /* greeting */ -+ i_assert(reply->status == 220); -+ break; -+ case 1: /* bad command reply */ -+ switch (client_index) { -+ case 0: case 1: case 2: -+ i_assert(reply->status == 501); -+ break; -+ case 3: -+ i_assert(smtp_reply_is_success(reply)); -+ break; -+ default: -+ i_unreached(); -+ } -+ ctx->replied = TRUE; -+ io_loop_stop(ioloop); -+ connection_disconnect(&conn->conn); -+ return; -+ default: -+ i_unreached(); -+ } -+ } -+ -+ i_assert(ret == 0); -+} -+ -+static void -+test_bad_vrfy_client_connected(struct client_connection *conn) -+{ -+ struct _bad_vrfy_client *ctx; -+ -+ ctx = p_new(conn->pool, struct _bad_vrfy_client, 1); -+ ctx->parser = smtp_reply_parser_init(conn->conn.input, (size_t)-1); -+ conn->context = ctx; -+ -+ switch (client_index) { -+ case 0: -+ o_stream_nsend_str(conn->conn.output, -+ "VRFY\r\n"); -+ break; -+ case 1: -+ o_stream_nsend_str(conn->conn.output, -+ "VRFY \"hendrik\r\n"); -+ break; -+ case 2: -+ o_stream_nsend_str(conn->conn.output, -+ "VRFY hen\"drik\r\n"); -+ break; -+ case 3: -+ o_stream_nsend_str(conn->conn.output, -+ "VRFY \"hendrik\"\r\n"); -+ break; -+ default: -+ i_unreached(); -+ } -+} -+ -+static void -+test_bad_vrfy_client_deinit(struct client_connection *conn) -+{ -+ struct _bad_vrfy_client *ctx = conn->context; -+ -+ i_assert(ctx->replied); -+ smtp_reply_parser_deinit(&ctx->parser); -+} -+ -+static void test_client_bad_vrfy(unsigned int index) -+{ -+ test_client_input = test_bad_vrfy_client_input; -+ test_client_connected = test_bad_vrfy_client_connected; -+ test_client_deinit = test_bad_vrfy_client_deinit; -+ test_client_run(index); -+} -+ -+/* server */ -+ -+static void -+test_server_bad_vrfy_disconnect(void *context ATTR_UNUSED, const char *reason) -+{ -+ if (debug) -+ i_debug("Disconnect: %s", reason); -+} -+ -+static int -+test_server_bad_vrfy_rcpt(void *conn_ctx ATTR_UNUSED, -+ struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, -+ struct smtp_server_recipient *rcpt ATTR_UNUSED) -+{ -+ test_assert(FALSE); -+ return 1; -+} -+ -+static int -+test_server_bad_vrfy_data_begin( -+ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, -+ struct smtp_server_transaction *trans ATTR_UNUSED, -+ struct istream *data_input ATTR_UNUSED) -+{ -+ test_assert(FALSE); -+ return 1; -+} -+ -+static void -+test_server_bad_vrfy(const struct smtp_server_settings *server_set) -+{ -+ server_callbacks.conn_disconnect = test_server_bad_vrfy_disconnect; -+ -+ server_callbacks.conn_cmd_rcpt = test_server_bad_vrfy_rcpt; -+ server_callbacks.conn_cmd_data_begin = test_server_bad_vrfy_data_begin; -+ test_server_run(server_set); -+} -+ -+/* test */ -+ -+static void test_bad_vrfy(void) -+{ -+ struct smtp_server_settings smtp_server_set; -+ -+ test_server_defaults(&smtp_server_set); -+ smtp_server_set.max_client_idle_time_msecs = 1000; -+ -+ test_begin("bad VRFY"); -+ test_run_client_server(&smtp_server_set, -+ test_server_bad_vrfy, -+ test_client_bad_vrfy, 4); -+ test_end(); -+} -+ -+/* -+ * Bad NOOP -+ */ -+ -+/* client */ -+ -+struct _bad_noop_client { -+ struct smtp_reply_parser *parser; -+ unsigned int reply; -+ -+ bool replied:1; -+}; -+ -+static void -+test_bad_noop_client_input(struct client_connection *conn) -+{ -+ struct _bad_noop_client *ctx = conn->context; -+ struct smtp_reply *reply; -+ const char *error; -+ int ret; -+ -+ while ((ret = smtp_reply_parse_next(ctx->parser, FALSE, -+ &reply, &error)) > 0) { -+ if (debug) -+ i_debug("REPLY: %s", smtp_reply_log(reply)); -+ -+ switch (ctx->reply++) { -+ case 0: /* greeting */ -+ i_assert(reply->status == 220); -+ break; -+ case 1: /* bad command reply */ -+ switch (client_index) { -+ case 1: case 2: -+ i_assert(reply->status == 501); -+ break; -+ case 0: case 3: -+ i_assert(smtp_reply_is_success(reply)); -+ break; -+ default: -+ i_unreached(); -+ } -+ ctx->replied = TRUE; -+ io_loop_stop(ioloop); -+ connection_disconnect(&conn->conn); -+ return; -+ default: -+ i_unreached(); -+ } -+ } -+ -+ i_assert(ret == 0); -+} -+ -+static void -+test_bad_noop_client_connected(struct client_connection *conn) -+{ -+ struct _bad_noop_client *ctx; -+ -+ ctx = p_new(conn->pool, struct _bad_noop_client, 1); -+ ctx->parser = smtp_reply_parser_init(conn->conn.input, (size_t)-1); -+ conn->context = ctx; -+ -+ switch (client_index) { -+ case 0: -+ o_stream_nsend_str(conn->conn.output, -+ "NOOP\r\n"); -+ break; -+ case 1: -+ o_stream_nsend_str(conn->conn.output, -+ "NOOP \"frop\r\n"); -+ break; -+ case 2: -+ o_stream_nsend_str(conn->conn.output, -+ "NOOP fr\"op\r\n"); -+ break; -+ case 3: -+ o_stream_nsend_str(conn->conn.output, -+ "NOOP \"frop\"\r\n"); -+ break; -+ default: -+ i_unreached(); -+ } -+} -+ -+static void -+test_bad_noop_client_deinit(struct client_connection *conn) -+{ -+ struct _bad_noop_client *ctx = conn->context; -+ -+ i_assert(ctx->replied); -+ smtp_reply_parser_deinit(&ctx->parser); -+} -+ -+static void test_client_bad_noop(unsigned int index) -+{ -+ test_client_input = test_bad_noop_client_input; -+ test_client_connected = test_bad_noop_client_connected; -+ test_client_deinit = test_bad_noop_client_deinit; -+ test_client_run(index); -+} -+ -+/* server */ -+ -+static void -+test_server_bad_noop_disconnect(void *context ATTR_UNUSED, const char *reason) -+{ -+ if (debug) -+ i_debug("Disconnect: %s", reason); -+} -+ -+static int -+test_server_bad_noop_rcpt(void *conn_ctx ATTR_UNUSED, -+ struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, -+ struct smtp_server_recipient *rcpt ATTR_UNUSED) -+{ -+ test_assert(FALSE); -+ return 1; -+} -+ -+static int -+test_server_bad_noop_data_begin( -+ void *conn_ctx ATTR_UNUSED, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, -+ struct smtp_server_transaction *trans ATTR_UNUSED, -+ struct istream *data_input ATTR_UNUSED) -+{ -+ test_assert(FALSE); -+ return 1; -+} -+ -+static void -+test_server_bad_noop(const struct smtp_server_settings *server_set) -+{ -+ server_callbacks.conn_disconnect = test_server_bad_noop_disconnect; -+ -+ server_callbacks.conn_cmd_rcpt = test_server_bad_noop_rcpt; -+ server_callbacks.conn_cmd_data_begin = test_server_bad_noop_data_begin; -+ test_server_run(server_set); -+} -+ -+/* test */ -+ -+static void test_bad_noop(void) -+{ -+ struct smtp_server_settings smtp_server_set; -+ -+ test_server_defaults(&smtp_server_set); -+ smtp_server_set.max_client_idle_time_msecs = 1000; -+ -+ test_begin("bad NOOP"); -+ test_run_client_server(&smtp_server_set, -+ test_server_bad_noop, -+ test_client_bad_noop, 4); -+ test_end(); -+} -+ - /* - * MAIL workarounds - */ -@@ -2246,6 +2556,8 @@ static void (*const test_functions[])(void) = { - test_bad_ehlo, - test_bad_mail, - test_bad_rcpt, -+ test_bad_vrfy, -+ test_bad_noop, - test_mail_workarounds, - test_rcpt_workarounds, - test_too_many_recipients, diff --git a/SOURCES/dovecot-2.3.10-smtppre.patch b/SOURCES/dovecot-2.3.10-smtppre.patch new file mode 100644 index 0000000..7bef066 --- /dev/null +++ b/SOURCES/dovecot-2.3.10-smtppre.patch @@ -0,0 +1,121 @@ +diff -up dovecot-2.3.8/src/lib-smtp/smtp-address.c.smtppre dovecot-2.3.8/src/lib-smtp/smtp-address.c +--- dovecot-2.3.8/src/lib-smtp/smtp-address.c.smtppre 2019-10-08 10:46:18.000000000 +0200 ++++ dovecot-2.3.8/src/lib-smtp/smtp-address.c 2020-05-29 19:11:19.340621409 +0200 +@@ -467,7 +467,7 @@ void smtp_address_detail_parse(pool_t po + *detail_r = p+1; + } + +- if (address->domain == NULL) ++ if (address->domain == NULL || *address->domain == '\0') + *username_r = user; + else if (strchr(user, '@') == NULL ) { + /* username is just glued to the domain... no SMTP escaping */ +@@ -548,7 +548,7 @@ void smtp_address_write(string_t *out, + if (quoted) + str_append_c(out, '\"'); + +- if (address->domain == NULL) ++ if (address->domain == NULL || *address->domain == '\0') + return; + + str_append_c(out, '@'); +@@ -587,8 +587,12 @@ void smtp_address_init(struct smtp_addre + const char *localpart, const char *domain) + { + i_zero(address); ++ if (localpart == NULL || *localpart == '\0') ++ return; ++ + address->localpart = localpart; +- address->domain = (localpart == NULL ? NULL : domain); ++ if (domain != NULL && *domain != '\0') ++ address->domain = domain; + } + + int smtp_address_init_from_msg(struct smtp_address *address, +@@ -597,7 +601,7 @@ int smtp_address_init_from_msg(struct sm + const char *p; + + i_zero(address); +- if (msg_addr->mailbox == NULL) ++ if (msg_addr->mailbox == NULL || *msg_addr->mailbox == '\0') + return 0; + + /* The message_address_parse() function allows UTF-8 codepoints in +@@ -609,7 +613,8 @@ int smtp_address_init_from_msg(struct sm + } + + address->localpart = msg_addr->mailbox; +- address->domain = msg_addr->domain; ++ if (msg_addr->domain != NULL && *msg_addr->domain != '\0') ++ address->domain = msg_addr->domain; + return 0; + } + +@@ -617,8 +622,8 @@ struct smtp_address * + smtp_address_clone(pool_t pool, const struct smtp_address *src) + { + struct smtp_address *new; +- size_t size, lpsize, dsize = 0; +- char *data, *localpart, *domain = NULL; ++ size_t size, lpsize = 0, dsize = 0; ++ char *data, *localpart = NULL, *domain = NULL; + + if (smtp_address_isnull(src)) + return NULL; +@@ -626,17 +631,21 @@ smtp_address_clone(pool_t pool, const st + /* @UNSAFE */ + + size = sizeof(struct smtp_address); +- lpsize = strlen(src->localpart) + 1; +- size = MALLOC_ADD(size, lpsize); +- if (src->domain != NULL) { ++ if (src->localpart != NULL && *src->localpart != '\0') { ++ lpsize = strlen(src->localpart) + 1; ++ size = MALLOC_ADD(size, lpsize); ++ } ++ if (src->domain != NULL && *src->domain != '\0') { + dsize = strlen(src->domain) + 1; + size = MALLOC_ADD(size, dsize); + } + + data = p_malloc(pool, size); + new = (struct smtp_address *)data; +- localpart = PTR_OFFSET(data, sizeof(*new)); +- memcpy(localpart, src->localpart, lpsize); ++ if (lpsize > 0) { ++ localpart = PTR_OFFSET(data, sizeof(*new)); ++ memcpy(localpart, src->localpart, lpsize); ++ } + if (dsize > 0) { + domain = PTR_OFFSET(data, sizeof(*new) + lpsize); + memcpy(domain, src->domain, dsize); +@@ -681,8 +690,8 @@ smtp_address_clone_temp(const struct smt + return NULL; + + new = t_new(struct smtp_address, 1); +- new->localpart = t_strdup(src->localpart); +- new->domain = t_strdup(src->domain); ++ new->localpart = t_strdup_empty(src->localpart); ++ new->domain = t_strdup_empty(src->domain); + return new; + } + +@@ -720,7 +729,7 @@ smtp_address_add_detail(pool_t pool, con + new_addr = p_new(pool, struct smtp_address, 1); + new_addr->localpart = p_strconcat(pool, + address->localpart, delim, detail, NULL); +- new_addr->domain = p_strdup(pool, address->domain); ++ new_addr->domain = p_strdup_empty(pool, address->domain); + + return new_addr; + } +@@ -737,7 +746,7 @@ smtp_address_add_detail_temp(const struc + new_addr = t_new(struct smtp_address, 1); + new_addr->localpart = t_strconcat( + address->localpart, delim, detail, NULL); +- new_addr->domain = t_strdup(address->domain); ++ new_addr->domain = t_strdup_empty(address->domain); + + return new_addr; + } diff --git a/SPECS/dovecot.spec b/SPECS/dovecot.spec index 9301abf..ccc33ff 100644 --- a/SPECS/dovecot.spec +++ b/SPECS/dovecot.spec @@ -5,7 +5,7 @@ Name: dovecot Epoch: 1 Version: 2.3.8 %global prever %{nil} -Release: 2%{?dist}.2 +Release: 4%{?dist} #dovecot itself is MIT, a few sources are PD, pigeonhole is LGPLv2 License: MIT and LGPLv2 Group: System Environment/Daemons @@ -42,20 +42,18 @@ Patch13: dovecot-2.2.36-bigkey.patch # not sent upstream as proper fix would use dovecot's lib-dcrypt but it introduces # hard to break circular dependency between lib and lib-dcrypt Patch14: dovecot-2.3.6-opensslhmac.patch -Patch15: dovecot-2.3.10-CVE_2020_10957p1.patch -Patch16: dovecot-2.3.10-CVE_2020_10957p2.patch -Patch17: dovecot-2.3.10-CVE_2020_10957p3.patch -Patch18: dovecot-2.3.10-CVE_2020_10957p4.patch -Patch19: dovecot-2.3.10-CVE_2020_10957p5.patch -Patch20: dovecot-2.3.10-CVE_2020_10957p6.patch + +# from upstream, for dovecot < 2.3.10.1 +Patch15: dovecot-2.3.10-smtppre.patch +Patch16: dovecot-2.3.10-CVE_2020_10957,10958,10967.patch # from upstream, for dovecot <= 2.3.10.1 -Patch21: dovecot-2.3.8-CVE_2020_12100prereq.patch -Patch22: dovecot-2.3.8-CVE_2020_12100.patch -Patch23: dovecot-2.3.8-CVE_2020_12100ph.patch -Patch24: dovecot-2.3.8-CVE_2020_12673.patch -Patch25: dovecot-2.3.8-CVE_2020_12674prereq.patch -Patch26: dovecot-2.3.8-CVE_2020_12674.patch +Patch17: dovecot-2.3.8-CVE_2020_12100prereq.patch +Patch18: dovecot-2.3.8-CVE_2020_12100.patch +Patch19: dovecot-2.3.8-CVE_2020_12100ph.patch +Patch20: dovecot-2.3.8-CVE_2020_12673.patch +Patch21: dovecot-2.3.8-CVE_2020_12674prereq.patch +Patch22: dovecot-2.3.8-CVE_2020_12674.patch Source15: prestartscript @@ -160,19 +158,14 @@ This package provides the development files for dovecot. %patch11 -p1 -b .aclfix %patch13 -p1 -b .bigkey %patch14 -p1 -b .opensslhmac -%patch15 -p1 -b .CVE_2020_10957p1 -%patch16 -p1 -b .CVE_2020_10957p2 -%patch17 -p1 -b .CVE_2020_10957p3 -%patch18 -p1 -b .CVE_2020_10957p4 -%patch19 -p1 -b .CVE_2020_10957p5 -%patch20 -p1 -b .CVE_2020_10957p6 -%patch21 -p1 -b .CVE_2020_12100prereq -%patch22 -p1 -b .CVE_2020_12100 -%patch23 -p1 -b .CVE_2020_12100ph -%patch24 -p1 -b .CVE_2020_12673 -%patch25 -p1 -b .CVE_2020_12674prereq -%patch26 -p1 -b .CVE_2020_12674 - +%patch15 -p1 -b .smtppre +%patch16 -p1 -b .CVE_2020_10957,10958,10967 +%patch17 -p1 -b .CVE_2020_12100prereq +%patch18 -p1 -b .CVE_2020_12100 +%patch19 -p1 -b .CVE_2020_12100ph +%patch20 -p1 -b .CVE_2020_12673 +%patch21 -p1 -b .CVE_2020_12674prereq +%patch22 -p1 -b .CVE_2020_12674 pushd dovecot-2*3-pigeonhole-%{pigeonholever} popd @@ -532,13 +525,17 @@ make check %{_libdir}/%{name}/dict/libdriver_pgsql.so %changelog -* Sat Aug 08 2020 Michal Hlavinka - 1:2.3.8-2.2 -- fix CVE-2020-12100 resource exhaustion via deeply nested MIME parts (#1866755) -- fix CVE-2020-12673 out of bound reads in dovecot NTLM implementation (#1866760) -- fix CVE-2020-12674 crash due to assert in RPA implementation (#1866767) - -* Fri Jun 05 2020 Michal Hlavinka - 1:2.3.8-2.1 -- fix CVE-2020-10957: malformed NOOP commands leads to DoS (#1840353) +* Fri Aug 07 2020 Michal Hlavinka - 1:2.3.8-4 +- fix CVE-2020-12100 resource exhaustion via deeply nested MIME parts (#1866756) +- fix CVE-2020-12673 out of bound reads in dovecot NTLM implementation (#1866761) +- fix CVE-2020-12674 crash due to assert in RPA implementation (#1866768) + +* Mon Jun 01 2020 Michal Hlavinka - 1:2.3.8-3 +- fix CVE-2020-10957 dovecot: malformed NOOP commands leads to DoS (#1840354) +- fix CVE-2020-10958 dovecot: command followed by sufficient number of newlines + leads to use-after-free (#1840357) +- fix CVE-2020-10967 dovecot: sending mail with empty quoted localpart + leads to DoS (#1840356) * Thu Jan 09 2020 Michal Hlavinka - 1:2.3.8-2 - fix default attributes for ghost files