dovecot-2.2-pigeonhole: managesieve-login: Implemented proxy XCL...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Thu May 21 19:47:50 UTC 2015


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/ad7fc0736050
changeset: 2074:ad7fc0736050
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Thu May 21 21:45:40 2015 +0200
description:
managesieve-login: Implemented proxy XCLIENT support.

diffstat:

 src/managesieve-login/client.c            |  53 +++++++++++++++++++++++++++-
 src/managesieve-login/client.h            |   1 +
 src/managesieve-login/managesieve-proxy.c |  57 ++++++++++++++++++++++++++++--
 3 files changed, 105 insertions(+), 6 deletions(-)

diffs (198 lines):

diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/client.c
--- a/src/managesieve-login/client.c	Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/client.c	Thu May 21 21:45:40 2015 +0200
@@ -80,6 +80,10 @@
 
 		/* Protocol version */
 		client_send_raw(client, "\"VERSION\" \"1.0\"\r\n");
+
+		/* XCLIENT */
+	    if (client->trusted)
+        	client_send_raw(client, "\"XCLIENT\"\r\n");
 	} T_END;
 }
 
@@ -151,13 +155,58 @@
 	return 1;
 }
 
+static int cmd_xclient
+(struct managesieve_client *client,
+	const struct managesieve_arg *args)
+{
+	unsigned int remote_port;
+	const char *arg;
+	bool args_ok = TRUE;
+
+	if ( !client->common.trusted ) {
+		client_send_no(&client->common,
+			"You are not from trusted IP");
+		return 1;
+	}
+	while (!MANAGESIEVE_ARG_IS_EOL(&args[0]) &&
+		managesieve_arg_get_atom(&args[0], &arg)) {
+		if ( strncasecmp(arg, "ADDR=", 5) == 0 ) {
+			if (net_addr2ip(arg + 5, &client->common.ip) < 0)
+				args_ok = FALSE;
+		} else if ( strncasecmp(arg, "PORT=", 5) == 0 ) {
+			if (str_to_uint(arg + 5, &remote_port) < 0 ||
+			    remote_port == 0 || remote_port > 65535)
+				args_ok = FALSE;
+			else
+				client->common.remote_port = remote_port;
+		} else if ( strncasecmp(arg, "SESSION=", 8) == 0 ) {
+			const char *value = arg + 8;
+
+			if (strlen(value) <= LOGIN_MAX_SESSION_ID_LEN) {
+				client->common.session_id =
+					p_strdup(client->common.pool, value);
+			}
+		} else if ( strncasecmp(arg, "TTL=", 4 ) == 0) {
+			if (str_to_uint(arg + 4, &client->common.proxy_ttl) < 0)
+				args_ok = FALSE;
+		}
+		args++;
+	}
+	if ( !args_ok || !MANAGESIEVE_ARG_IS_EOL(&args[0]))
+		return -1;
+
+	client_send_ok(&client->common, "Updated");
+	return 1;
+}
+
 static struct managesieve_command commands[] = {
 	{ "AUTHENTICATE", cmd_authenticate, 1 },
 	{ "CAPABILITY", cmd_capability, -1 },
 	{ "STARTTLS", cmd_starttls, -1 },
 	{ "NOOP", cmd_noop, 0 },
-	{	"LOGOUT", cmd_logout, -1},
-	{ NULL, NULL, 0}
+	{ "LOGOUT", cmd_logout, -1 },
+	{ "XCLIENT", cmd_xclient, 0 },
+	{ NULL, NULL, 0 }
 };
 
 static bool client_handle_input(struct managesieve_client *client)
diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/client.h
--- a/src/managesieve-login/client.h	Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/client.h	Thu May 21 21:45:40 2015 +0200
@@ -32,6 +32,7 @@
 
 	unsigned int proxy_starttls:1;
 	unsigned int proxy_sasl_plain:1;
+	unsigned int proxy_xclient:1;
 };
 
 bool client_skip_line(struct managesieve_client *client);
diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/managesieve-proxy.c
--- a/src/managesieve-login/managesieve-proxy.c	Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/managesieve-proxy.c	Thu May 21 21:45:40 2015 +0200
@@ -23,6 +23,7 @@
 	PROXY_STATE_INITIAL,
 	PROXY_STATE_TLS_START,
 	PROXY_STATE_TLS_READY,
+	PROXY_STATE_XCLIENT,
 	PROXY_STATE_AUTHENTICATE,
 };
 
@@ -64,8 +65,21 @@
 	managesieve_quote_append_string(dest, str_c(base64), FALSE);
 }
 
+static void proxy_write_xclient
+(struct managesieve_client *client, string_t *str)
+{
+	str_printfa(str,
+		"XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
+		net_ip2addr(&client->common.ip),
+		client->common.remote_port,
+		client_get_session_id(&client->common),
+		client->common.proxy_ttl - 1);
+}
+
 static int proxy_write_login(struct managesieve_client *client, string_t *str)
 {
+	i_assert(client->common.proxy_ttl > 1);
+
 	if ( !client->proxy_sasl_plain ) {
 		client_log_err(&client->common, "proxy: "
 			"Server does not support required PLAIN SASL mechanism");
@@ -77,7 +91,6 @@
 	get_plain_auth(&client->common, str);
 	proxy_free_password(&client->common);
 	str_append(str, "\r\n");
-
 	return 1;
 }
 
@@ -171,6 +184,8 @@
 
 			} else if ( strcasecmp(capability, "STARTTLS") == 0 ) {
 				client->proxy_starttls = TRUE;
+			} else if ( strcasecmp(capability, "XCLIENT") == 0 ) {
+				client->proxy_xclient = TRUE;
 			}
 
 		} else {
@@ -249,6 +264,11 @@
 
 				str_append(command, "STARTTLS\r\n");
 				msieve_client->proxy_state = PROXY_STATE_TLS_START;
+
+			} else if (msieve_client->proxy_xclient) {
+				proxy_write_xclient(msieve_client, command);
+				msieve_client->proxy_state = PROXY_STATE_XCLIENT;
+
 			} else {
 				if ( proxy_write_login(msieve_client, command) < 0 ) {
 					client_proxy_failed(client, TRUE);
@@ -296,17 +316,46 @@
 			}
 
 			command = t_str_new(128);
+			if ( msieve_client->proxy_xclient ) {
+				proxy_write_xclient(msieve_client, command);
+				msieve_client->proxy_state = PROXY_STATE_XCLIENT;
+
+			} else {
+				if ( proxy_write_login(msieve_client, command) < 0 ) {
+					client_proxy_failed(client, TRUE);
+					return -1;
+				}
+				msieve_client->proxy_state = PROXY_STATE_AUTHENTICATE;
+			}
+			(void)o_stream_send(output, str_data(command), str_len(command));
+		}
+		return 0;
+
+	case PROXY_STATE_XCLIENT:
+		if ( strncasecmp(line, "OK", 2) == 0 &&
+			( strlen(line) == 2 || line[2] == ' ' ) ) {
+
+			/* STARTTLS successful, begin TLS negotiation. */
+			if ( login_proxy_starttls(client->login_proxy) < 0 ) {
+				client_proxy_failed(client, TRUE);
+				return -1;
+			}
+
+			command = t_str_new(128);
 			if ( proxy_write_login(msieve_client, command) < 0 ) {
 				client_proxy_failed(client, TRUE);
 				return -1;
 			}
-
 			(void)o_stream_send(output, str_data(command), str_len(command));
-
 			msieve_client->proxy_state = PROXY_STATE_AUTHENTICATE;
+			return 0;
 		}
 
-		return 0;
+		client_log_err(client, t_strdup_printf(
+			"proxy: Remote XCLIENT failed: %s",
+			str_sanitize(line, 160)));
+		client_proxy_failed(client, TRUE);
+		return -1;
 
 	case PROXY_STATE_AUTHENTICATE:
 


More information about the dovecot-cvs mailing list