Blame SOURCES/dovecot-2.3.10-CVE_2020_10957p5.patch

311a5d
From 363af76535f8137ba76d9de7935023bab9a045ef Mon Sep 17 00:00:00 2001
311a5d
From: Stephan Bosch <stephan.bosch@open-xchange.com>
311a5d
Date: Tue, 24 Mar 2020 22:24:20 +0100
311a5d
Subject: [PATCH] lib-smtp: Add tests for smtp_string_parse() and
311a5d
 smtp_string_write().
311a5d
311a5d
---
311a5d
 src/lib-smtp/Makefile.am        |   5 ++
311a5d
 src/lib-smtp/test-smtp-syntax.c | 150 ++++++++++++++++++++++++++++++++
311a5d
 2 files changed, 155 insertions(+)
311a5d
 create mode 100644 src/lib-smtp/test-smtp-syntax.c
311a5d
311a5d
diff --git a/src/lib-smtp/Makefile.am b/src/lib-smtp/Makefile.am
311a5d
index b03761df8b..d87cd4e6d3 100644
311a5d
--- a/src/lib-smtp/Makefile.am
311a5d
+++ b/src/lib-smtp/Makefile.am
311a5d
@@ -72,6 +72,7 @@ pkginc_libdir=$(pkgincludedir)
311a5d
 pkginc_lib_HEADERS = $(headers)
311a5d
 
311a5d
 test_programs = \
311a5d
+	test-smtp-syntax \
311a5d
 	test-smtp-address \
311a5d
 	test-smtp-params \
311a5d
 	test-smtp-reply \
311a5d
@@ -121,6 +122,10 @@ if BUILD_OPENSSL
311a5d
 test_libs_ssl += ../lib-ssl-iostream/libssl_iostream_openssl.la
311a5d
 endif
311a5d
 
311a5d
+test_smtp_syntax_SOURCES = test-smtp-syntax.c
311a5d
+test_smtp_syntax_LDADD = $(test_libs)
311a5d
+test_smtp_syntax_DEPENDENCIES = $(test_deps)
311a5d
+
311a5d
 test_smtp_address_SOURCES = test-smtp-address.c
311a5d
 test_smtp_address_LDFLAGS = -export-dynamic
311a5d
 test_smtp_address_LDADD = $(test_libs)
