dovecot-1.2: If commands are pipelined after the login command, ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Jun 21 12:51:46 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/2351a81ce699
changeset: 7927:2351a81ce699
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jun 21 12:23:08 2008 +0300
description:
If commands are pipelined after the login command, pass them to the
IMAP/POP3 process so it can process the command instead of discarding it.

diffstat:

21 files changed, 206 insertions(+), 95 deletions(-)
src/imap-login/client-authenticate.c |    4 +-
src/imap-login/client.c              |   33 +++++++++---------
src/imap-login/client.h              |    1 
src/imap-login/imap-proxy.c          |    4 +-
src/imap/client.c                    |    4 --
src/imap/client.h                    |    1 
src/imap/main.c                      |   26 +++++++++++++-
src/login-common/client-common.h     |    9 +++++
src/login-common/master.c            |   51 +++++++++++++++++++---------
src/master/login-process.c           |   32 ++++++++++++++++--
src/master/mail-process.c            |    9 +++++
src/master/mail-process.h            |    1 
src/master/master-login-interface.h  |    5 ++
src/master/master-settings.c         |    2 -
src/pop3-login/client-authenticate.c |    2 -
src/pop3-login/client.c              |   25 ++++++--------
src/pop3-login/client.h              |    2 -
src/pop3-login/pop3-proxy.c          |    4 +-
src/pop3/client.c                    |   60 +++++++++++++++++++---------------
src/pop3/client.h                    |    2 +
src/pop3/main.c                      |   24 ++++++++++++-

diffs (truncated from 804 to 300 lines):

diff -r 187183c360dd -r 2351a81ce699 src/imap-login/client-authenticate.c
--- a/src/imap-login/client-authenticate.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap-login/client-authenticate.c	Sat Jun 21 12:23:08 2008 +0300
@@ -52,14 +52,14 @@ static void client_auth_input(struct ima
 		return;
 
 	if (client->skip_line) {
-		if (i_stream_next_line(client->input) == NULL)
+		if (i_stream_next_line(client->common.input) == NULL)
 			return;
 
 		client->skip_line = FALSE;
 	}
 
 	/* @UNSAFE */
-	line = i_stream_next_line(client->input);
+	line = i_stream_next_line(client->common.input);
 	if (line == NULL)
 		return;
 
diff -r 187183c360dd -r 2351a81ce699 src/imap-login/client.c
--- a/src/imap-login/client.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap-login/client.c	Sat Jun 21 12:23:08 2008 +0300
@@ -19,10 +19,6 @@
 
 #include <stdlib.h>
 
-/* max. size of one parameter in line, or max reply length in SASL
-   authentication */
-#define MAX_INBUF_SIZE 4096
-
 /* max. size of output buffer. if it gets full, the client is disconnected.
    SASL authentication gives the largest output. */
 #define MAX_OUTBUF_SIZE 4096
@@ -72,10 +68,11 @@ static void client_set_title(struct imap
 
 static void client_open_streams(struct imap_client *client, int fd)
 {
-	client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
+	client->common.input =
+		i_stream_create_fd(fd, LOGIN_MAX_INBUF_SIZE, FALSE);
 	client->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE, FALSE);
-	client->parser = imap_parser_create(client->input, client->output,
-					    MAX_IMAP_LINE);
+	client->parser = imap_parser_create(client->common.input,
+					    client->output, MAX_IMAP_LINE);
 }
 
 /* Skip incoming data until newline is found,
@@ -85,11 +82,11 @@ bool client_skip_line(struct imap_client
 	const unsigned char *data;
 	size_t i, data_size;
 
-	data = i_stream_get_data(client->input, &data_size);
+	data = i_stream_get_data(client->common.input, &data_size);
 
 	for (i = 0; i < data_size; i++) {
 		if (data[i] == '\n') {
-			i_stream_skip(client->input, i+1);
+			i_stream_skip(client->common.input, i+1);
 			return TRUE;
 		}
 	}
@@ -141,7 +138,7 @@ static void client_start_tls(struct imap
 	client_set_title(client);
 
 	client->common.fd = fd_ssl;
-	i_stream_unref(&client->input);
+	i_stream_unref(&client->common.input);
 	o_stream_unref(&client->output);
 	imap_parser_destroy(&client->parser);
 
@@ -360,7 +357,9 @@ static bool client_handle_input(struct i
 		/* not enough data */
 		return FALSE;
 	}
