]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Don't hang at ambiguous commands when they were pipelined already before login
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 5 Jan 2016 16:01:26 +0000 (11:01 -0500)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 5 Jan 2016 16:01:26 +0000 (11:01 -0500)
For example if all of these are sent in a single IP packet:

a login user pass
b select inbox
c noop
d unselect

src/imap/main.c

index 6f24c15dc80ef6b23297db196154744d0a0402eb..acc0d6b262f75770199256233c48bf058a509590 100644 (file)
@@ -202,6 +202,13 @@ client_add_input(struct client *client, const unsigned char *client_input,
        (void)client_handle_input(client);
        o_stream_uncork(output);
        o_stream_unref(&output);
+
+       /* we could have already handled LOGOUT, or we might need to continue
+          pending ambigious commands. */
+       if (client->disconnected)
+               client_destroy(client, NULL);
+       else
+               client_continue_pending_input(client);
 }
 
 int client_create_from_input(const struct mail_storage_service_input *input,
@@ -280,6 +287,7 @@ static void main_stdio_run(const char *username)
                const buffer_t *input_buf = t_base64_decode_str(input_base64);
                client_add_input(client, input_buf->data, input_buf->used);
        }
+       /* client may be destroyed now */
 }
 
 static void
@@ -314,12 +322,12 @@ login_client_connected(const struct master_login_client *login_client,
                master_service_client_connection_destroyed(master_service);
                return;
        }
-       client_add_input(client, login_client->data,
-                        login_client->auth_req.data_size);
-
        flags = login_client->auth_req.flags;
        if ((flags & MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION) != 0)
                client->tls_compression = TRUE;
+       client_add_input(client, login_client->data,
+                        login_client->auth_req.data_size);
+       /* client may be destroyed now */
 }
 
 static void login_client_failed(const struct master_login_client *client,