311a5d
diff --git a/src/lib-smtp/test-smtp-syntax.c b/src/lib-smtp/test-smtp-syntax.c
311a5d
new file mode 100644
311a5d
index 0000000000..735cd01220
311a5d
--- /dev/null
311a5d
+++ b/src/lib-smtp/test-smtp-syntax.c
311a5d
@@ -0,0 +1,150 @@
311a5d
+/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
311a5d
+
311a5d
+#include "lib.h"
311a5d
+#include "str.h"
311a5d
+#include "str-sanitize.h"
311a5d
+#include "test-common.h"
311a5d
+#include "smtp-syntax.h"
311a5d
+
311a5d
+/*
311a5d
+ * Valid string parse tests
311a5d
+ */
311a5d
+
311a5d
+struct valid_string_parse_test {
311a5d
+	const char *input, *parsed, *output;
311a5d
+};
311a5d
+
311a5d
+static const struct valid_string_parse_test
311a5d
+valid_string_parse_tests[] = {
311a5d
+	{
311a5d
+		.input = "",
311a5d
+		.parsed = "",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "atom",
311a5d
+		.parsed = "atom",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "abcdefghijklmnopqrstuvwxyz"
311a5d
+			 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
311a5d
+			 "0123456789!#$%&'*+-/=?^_`{|}~",
311a5d
+		.parsed = "abcdefghijklmnopqrstuvwxyz"
311a5d
+			  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
311a5d
+			  "0123456789!#$%&'*+-/=?^_`{|}~",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\"quoted-string\"",
311a5d
+		.parsed = "quoted-string",
311a5d
+		.output = "quoted-string",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\"quoted \\\"string\\\"\"",
311a5d
+		.parsed = "quoted \"string\"",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\"quoted \\\\string\\\\\"",
311a5d
+		.parsed = "quoted \\string\\",
311a5d
+	},
311a5d
+};
311a5d
+
311a5d
+static const unsigned int valid_string_parse_test_count =
311a5d
+	N_ELEMENTS(valid_string_parse_tests);
311a5d
+
311a5d
+static void test_smtp_string_parse_valid(void)
311a5d
+{
311a5d
+	unsigned int i;
311a5d
+
311a5d
+	for (i = 0; i < valid_string_parse_test_count; i++) T_BEGIN {
311a5d
+		const struct valid_string_parse_test *test =
311a5d
+			&valid_string_parse_tests[i];
311a5d
+		const char *parsed, *error = NULL;
311a5d
+		int ret;
311a5d
+
311a5d
+		ret = smtp_string_parse(test->input, &parsed, &error);
311a5d
+
311a5d
+		test_begin(t_strdup_printf("smtp string valid [%d]", i));
311a5d
+		test_out_reason(t_strdup_printf("parse(\"%s\")", test->input),
311a5d
+				ret >= 0, error);
311a5d
+		test_assert(ret != 0 || *test->input == '\0');
311a5d
+
311a5d
+		if (!test_has_failed()) {
311a5d
+			string_t *encoded;
311a5d
+			const char *output;
311a5d
+
311a5d
+			test_out(t_strdup_printf("parsed = \"%s\"", parsed),
311a5d
+				 null_strcmp(parsed, test->parsed) == 0);
311a5d
+
311a5d
+			encoded = t_str_new(255);
311a5d
+			smtp_string_write(encoded, parsed);
311a5d
+			output = (test->output == NULL ?
311a5d
+				  test->input : test->output);
311a5d
+			test_out(t_strdup_printf("write() = \"%s\"",
311a5d
+						 str_c(encoded)),
311a5d
+				 strcmp(str_c(encoded), output) == 0);
311a5d
+		}
311a5d
+		test_end();
311a5d
+	} T_END;
311a5d
+}
311a5d
+
311a5d
+/*
311a5d
+ * Invalid string parse tests
311a5d
+ */
311a5d
+
311a5d
+struct invalid_string_parse_test {
311a5d
+	const char *input;
311a5d
+};
311a5d
+
311a5d
+static const struct invalid_string_parse_test
311a5d
+invalid_string_parse_tests[] = {
311a5d
+	{
311a5d
+		.input = " ",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\\",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\"",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "\"aa",
311a5d
+	},
311a5d
+	{
311a5d
+		.input = "aa\"",
311a5d
+	},
311a5d
+};
311a5d
+
311a5d
+static const unsigned int invalid_string_parse_test_count =
311a5d
+	N_ELEMENTS(invalid_string_parse_tests);
311a5d
+
311a5d
+static void test_smtp_string_parse_invalid(void)
311a5d
+{
311a5d
+	unsigned int i;
311a5d
+
311a5d
+	for (i = 0; i < invalid_string_parse_test_count; i++) T_BEGIN {
311a5d
+		const struct invalid_string_parse_test *test =
311a5d
+			&invalid_string_parse_tests[i];
311a5d
+		const char *parsed, *error;
311a5d
+		int ret;
311a5d
+
311a5d
+		ret = smtp_string_parse(test->input, &parsed, &error);
311a5d
+
311a5d
+		test_begin(t_strdup_printf("smtp string invalid [%d]", i));
311a5d
+		test_out_reason(t_strdup_printf("parse(\"%s\")", test->input),
311a5d
+				ret < 0, error);
311a5d
+		test_end();
311a5d
+	} T_END;
311a5d
+}
311a5d
+
311a5d
+/*
311a5d
+ * Tests
311a5d
+ */
311a5d
+
311a5d
+int main(void)
311a5d
+{
311a5d
+	static void (*test_functions[])(void) = {
311a5d
+		test_smtp_string_parse_valid,
311a5d
+		test_smtp_string_parse_invalid,
311a5d
+		NULL
311a5d
+	};
311a5d
+	return test_run(test_functions);
311a5d
+}