]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
pop3-login: Read command more carefully
authorAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 8 Jul 2020 05:55:31 +0000 (08:55 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 10 Jul 2020 06:58:10 +0000 (09:58 +0300)
Ensure we don't consume '\n' or '\0' when reading command, but
that we consume '\r' otherwise i_stream_read_next_line won't work properly.

src/pop3-login/client.c

index 1cef4cc4eb07bc2aed3f5b27181b974a576c6572..a17bdb2e775ce98c8733dab19cb91416943459ed 100644 (file)
 #include "pop3-proxy.h"
 #include "pop3-login-settings.h"
 
+#include <ctype.h>
+
 /* Disconnect client when it sends too many bad commands */
 #define CLIENT_MAX_BAD_COMMANDS 3
+#define CLIENT_MAX_CMD_LEN 8
 
 static bool cmd_stls(struct pop3_client *client)
 {
@@ -88,7 +91,6 @@ static bool cmd_xclient(struct pop3_client *client, const char *args)
 static bool client_command_execute(struct pop3_client *client, const char *cmd,
                                   const char *args)
 {
-       cmd = t_str_ucase(cmd);
        if (strcmp(cmd, "CAPA") == 0)
                return cmd_capa(client, args);
        if (strcmp(cmd, "USER") == 0)
@@ -142,16 +144,21 @@ static bool client_read_cmd_name(struct client *client, const char **cmd_r)
 {
        const unsigned char *data;
        size_t size, i;
+       string_t *cmd = t_str_new(CLIENT_MAX_CMD_LEN);
        if (i_stream_read_more(client->input, &data, &size) <= 0)
                return FALSE;
        for(i = 0; i < size; i++) {
+               if (data[i] == '\r') continue;
                if (data[i] == ' ' ||
-                   data[i] == '\r' ||
-                   data[i] == '\n') {
-                       *cmd_r = t_str_ucase(t_strndup(data, i));
-                       i_stream_skip(client->input, i+1);
+                   data[i] == '\n' ||
+                   data[i] == '\0' ||
+                   i >= CLIENT_MAX_CMD_LEN) {
+                       *cmd_r = str_c(cmd);
+                       /* only skip ws */
+                       i_stream_skip(client->input, i + (data[i] == ' ' ? 1 : 0));
                        return TRUE;
                }
+               str_append_c(cmd, i_toupper(data[i]));
        }
        return FALSE;
 }