]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: Add workarounds for well-known MAIL and RCPT command syntax deviations.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 8 Apr 2018 10:25:49 +0000 (12:25 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 27 Apr 2018 10:40:00 +0000 (13:40 +0300)
src/lib-smtp/smtp-server-cmd-mail.c
src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/smtp-server-connection.c
src/lib-smtp/smtp-server.c
src/lib-smtp/smtp-server.h

index abb9cee778095a31131d3a0c5df4229341dd0021..a270f5b5dfe1d34ae33adb2f077ac2046c617581 100644 (file)
@@ -73,6 +73,7 @@ void smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd,
        const struct smtp_server_callbacks *callbacks = conn->callbacks;
        struct smtp_server_command *command = cmd->cmd;
        struct smtp_server_cmd_mail *mail_data;
+       enum smtp_address_parse_flags path_parse_flags;
        struct smtp_address *path;
        enum smtp_param_parse_error pperror;
        const char *error;
@@ -91,9 +92,26 @@ void smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd,
                smtp_server_reply(cmd, 501, "5.5.4", "Invalid parameters");
                return;
        }
-       if (smtp_address_parse_path_full(pool_datastack_create(), params + 5,
-                                        SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY,
-                                        &path, &error, &params) < 0) {
+       if (params[5] != ' ' && params[5] != '\t') {
+               params += 5;
+       } else if ((set->workarounds &
+                   SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH) != 0) {
+               params += 5;
+               while (*params == ' ' || *params == '\t')
+                       params++;
+       } else {
+               smtp_server_reply(cmd, 501, "5.5.4",
+                                 "Invalid FROM: "
+                                 "Unexpected whitespace before path");
+               return;
+       }
+       path_parse_flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY;
+       if (*params != '\0' &&
+           (set->workarounds & SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH) != 0)
+               path_parse_flags |= SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL;
+       if (smtp_address_parse_path_full(pool_datastack_create(), params,
+                                        path_parse_flags, &path, &error,
+                                        &params) < 0) {
                smtp_server_reply(cmd, 501, "5.5.4", "Invalid FROM: %s", error);
                return;
        }
index a3417b7b06f4fbe39971a13729ef83fa168efcee..15bb5d635986d5abc7813be426d94f9d21a5db61 100644 (file)
@@ -100,6 +100,7 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
        const struct smtp_server_callbacks *callbacks = conn->callbacks;
        struct smtp_server_command *command = cmd->cmd;
        struct smtp_server_cmd_rcpt *rcpt_data;
+       enum smtp_address_parse_flags path_parse_flags;
        struct smtp_address *path;
        enum smtp_param_parse_error pperror;
        const char *error;
@@ -120,9 +121,25 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
                        501, "5.5.4", "Invalid parameters");
                return;
        }
-       if (smtp_address_parse_path_full(pool_datastack_create(), params + 3,
-                                        SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART,
-                                        &path, &error, &params) < 0) {
+       if (params[3] != ' ' && params[3] != '\t') {
+               params += 3;
+       } else if ((set->workarounds &
+                   SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH) != 0) {
+               params += 3;
+               while (*params == ' ' || *params == '\t')
+                       params++;
+       } else {
+               smtp_server_reply(cmd, 501, "5.5.4",
+                                 "Invalid TO: "
+                                 "Unexpected whitespace before path");
+               return;
+       }
+       path_parse_flags = SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART;
+       if ((set->workarounds & SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH) != 0)
+               path_parse_flags |= SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL;
+       if (smtp_address_parse_path_full(pool_datastack_create(), params,
+                                        path_parse_flags, &path, &error,
+                                        &params) < 0) {
                smtp_server_reply(cmd,
                        501, "5.5.4", "Invalid TO: %s", error);
                return;
index cca0e570a3c91167834ed736d7e761b635338f05..1c0fdb33d4c497c1cbf3e7a1d1fffdce51b0f6e2 100644 (file)
@@ -794,6 +794,8 @@ smtp_server_connection_alloc(struct smtp_server *server,
                }
                if (set->capabilities != 0)
                        conn->set.capabilities = set->capabilities;
+               conn->set.workarounds |= set->workarounds;
+
                if (set->max_client_idle_time_msecs > 0) {
                        conn->set.max_client_idle_time_msecs =
                                set->max_client_idle_time_msecs;
index 003b6651fddb1eda4771d4153310b513e231bd66..54ada3700f1364f0f84c8aeec5b92a47dc570cee 100644 (file)
@@ -43,6 +43,7 @@ struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
        } else  {
                server->set.capabilities = set->capabilities;
        }
+       server->set.workarounds = set->workarounds;
        server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs;
        server->set.max_pipelined_commands = (set->max_pipelined_commands > 0 ?
                set->max_pipelined_commands : 1);
index 98c5e420bbd76e04dda5ea62a1660884f2962cc5..bc749b06f2176e954633d1e85f9ee424e15cbbab 100644 (file)
@@ -226,9 +226,15 @@ struct smtp_server_callbacks {
  * Server
  */
 
+enum smtp_server_workarounds {
+       SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH   = BIT(0),
+       SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH         = BIT(1)
+};
+
 struct smtp_server_settings {
        enum smtp_protocol protocol;
        enum smtp_capability capabilities;
+       enum smtp_server_workarounds workarounds;
 
        const char *hostname;
        const char *login_greeting;