dovecot-2.1: pop3-login: Implemented XCLIENT command for forward...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 25 05:21:12 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/35ed77dd500e
changeset: 14190:35ed77dd500e
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 25 05:20:47 2012 +0200
description:
pop3-login: Implemented XCLIENT command for forwarding client ip/port from proxy.

diffstat:

 src/pop3-login/client.c     |  54 ++++++++++++++++++++++++++++++++++++++------
 src/pop3-login/client.h     |   1 +
 src/pop3-login/pop3-proxy.c |  10 ++++++++
 3 files changed, 57 insertions(+), 8 deletions(-)

diffs (120 lines):

diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/client.c
--- a/src/pop3-login/client.c	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/client.c	Sat Feb 25 05:20:47 2012 +0200
@@ -35,6 +35,40 @@
 	return TRUE;
 }
 
+static bool cmd_xclient(struct pop3_client *client, const char *args)
+{
+	const char *const *tmp;
+	unsigned int remote_port;
+	bool args_ok = TRUE;
+
+	if (!client->common.trusted) {
+		client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
+				 "You are not from trusted IP");
+		return TRUE;
+	}
+	for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
+		if (strncasecmp(*tmp, "ADDR=", 5) == 0) {
+			if (net_addr2ip(*tmp + 5, &client->common.ip) < 0)
+				args_ok = FALSE;
+		} else if (strncasecmp(*tmp, "PORT=", 5) == 0) {
+			if (str_to_uint(*tmp + 5, &remote_port) < 0 ||
+			    remote_port == 0 || remote_port > 65535)
+				args_ok = FALSE;
+			else
+				client->common.remote_port = remote_port;
+		}
+	}
+	if (!args_ok) {
+		client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
+				 "Invalid parameters");
+		return TRUE;
+	}
+
+	/* args ok, set them and reset the state */
+	client_send_line(&client->common, CLIENT_CMD_REPLY_OK, "Updated");
+	return TRUE;
+}
+
 static bool client_command_execute(struct pop3_client *client, const char *cmd,
 				   const char *args)
 {
@@ -53,6 +87,8 @@
 		return cmd_stls(client);
 	if (strcmp(cmd, "QUIT") == 0)
 		return cmd_quit(client);
+	if (strcmp(cmd, "XCLIENT") == 0)
+		return cmd_xclient(client, args);
 
 	client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
 			 "Unknown command.");
@@ -149,18 +185,20 @@
 static void pop3_client_send_greeting(struct client *client)
 {
 	struct pop3_client *pop3_client = (struct pop3_client *)client;
+	string_t *str;
 
 	client->io = io_add(client->fd, IO_READ, client_input, client);
 
+	str = t_str_new(128);
+	if (client->trusted) {
+		/* Dovecot extension to avoid extra roundtrip for CAPA */
+		str_append(str, "[XCLIENT] ");
+	}
+	str_append(str, client->set->login_greeting);
 	pop3_client->apop_challenge = get_apop_challenge(pop3_client);
-	if (pop3_client->apop_challenge == NULL) {
-		client_send_line(client, CLIENT_CMD_REPLY_OK,
-				 client->set->login_greeting);
-	} else {
-		client_send_line(client, CLIENT_CMD_REPLY_OK,
-			t_strconcat(client->set->login_greeting, " ",
-				    pop3_client->apop_challenge, NULL));
-	}
+	if (pop3_client->apop_challenge != NULL)
+		str_printfa(str, " %s", pop3_client->apop_challenge);
+	client_send_line(client, CLIENT_CMD_REPLY_OK, str_c(str));
 	client->greeting_sent = TRUE;
 }
 
diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/client.h
--- a/src/pop3-login/client.h	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/client.h	Sat Feb 25 05:20:47 2012 +0200
@@ -18,6 +18,7 @@
 	char *last_user;
 	char *apop_challenge;
 	unsigned int apop_server_pid, apop_connect_uid;
+	bool proxy_xclient;
 };
 
 #endif
diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/pop3-proxy.c
--- a/src/pop3-login/pop3-proxy.c	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/pop3-proxy.c	Sat Feb 25 05:20:47 2012 +0200
@@ -37,6 +37,14 @@
 {
 	string_t *str;
 
+	if (client->proxy_xclient) {
+		/* remote supports XCLIENT, send it */
+		(void)o_stream_send_str(output, t_strdup_printf(
+			"XCLIENT ADDR=%s PORT=%u\r\n",
+			net_ip2addr(&client->common.ip),
+			client->common.remote_port));
+	}
+
 	str = t_str_new(128);
 	if (client->common.proxy_master_user == NULL) {
 		/* send USER command */
@@ -71,6 +79,8 @@
 			client_proxy_failed(client, TRUE);
 			return -1;
 		}
+		pop3_client->proxy_xclient =
+			strncmp(line+3, " [XCLIENT]", 10) == 0;
 
 		ssl_flags = login_proxy_get_ssl_flags(client->login_proxy);
 		if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) {


More information about the dovecot-cvs mailing list