From: Stephan Bosch Date: Mon, 20 Aug 2018 20:18:27 +0000 (+0200) Subject: lmtp: Add client workarounds. X-Git-Tag: 2.3.10~270 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ed2397f80e1768837b6a01d207a640cec83bf1a;p=thirdparty%2Fdovecot%2Fcore.git lmtp: Add client workarounds. Adds same workarounds as the submission service supports. --- diff --git a/doc/example-config/conf.d/20-lmtp.conf b/doc/example-config/conf.d/20-lmtp.conf index b33a4678be..0684e81908 100644 --- a/doc/example-config/conf.d/20-lmtp.conf +++ b/doc/example-config/conf.d/20-lmtp.conf @@ -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 diff --git a/src/lmtp/lmtp-client.c b/src/lmtp/lmtp-client.c index 972dcc64fa..7d947772e8 100644 --- a/src/lmtp/lmtp-client.c +++ b/src/lmtp/lmtp-client.c @@ -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, diff --git a/src/lmtp/lmtp-settings.c b/src/lmtp/lmtp-settings.c index 1d5ecc8ebe..d6da86eb89 100644 --- a/src/lmtp/lmtp-settings.c +++ b/src/lmtp/lmtp-settings.c @@ -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 = { }; /* */ +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; diff --git a/src/lmtp/lmtp-settings.h b/src/lmtp/lmtp-settings.h index aae84ca71a..6b7bcc54a1 100644 --- a/src/lmtp/lmtp-settings.h +++ b/src/lmtp/lmtp-settings.h @@ -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), +}; /* */ 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;