dovecot-2.2: lmtp: Implemented Postfix-compatible XCLIENT extens...

dovecot at dovecot.org dovecot at dovecot.org
Thu Feb 23 11:12:16 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/1af2a0497f3f
changeset: 14149:1af2a0497f3f
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Feb 23 11:12:04 2012 +0200
description:
lmtp: Implemented Postfix-compatible XCLIENT extension for changing client's ip/port.

diffstat:

 src/lmtp/client.c        |  25 +++++++++++++++++++++++++
 src/lmtp/client.h        |   1 +
 src/lmtp/commands.c      |  40 ++++++++++++++++++++++++++++++++++++++++
 src/lmtp/commands.h      |   1 +
 src/lmtp/lmtp-settings.c |   4 +++-
 src/lmtp/lmtp-settings.h |   1 +
 6 files changed, 71 insertions(+), 1 deletions(-)

diffs (149 lines):

diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/client.c
--- a/src/lmtp/client.c	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/client.c	Thu Feb 23 11:12:04 2012 +0200
@@ -68,6 +68,8 @@
 		return cmd_rset(client, args);
 	if (strcmp(cmd, "NOOP") == 0)
 		return cmd_noop(client, args);
+	if (strcmp(cmd, "XCLIENT") == 0)
+		return cmd_xclient(client, args);
 
 	client_send_line(client, "502 5.5.2 Unknown command");
 	return 0;
@@ -342,6 +344,29 @@
 	va_end(args);
 }
 
+bool client_is_trusted(struct client *client)
+{
+	const char *const *net;
+	struct ip_addr net_ip;
+	unsigned int bits;
+
+	if (client->lmtp_set->login_trusted_networks == NULL)
+		return FALSE;
+
+	net = t_strsplit_spaces(client->lmtp_set->login_trusted_networks, ", ");
+	for (; *net != NULL; net++) {
+		if (net_parse_range(*net, &net_ip, &bits) < 0) {
+			i_error("login_trusted_networks: "
+				"Invalid network '%s'", *net);
+			break;
+		}
+
+		if (net_is_in_network(&client->remote_ip, &net_ip, bits))
+			return TRUE;
+	}
+	return FALSE;
+}
+
 void clients_destroy(void)
 {
 	while (clients != NULL) {
diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/client.h
--- a/src/lmtp/client.h	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/client.h	Thu Feb 23 11:12:04 2012 +0200
@@ -82,6 +82,7 @@
 
 void client_send_line(struct client *client, const char *fmt, ...)
 	ATTR_FORMAT(2, 3);
+bool client_is_trusted(struct client *client);
 
 void clients_destroy(void);
 
diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/commands.c
--- a/src/lmtp/commands.c	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/commands.c	Thu Feb 23 11:12:04 2012 +0200
@@ -68,6 +68,8 @@
 
 	client_state_reset(client);
 	client_send_line(client, "250-%s", client->my_domain);
+	if (client_is_trusted(client))
+		client_send_line(client, "250-XCLIENT ADDR PORT");
 	client_send_line(client, "250-8BITMIME");
 	client_send_line(client, "250-ENHANCEDSTATUSCODES");
 	client_send_line(client, "250 PIPELINING");
@@ -902,3 +904,41 @@
 	client_input_data_handle(client);
 	return -1;
 }
+
+int cmd_xclient(struct client *client, const char *args)
+{
+	const char *const *tmp;
+	struct ip_addr remote_ip;
+	unsigned int remote_port = 0;
+	bool args_ok = TRUE;
+
+	if (!client_is_trusted(client)) {
+		client_send_line(client, "550 You are not from trusted IP");
+		return 0;
+	}
+	remote_ip.family = 0;
+	for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
+		if (strncasecmp(*tmp, "ADDR=", 5) == 0) {
+			if (net_addr2ip(*tmp + 5, &remote_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;
+		}
+	}
+	if (!args_ok) {
+		client_send_line(client, "501 Invalid parameters");
+		return 0;
+	}
+
+	/* args ok, set them and reset the state */
+	client_state_reset(client);
+	if (remote_ip.family != 0)
+		client->remote_ip = remote_ip;
+	if (remote_port != 0)
+		client->remote_port = remote_port;
+	client_send_line(client, "220 %s %s", client->my_domain,
+			 client->lmtp_set->login_greeting);
+	return 0;
+}
diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/commands.h
--- a/src/lmtp/commands.h	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/commands.h	Thu Feb 23 11:12:04 2012 +0200
@@ -11,5 +11,6 @@
 int cmd_rset(struct client *client, const char *args);
 int cmd_noop(struct client *client, const char *args);
 int cmd_data(struct client *client, const char *args);
+int cmd_xclient(struct client *client, const char *args);
 
 #endif
diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/lmtp-settings.c
--- a/src/lmtp/lmtp-settings.c	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/lmtp-settings.c	Thu Feb 23 11:12:04 2012 +0200
@@ -60,6 +60,7 @@
 	DEF(SET_BOOL, lmtp_proxy),
 	DEF(SET_BOOL, lmtp_save_to_detail_mailbox),
 	DEF(SET_STR_VARS, login_greeting),
+	DEF(SET_STR, login_trusted_networks),
 
 	SETTING_DEFINE_LIST_END
 };
@@ -67,7 +68,8 @@
 static const struct lmtp_settings lmtp_default_settings = {
 	.lmtp_proxy = FALSE,
 	.lmtp_save_to_detail_mailbox = FALSE,
-	.login_greeting = PACKAGE_NAME" ready."
+	.login_greeting = PACKAGE_NAME" ready.",
+	.login_trusted_networks = ""
 };
 
 static const struct setting_parser_info *lmtp_setting_dependencies[] = {
diff -r ac4eed7bef23 -r 1af2a0497f3f src/lmtp/lmtp-settings.h
--- a/src/lmtp/lmtp-settings.h	Thu Feb 16 23:05:17 2012 +0000
+++ b/src/lmtp/lmtp-settings.h	Thu Feb 23 11:12:04 2012 +0200
@@ -8,6 +8,7 @@
 	bool lmtp_proxy;
 	bool lmtp_save_to_detail_mailbox;
 	const char *login_greeting;
+	const char *login_trusted_networks;
 };
 
 extern const struct setting_parser_info lmtp_setting_parser_info;


More information about the dovecot-cvs mailing list