changeset 26679:48d3ebe992de

lmtp: Add client workarounds. Adds same workarounds as the submission service supports.
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Mon, 20 Aug 2018 22:18:27 +0200
parents 52c33fc97040
children 49c6f9173347
files doc/example-config/conf.d/20-lmtp.conf src/lmtp/lmtp-client.c src/lmtp/lmtp-settings.c src/lmtp/lmtp-settings.h
diffstat 4 files changed, 78 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/example-config/conf.d/20-lmtp.conf	Mon Aug 20 22:00:04 2018 +0200
+++ b/doc/example-config/conf.d/20-lmtp.conf	Mon Aug 20 22:18:27 2018 +0200
@@ -23,6 +23,17 @@
 # when a mail has multiple recipients.
 #lmtp_hdr_delivery_address = final
 
+# Workarounds for various client bugs:
+#   whitespace-before-path:
+#     Allow one or more spaces or tabs between `MAIL FROM:' and path and between
+#     `RCPT TO:' and path.
+#   mailbox-for-path:
+#     Allow using bare Mailbox syntax (i.e., without <...>) instead of full path
+#     syntax.
+#
+# The list is space-separated.
+#lmtp_client_workarounds =
+
 protocol lmtp {
   # Space separated list of plugins to load (default is global mail_plugins).
   #mail_plugins = $mail_plugins
--- a/src/lmtp/lmtp-client.c	Mon Aug 20 22:00:04 2018 +0200
+++ b/src/lmtp/lmtp-client.c	Mon Aug 20 22:18:27 2018 +0200
@@ -143,6 +143,7 @@
 struct client *client_create(int fd_in, int fd_out,
 			     const struct master_service_connection *conn)
 {
+	enum lmtp_client_workarounds workarounds;
 	struct smtp_server_settings lmtp_set;
 	struct client *client;
 	pool_t pool;
@@ -192,6 +193,16 @@
 	lmtp_set.rawlog_dir = client->lmtp_set->lmtp_rawlog_dir;
 	lmtp_set.event_parent = client->event;
 
+	workarounds = client->lmtp_set->parsed_workarounds;
+	if ((workarounds & LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH) != 0) {
+		lmtp_set.workarounds |=
+			SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH;
+	}
+	if ((workarounds & LMTP_WORKAROUND_MAILBOX_FOR_PATH) != 0) {
+		lmtp_set.workarounds |=
+			SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH;
+	}
+
 	client->conn = smtp_server_connection_create
 		(lmtp_server, fd_in, fd_out,
 			&conn->remote_ip, conn->remote_port,
--- a/src/lmtp/lmtp-settings.c	Mon Aug 20 22:00:04 2018 +0200
+++ b/src/lmtp/lmtp-settings.c	Mon Aug 20 22:18:27 2018 +0200
@@ -68,6 +68,8 @@
 	DEF(SET_STR_VARS, lmtp_rawlog_dir),
 	DEF(SET_STR_VARS, lmtp_proxy_rawlog_dir),
 
+	DEF(SET_STR, lmtp_client_workarounds),
+
 	DEF(SET_STR_VARS, login_greeting),
 	DEF(SET_STR, login_trusted_networks),
 
@@ -87,6 +89,8 @@
 	.lmtp_rawlog_dir = "",
 	.lmtp_proxy_rawlog_dir = "",
 
+	.lmtp_client_workarounds = "",
+
 	.login_greeting = PACKAGE_NAME" ready.",
 	.login_trusted_networks = "",
 
@@ -114,11 +118,54 @@
 };
 
 /* <settings checks> */
+struct lmtp_client_workaround_list {
+	const char *name;
+	enum lmtp_client_workarounds num;
+};
+
+static const struct lmtp_client_workaround_list
+lmtp_client_workaround_list[] = {
+	{ "whitespace-before-path", LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH },
+	{ "mailbox-for-path", LMTP_WORKAROUND_MAILBOX_FOR_PATH },
+	{ NULL, 0 }
+};
+
+static int
+lmtp_settings_parse_workarounds(struct lmtp_settings *set,
+				const char **error_r)
+{
+	enum lmtp_client_workarounds client_workarounds = 0;
+        const struct lmtp_client_workaround_list *list;
+	const char *const *str;
+
+        str = t_strsplit_spaces(set->lmtp_client_workarounds, " ,");
+	for (; *str != NULL; str++) {
+		list = lmtp_client_workaround_list;
+		for (; list->name != NULL; list++) {
+			if (strcasecmp(*str, list->name) == 0) {
+				client_workarounds |= list->num;
+				break;
+			}
+		}
+		if (list->name == NULL) {
+			*error_r = t_strdup_printf(
+				"lmtp_client_workarounds: "
+				"Unknown workaround: %s", *str);
+			return -1;
+		}
+	}
+	set->parsed_workarounds = client_workarounds;
+	return 0;
+}
+
 static bool lmtp_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 				const char **error_r)
 {
 	struct lmtp_settings *set = _set;
 
+	if (lmtp_settings_parse_workarounds(set, error_r) < 0)
+		return FALSE;
+
 	if (strcmp(set->lmtp_hdr_delivery_address, "none") == 0) {
 		set->parsed_lmtp_hdr_delivery_address =
 			LMTP_HDR_DELIVERY_ADDRESS_NONE;
--- a/src/lmtp/lmtp-settings.h	Mon Aug 20 22:00:04 2018 +0200
+++ b/src/lmtp/lmtp-settings.h	Mon Aug 20 22:18:27 2018 +0200
@@ -11,6 +11,11 @@
 	LMTP_HDR_DELIVERY_ADDRESS_FINAL,
 	LMTP_HDR_DELIVERY_ADDRESS_ORIGINAL
 };
+
+enum lmtp_client_workarounds {
+	LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH	= BIT(0),
+	LMTP_WORKAROUND_MAILBOX_FOR_PATH	= BIT(1),
+};
 /* </settings checks> */
 
 struct lmtp_settings {
@@ -23,6 +28,8 @@
 	const char *lmtp_rawlog_dir;
 	const char *lmtp_proxy_rawlog_dir;
 
+	const char *lmtp_client_workarounds;
+
 	const char *login_greeting;
 	const char *login_trusted_networks;
 
@@ -30,6 +37,8 @@
 	const char *mail_plugin_dir;
 
 	enum lmtp_hdr_delivery_address parsed_lmtp_hdr_delivery_address;
+
+	enum lmtp_client_workarounds parsed_workarounds;
 };
 
 extern const struct setting_parser_info lmtp_setting_parser_info;