Blame SOURCES/dovecot-2.3.13-CVE_2020_25275-part5.patch

27f02a
From 9d3ecff3de5553159334cf644e996a616dc52670 Mon Sep 17 00:00:00 2001
27f02a
From: Timo Sirainen <timo.sirainen@open-xchange.com>
27f02a
Date: Mon, 17 Aug 2020 18:22:42 +0300
27f02a
Subject: [PATCH] imap-login: Use imap_parser_read_tag() and
27f02a
 _read_command_name()
27f02a
27f02a
---
27f02a
 src/imap-login/imap-login-client.c | 58 ++++++++++++------------------
27f02a
 1 file changed, 23 insertions(+), 35 deletions(-)
27f02a
27f02a
diff --git a/src/imap-login/imap-login-client.c b/src/imap-login/imap-login-client.c
27f02a
index ce5049d567..b2c8af9cbf 100644
27f02a
--- a/src/imap-login/imap-login-client.c
27f02a
+++ b/src/imap-login/imap-login-client.c
27f02a
@@ -196,7 +196,7 @@ static int client_command_execute(struct imap_client *client, const char *cmd,
27f02a
 
27f02a
 static bool client_invalid_command(struct imap_client *client)
27f02a
 {
27f02a
-	if (*client->cmd_tag == '\0')
27f02a
+	if (client->cmd_tag == NULL || *client->cmd_tag == '\0')
27f02a
 		client->cmd_tag = "*";
27f02a
 	if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
27f02a
 		client_send_reply(&client->common, IMAP_CMD_REPLY_BYE,
27f02a
@@ -210,33 +210,6 @@ static bool client_invalid_command(struct imap_client *client)
27f02a
 	return TRUE;
27f02a
 }
27f02a
 
27f02a
-static bool imap_is_valid_tag(const char *tag)
27f02a
-{
27f02a
-	for (; *tag != '\0'; tag++) {
27f02a
-		switch (*tag) {
27f02a
-		case '+':
27f02a
-		/* atom-specials: */
27f02a
-		case '(':
27f02a
-		case ')':
27f02a
-		case '{':
27f02a
-		case '/':
27f02a
-		case ' ':
27f02a
-		/* list-wildcards: */
27f02a
-		case '%':
27f02a
-		case '*':
27f02a
-		/* quoted-specials: */
27f02a
-		case '"':
27f02a
-		case '\\':
27f02a
-			return FALSE;
27f02a
-		default:
27f02a
-			if (*tag < ' ') /* CTL */
27f02a
-				return FALSE;
27f02a
-			break;
27f02a
-		}
27f02a
-	}
27f02a
-	return TRUE;
27f02a
-}
27f02a
-
27f02a
 static int client_parse_command(struct imap_client *client,
27f02a
 				const struct imap_arg **args_r)
27f02a
 {
27f02a
@@ -261,6 +234,9 @@ static int client_parse_command(struct imap_client *client,
27f02a
 
27f02a
 static bool client_handle_input(struct imap_client *client)
27f02a
 {
27f02a
+	const char *tag, *name;
27f02a
+	int ret;
27f02a
+
27f02a
 	i_assert(!client->common.authenticating);
27f02a
 
27f02a
 	if (client->cmd_finished) {
27f02a
@@ -282,23 +258,35 @@ static bool client_handle_input(struct imap_client *client)
27f02a
 	}
27f02a
 
27f02a
 	if (client->cmd_tag == NULL) {
27f02a
-                client->cmd_tag = imap_parser_read_word(client->parser);
27f02a
-		if (client->cmd_tag == NULL)
27f02a
+		ret = imap_parser_read_tag(client->parser, &tag;;
27f02a
+		if (ret == 0)
27f02a
 			return FALSE; /* need more data */
27f02a
-		if (!imap_is_valid_tag(client->cmd_tag) ||
27f02a
-		    strlen(client->cmd_tag) > IMAP_TAG_MAX_LEN) {
27f02a
+		if (ret < 0 || strlen(tag) > IMAP_TAG_MAX_LEN) {
27f02a
 			/* the tag is invalid, don't allow it and don't
27f02a
 			   send it back. this attempts to prevent any
27f02a
 			   potentially dangerous replies in case someone tries
27f02a
 			   to access us using HTTP protocol. */
27f02a
-			client->cmd_tag = "";
27f02a
+			client->skip_line = TRUE;
27f02a
+			client->cmd_finished = TRUE;
27f02a
+			if (!client_invalid_command(client))
27f02a
+				return FALSE;
27f02a
+			return client_handle_input(client);
27f02a
 		}
27f02a
+		client->cmd_tag = tag;
27f02a
 	}
27f02a
 
27f02a
 	if (client->cmd_name == NULL) {
27f02a
-                client->cmd_name = imap_parser_read_word(client->parser);
27f02a
-		if (client->cmd_name == NULL)
27f02a
+		ret = imap_parser_read_command_name(client->parser, &name);
27f02a
+		if (ret == 0)
27f02a
 			return FALSE; /* need more data */
27f02a
+		if (ret < 0) {
27f02a
+			client->skip_line = TRUE;
27f02a
+			client->cmd_finished = TRUE;
27f02a
+			if (!client_invalid_command(client))
27f02a
+				return FALSE;
27f02a
+			return client_handle_input(client);
27f02a
+		}
27f02a
+		client->cmd_name = name;
27f02a
 	}
27f02a
 	return client->common.v.input_next_cmd(&client->common);
27f02a
 }