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

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