import dovecot-2.3.8-4.el8
This commit is contained in:
parent
552325dc66
commit
5e1a55119d
1090
SOURCES/dovecot-2.3.10-CVE_2020_10957,10958,10967.patch
Normal file
1090
SOURCES/dovecot-2.3.10-CVE_2020_10957,10958,10967.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,60 +0,0 @@
|
||||
From 606724bd528b92347dce580d3ab48fc1e3c2f4d7 Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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) {
|
@ -1,51 +0,0 @@
|
||||
From aedb205c79395de77127fb7166b29b09319df23c Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
From 874817b169d19a4ae51d80ad5798a396bfe90136 Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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;
|
@ -1,24 +0,0 @@
|
||||
From 5efeccc10beccbf8d7700adec1278f97d416cbc6 Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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);
|
@ -1,191 +0,0 @@
|
||||
From 363af76535f8137ba76d9de7935023bab9a045ef Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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);
|
||||
+}
|
@ -1,340 +0,0 @@
|
||||
From f206dc478d1b22183f645ea8c98ffe3712e106b2 Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Bosch <stephan.bosch@open-xchange.com>
|
||||
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,
|
121
SOURCES/dovecot-2.3.10-smtppre.patch
Normal file
121
SOURCES/dovecot-2.3.10-smtppre.patch
Normal file
@ -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;
|
||||
}
|
@ -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 <mhlavink@redhat.com> - 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 Aug 07 2020 Michal Hlavinka <mhlavink@redhat.com> - 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)
|
||||
|
||||
* Fri Jun 05 2020 Michal Hlavinka <mhlavink@redhat.com> - 1:2.3.8-2.1
|
||||
- fix CVE-2020-10957: malformed NOOP commands leads to DoS (#1840353)
|
||||
* Mon Jun 01 2020 Michal Hlavinka <mhlavink@redhat.com> - 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 <mhlavink@redhat.com> - 1:2.3.8-2
|
||||
- fix default attributes for ghost files
|
||||
|
Loading…
Reference in New Issue
Block a user