]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lmtp: Add client workarounds.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 20 Aug 2018 20:18:27 +0000 (22:18 +0200)
committerStephan Bosch <stephan.bosch@open-xchange.com>
Mon, 25 Nov 2019 10:26:50 +0000 (11:26 +0100)
Adds same workarounds as the submission service supports.

doc/example-config/conf.d/20-lmtp.conf
src/lmtp/lmtp-client.c
src/lmtp/lmtp-settings.c
src/lmtp/lmtp-settings.h

index b33a4678befb8e5e89c769208abbb352d8ac6a88..0684e819088cd84df1131b9bc87ff084b420f43c 100644 (file)
 # 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
index 972dcc64fa6e19130675627c04b54a7f009b2859..7d947772e8ec19057d5382e1ad977e1724f56f33 100644 (file)
@@ -143,6 +143,7 @@ static void client_read_settings(struct client *client, bool ssl)
 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 @@ struct client *client_create(int fd_in, int fd_out,
        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,
index 1d5ecc8ebe36ab5d5e25de186396e98cb0eed138..d6da86eb89bb763b4b8fa1047c74ec278deda538 100644 (file)
@@ -68,6 +68,8 @@ static const struct setting_define lmtp_setting_defines[] = {
        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 @@ static const struct lmtp_settings lmtp_default_settings = {
        .lmtp_rawlog_dir = "",
        .lmtp_proxy_rawlog_dir = "",
 
+       .lmtp_client_workarounds = "",
+
        .login_greeting = PACKAGE_NAME" ready.",
        .login_trusted_networks = "",
 
@@ -114,11 +118,54 @@ const struct setting_parser_info lmtp_setting_parser_info = {
 };
 
 /* <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;
index aae84ca71af0c22eb15d6ad54d9e29a22ce3df4a..6b7bcc54a1f599a90a0812d758c81c3a01384d4f 100644 (file)
@@ -11,6 +11,11 @@ enum lmtp_hdr_delivery_address {
        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 @@ struct lmtp_settings {
        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 @@ struct lmtp_settings {
        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;