]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common, imap: Allow imap process to handle multiplex ostream
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 8 Apr 2024 21:12:05 +0000 (00:12 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Tue, 18 Jun 2024 08:31:38 +0000 (08:31 +0000)
src/imap/imap-client.c
src/imap/imap-client.h
src/imap/main.c
src/lib-login/login-interface.h
src/login-common/client-common.c
src/login-common/sasl-server.c

index 2d4b9a69995cbcaebbf00ac2a18bfd9d55712c2f..5427fa21f8e5e1ce6348e9af68053fd16a28f4e3 100644 (file)
@@ -11,6 +11,7 @@
 #include "istream.h"
 #include "istream-concat.h"
 #include "ostream.h"
+#include "ostream-multiplex.h"
 #include "time-util.h"
 #include "var-expand.h"
 #include "settings.h"
@@ -118,6 +119,13 @@ struct client *client_create(int fd_in, int fd_out,
        client->input = i_stream_create_fd(fd_in,
                                           set->imap_max_line_length);
        client->output = o_stream_create_fd(fd_out, SIZE_MAX);
+       if ((flags & CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT) != 0) {
+               client->multiplex_output =
+                       o_stream_create_multiplex(client->output, SIZE_MAX,
+                               OSTREAM_MULTIPLEX_FORMAT_STREAM_CONTINUE);
+               o_stream_unref(&client->output);
+               client->output = client->multiplex_output;
+       }
        o_stream_set_no_error_handling(client->output, TRUE);
        i_stream_set_name(client->input, "<imap client>");
        o_stream_set_name(client->output, "<imap client>");
index 548e38fd4a2985d9b794d929ab2c12c151058f1d..9017deb97bbd37ad8d7bccbb67e83e282692f714 100644 (file)
@@ -20,6 +20,7 @@ struct imap_urlauth_context;
 
 enum client_create_flags {
        CLIENT_CREATE_FLAG_UNHIBERNATED = BIT(0),
+       CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT = BIT(1),
 };
 
 struct mailbox_keywords {
@@ -168,6 +169,7 @@ struct client {
        struct io *io;
        struct istream *input, *pre_rawlog_input, *post_rawlog_input;
        struct ostream *output, *pre_rawlog_output, *post_rawlog_output;
+       struct ostream *multiplex_output;
        struct timeout *to_idle, *to_idle_output, *to_delayed_input;
        guid_128_t anvil_conn_guid;
 
index f9d05472b4beb64fd9aab147fd5f58655de53797..91a13ebce35ef38db254f0ef9b917cfbe50b216d 100644 (file)
@@ -362,6 +362,7 @@ login_request_finished(const struct login_server_request *request,
        struct client *client;
        struct imap_login_request imap_request;
        enum login_request_flags flags = request->auth_req.flags;
+       enum client_create_flags create_flags = 0;
        const char *error;
 
        i_zero(&input);
@@ -375,13 +376,15 @@ login_request_finished(const struct login_server_request *request,
        input.session_id = request->session_id;
        if ((flags & LOGIN_REQUEST_FLAG_END_CLIENT_SECURED_TLS) != 0)
                input.end_client_tls_secured = TRUE;
+       if ((flags & LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT) != 0)
+               create_flags |= CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT;
 
        client_parse_imap_login_request(request->data,
                                        request->auth_req.data_size,
                                        &imap_request);
 
        if (client_create_from_input(&input, request->fd, request->fd,
-                                    0, &client, &error) < 0) {
+                                    create_flags, &client, &error) < 0) {
                int fd = request->fd;
                struct ostream *output =
                        o_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE);
index 682231aeb99ea308656bcbc102e81fbc31e939d3..eae04ba0a9cc656e76b35653ae0fd464c47cde18 100644 (file)
@@ -24,6 +24,8 @@ enum login_request_flags {
        LOGIN_REQUEST_FLAG_END_CLIENT_SECURED_TLS = BIT(2),
        /* This login is implicit; no command reply is expected */
        LOGIN_REQUEST_FLAG_IMPLICIT             = BIT(3),
+       /* The output stream is ostream-multiplex */
+       LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT     = BIT(4),
 };
 
 /* Login request. File descriptor may be sent along with the request. */
index 3ef60a7f1b145c1d5d3b8dda13af2a5f8e7d2399..c052b3383444df1c2db88a96ebfb16f90ff84ac4 100644 (file)
@@ -879,7 +879,7 @@ int client_get_plaintext_fd(struct client *client, int *fd_r, bool *close_fd_r)
 {
        int fds[2];
 
-       if (client->ssl_iostream == NULL && client->multiplex_output == NULL) {
+       if (client->ssl_iostream == NULL) {
                /* Plaintext connection - We can send the fd directly to
                   the post-login process without any proxying. */
                *fd_r = client->fd;
index ade2338c3b9ba5e706c775f601e390b0331064dc..4dd3bb7c9342ec6a4e952ca88209e6e3fb024714 100644 (file)
@@ -178,6 +178,8 @@ static int master_send_request(struct anvil_request *anvil_request)
        req.local_port = client->local_port;
        req.remote_port = client->remote_port;
        req.client_pid = getpid();
+       if (client->multiplex_output != NULL)
+               req.flags |= LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT;
        if (client->ssl_iostream != NULL &&
            ssl_iostream_get_compression(client->ssl_iostream) != NULL)
                req.flags |= LOGIN_REQUEST_FLAG_TLS_COMPRESSION;