From: Stephan Bosch Date: Sun, 8 Apr 2018 13:53:37 +0000 (+0200) Subject: submission: Add workarounds for well-known MAIL and RCPT command syntax deviations. X-Git-Tag: 2.3.2.rc1~140 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bad32c8aa23a084a38348d7e27891981fc737e1;p=thirdparty%2Fdovecot%2Fcore.git submission: Add workarounds for well-known MAIL and RCPT command syntax deviations. This adds a new `submission_client_workarounds' setting that works analogous to the `imap_client_workarounds' setting. Workarounds: - 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. --- diff --git a/doc/example-config/conf.d/20-submission.conf b/doc/example-config/conf.d/20-submission.conf index d27009a382..078faf128b 100644 --- a/doc/example-config/conf.d/20-submission.conf +++ b/doc/example-config/conf.d/20-submission.conf @@ -25,6 +25,17 @@ # Maximum number of recipients accepted per connection (default: unlimited) #submission_max_recipients = +# 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. +#submission_client_workarounds = + # Relay server configuration: # # The Dovecot SMTP submission service directly proxies the mail transaction diff --git a/src/submission/submission-client.c b/src/submission/submission-client.c index c4f8cf3812..f98a16f436 100644 --- a/src/submission/submission-client.c +++ b/src/submission/submission-client.c @@ -185,6 +185,8 @@ struct client *client_create(int fd_in, int fd_out, const char *helo, const unsigned char *pdata, unsigned int pdata_len) { + enum submission_client_workarounds workarounds = + set->parsed_workarounds; const struct mail_storage_settings *mail_set; struct smtp_server_settings smtp_set; const char *ident; @@ -207,6 +209,15 @@ struct client *client_create(int fd_in, int fd_out, smtp_set.max_client_idle_time_msecs = CLIENT_IDLE_TIMEOUT_MSECS; smtp_set.debug = user->mail_debug; + if ((workarounds & WORKAROUND_WHITESPACE_BEFORE_PATH) != 0) { + smtp_set.workarounds |= + SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH; + } + if ((workarounds & WORKAROUND_MAILBOX_FOR_PATH) != 0) { + smtp_set.workarounds |= + SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH; + } + client->conn = smtp_server_connection_create(smtp_server, fd_in, fd_out, user->conn.remote_ip, user->conn.remote_port, FALSE, &smtp_set, &smtp_callbacks, client); diff --git a/src/submission/submission-settings.c b/src/submission/submission-settings.c index 160ec08777..29bce42ddc 100644 --- a/src/submission/submission-settings.c +++ b/src/submission/submission-settings.c @@ -11,7 +11,8 @@ #include #include -static bool submission_settings_check(void *_set, pool_t pool, const char **error_r); +static bool submission_settings_verify(void *_set, pool_t pool, + const char **error_r); /* */ static struct file_listener_settings submission_unix_listeners_array[] = { @@ -65,6 +66,7 @@ static const struct setting_define submission_setting_defines[] = { DEF(SET_SIZE, submission_max_mail_size), DEF(SET_UINT, submission_max_recipients), + DEF(SET_STR, submission_client_workarounds), DEF(SET_STR, submission_logout_format), DEF(SET_STR, submission_relay_host), @@ -100,6 +102,7 @@ static const struct submission_settings submission_default_settings = { .submission_max_mail_size = 0, .submission_max_recipients = 0, + .submission_client_workarounds = "", .submission_logout_format = "in=%i out=%o", .submission_relay_host = "", @@ -138,22 +141,67 @@ const struct setting_parser_info submission_setting_parser_info = { .parent_offset = (size_t)-1, -#ifndef CONFIG_BINARY - .check_func = submission_settings_check, -#endif + .check_func = submission_settings_verify, .dependencies = submission_setting_dependencies }; -static bool submission_settings_check(void *_set, pool_t pool, - const char **error_r ATTR_UNUSED) +/* */ +struct submission_client_workaround_list { + const char *name; + enum submission_client_workarounds num; +}; + +static const struct submission_client_workaround_list +submission_client_workaround_list[] = { + { "whitespace-before-path", WORKAROUND_WHITESPACE_BEFORE_PATH }, + { "mailbox-for-path", WORKAROUND_MAILBOX_FOR_PATH }, + { NULL, 0 } +}; + +static int +submission_settings_parse_workarounds(struct submission_settings *set, + const char **error_r) +{ + enum submission_client_workarounds client_workarounds = 0; + const struct submission_client_workaround_list *list; + const char *const *str; + + str = t_strsplit_spaces(set->submission_client_workarounds, " ,"); + for (; *str != NULL; str++) { + list = submission_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( + "submission_client_workarounds: " + "Unknown workaround: %s", *str); + return -1; + } + } + set->parsed_workarounds = client_workarounds; + return 0; +} + +static bool +submission_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct submission_settings *set = _set; + if (submission_settings_parse_workarounds(set, error_r) < 0) + return FALSE; + +#ifndef CONFIG_BINARY if (set->submission_relay_max_idle_time == 0) { *error_r = "submission_relay_max_idle_time must not be 0"; return FALSE; } if (*set->hostname == '\0') set->hostname = p_strdup(pool, my_hostdomain()); +#endif return TRUE; } +/* */ diff --git a/src/submission/submission-settings.h b/src/submission/submission-settings.h index 6c260d0def..dee42607e6 100644 --- a/src/submission/submission-settings.h +++ b/src/submission/submission-settings.h @@ -1,6 +1,15 @@ #ifndef SUBMISSION_SETTINGS_H #define SUBMISSION_SETTINGS_H +#include "smtp-server.h" + +/* */ +enum submission_client_workarounds { + WORKAROUND_WHITESPACE_BEFORE_PATH = BIT(0), + WORKAROUND_MAILBOX_FOR_PATH = BIT(1), +}; +/* */ + struct submission_settings { bool verbose_proctitle; @@ -12,6 +21,7 @@ struct submission_settings { /* submission: */ size_t submission_max_mail_size; unsigned int submission_max_recipients; + const char *submission_client_workarounds; const char *submission_logout_format; /* submission relay: */ @@ -35,6 +45,8 @@ struct submission_settings { /* imap urlauth: */ const char *imap_urlauth_host; in_port_t imap_urlauth_port; + + enum submission_client_workarounds parsed_workarounds; }; extern const struct setting_parser_info submission_setting_parser_info;