-	client->skip_line = TRUE;
+	/* we read the entire line - skip over the CRLF */
+	if (!client_skip_line(client))
+		i_unreached();
 
 	if (*client->cmd_tag == '\0')
 		ret = -1;
@@ -387,7 +386,7 @@ static bool client_handle_input(struct i
 
 bool client_read(struct imap_client *client)
 {
-	switch (i_stream_read(client->input)) {
+	switch (i_stream_read(client->common.input)) {
 	case -2:
 		/* buffer full */
 		client_send_line(client, "* BYE Input buffer full, aborting");
@@ -557,8 +556,8 @@ void client_destroy(struct imap_client *
 
 	client_unlink(&client->common);
 
-	if (client->input != NULL)
-		i_stream_close(client->input);
+	if (client->common.input != NULL)
+		i_stream_close(client->common.input);
 	if (client->output != NULL)
 		o_stream_close(client->output);
 
@@ -637,8 +636,8 @@ bool client_unref(struct imap_client *cl
 
 	imap_parser_destroy(&client->parser);
 
-	if (client->input != NULL)
-		i_stream_unref(&client->input);
+	if (client->common.input != NULL)
+		i_stream_unref(&client->common.input);
 	if (client->output != NULL)
 		o_stream_unref(&client->output);
 
@@ -665,7 +664,7 @@ void client_send_line(struct imap_client
 		   want this connection destroyed. however destroying it here
 		   might break things if client is still tried to be accessed
 		   without being referenced.. */
-		i_stream_close(client->input);
+		i_stream_close(client->common.input);
 	}
 }
 
diff -r 187183c360dd -r 2351a81ce699 src/imap-login/client.h
--- a/src/imap-login/client.h	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap-login/client.h	Sat Jun 21 12:23:08 2008 +0300
@@ -12,7 +12,6 @@ struct imap_client {
 	int refcount;
 
 	struct io *io;
-	struct istream *input;
 	struct ostream *output;
 	struct imap_parser *parser;
 	struct timeout *to_idle_disconnect, *to_auth_waiting;
diff -r 187183c360dd -r 2351a81ce699 src/imap-login/imap-proxy.c
--- a/src/imap-login/imap-proxy.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap-login/imap-proxy.c	Sat Jun 21 12:23:08 2008 +0300
@@ -97,11 +97,11 @@ static int proxy_input_line(struct imap_
 				      login_proxy_get_port(client->proxy));
 
 		(void)client_skip_line(client);
-		login_proxy_detach(client->proxy, client->input,
+		login_proxy_detach(client->proxy, client->common.input,
 				   client->output);
 
 		client->proxy = NULL;
-		client->input = NULL;
+		client->common.input = NULL;
 		client->output = NULL;
 		client->common.fd = -1;
 		client_destroy_success(client, msg);
diff -r 187183c360dd -r 2351a81ce699 src/imap/client.c
--- a/src/imap/client.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap/client.c	Sat Jun 21 12:23:08 2008 +0300
@@ -17,8 +17,6 @@ extern struct mail_storage_callbacks mai
 extern struct mail_storage_callbacks mail_storage_callbacks;
 
 static struct client *my_client; /* we don't need more than one currently */
-
-static bool client_handle_input(struct client *client);
 
 static void client_idle_timeout(struct client *client)
 {
@@ -684,7 +682,7 @@ static bool client_handle_next_command(s
 	return client_command_input(client->input_lock);
 }
 
-static bool client_handle_input(struct client *client)
+bool client_handle_input(struct client *client)
 {
 	bool ret, remove_io, handled_commands = FALSE;
 
diff -r 187183c360dd -r 2351a81ce699 src/imap/client.h
--- a/src/imap/client.h	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap/client.h	Sat Jun 21 12:23:08 2008 +0300
@@ -171,6 +171,7 @@ void client_continue_pending_input(struc
 void client_continue_pending_input(struct client **_client);
 
 void client_input(struct client *client);
+bool client_handle_input(struct client *client);
 int client_output(struct client *client);
 
 #endif
diff -r 187183c360dd -r 2351a81ce699 src/imap/main.c
--- a/src/imap/main.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/imap/main.c	Sat Jun 21 12:23:08 2008 +0300
@@ -5,6 +5,8 @@
 #include "network.h"
 #include "ostream.h"
 #include "str.h"
+#include "base64.h"
+#include "istream.h"
 #include "lib-signals.h"
 #include "restrict-access.h"
 #include "fd-close-on-exec.h"
@@ -163,6 +165,7 @@ static void main_init(void)
 static void main_init(void)
 {
 	struct client *client;
+	struct ostream *output;
 	struct mail_namespace *ns;
 	const char *user, *str;
 
@@ -238,7 +241,9 @@ static void main_init(void)
 		i_fatal("Namespace initialization failed");
 	client = client_create(0, 1, ns);
 
-        o_stream_cork(client->output);
+	output = client->output;
+	o_stream_ref(output);
+	o_stream_cork(output);
 	if (IS_STANDALONE()) {
 		client_send_line(client, t_strconcat(
 			"* PREAUTH [CAPABILITY ",
@@ -249,7 +254,18 @@ static void main_init(void)
 		client_send_line(client, t_strconcat(getenv("IMAPLOGINTAG"),
 						     " OK Logged in.", NULL));
 	}
-        o_stream_uncork(client->output);
+	str = getenv("CLIENT_INPUT");
+	if (str != NULL) T_BEGIN {
+		buffer_t *buf = t_base64_decode_str(str);
+		if (buf->used > 0) {
+			if (!i_stream_add_data(client->input, buf->data,
+					       buf->used))
+				i_panic("Couldn't add client input to stream");
+			(void)client_handle_input(client);
+		}
+	} T_END;
+        o_stream_uncork(output);
+	o_stream_unref(&output);
 }
 
 static void main_deinit(void)
@@ -292,8 +308,12 @@ int main(int argc ATTR_UNUSED, char *arg
         process_title_init(argv, envp);
 	ioloop = io_loop_create();
 
+	/* fake that we're running, so we know if client was destroyed
+	   while initializing */
+	io_loop_set_running(ioloop);
 	main_init();
-        io_loop_run(ioloop);
+	if (io_loop_is_running(ioloop))
+		io_loop_run(ioloop);
 	main_deinit();
 
 	io_loop_destroy(&ioloop);
diff -r 187183c360dd -r 2351a81ce699 src/login-common/client-common.h
--- a/src/login-common/client-common.h	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/login-common/client-common.h	Sat Jun 21 12:23:08 2008 +0300
@@ -4,6 +4,14 @@
 #include "network.h"
 #include "master.h"
 #include "sasl-server.h"
+
+/* max. size of input buffer. this means:
+
+   SASL: Max SASL request length from client
+   IMAP: Max. length of a single parameter
+   POP3: Max. length of a command line (spec says 512 would be enough)
+*/
+#define LOGIN_MAX_INBUF_SIZE 4096
 
 struct client {
 	struct client *prev, *next;
@@ -14,6 +22,7 @@ struct client {
 	struct ssl_proxy *proxy;
 
 	int fd;
+	struct istream *input;
 
 	char *auth_mech_name;
 	struct auth_request *auth_request;
diff -r 187183c360dd -r 2351a81ce699 src/login-common/master.c
--- a/src/login-common/master.c	Sat Jun 21 12:22:01 2008 +0300
+++ b/src/login-common/master.c	Sat Jun 21 12:23:08 2008 +0300
@@ -2,6 +2,7 @@
 
 #include "common.h"
 #include "hash.h"
+#include "buffer.h"
 #include "ioloop.h"
 #include "network.h"
 #include "fdpass.h"
@@ -59,32 +60,50 @@ void master_request_login(struct client 
 void master_request_login(struct client *client, master_callback_t *callback,
 			  unsigned int auth_pid, unsigned int auth_id)
 {
-	struct master_login_request req;
+	buffer_t *buf;
+	struct master_login_request *req;
 	struct stat st;
+	const unsigned char *data;
+	size_t size;
+	ssize_t ret;
 
 	i_assert(auth_pid != 0);
 
-	memset(&req, 0, sizeof(req));


More information about the dovecot-cvs mailing list