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

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