]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: smtp-params - Add support for parsing RCPT ORCPT parameter without domain.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 8 Oct 2019 22:25:41 +0000 (00:25 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 7 Nov 2019 07:34:34 +0000 (07:34 +0000)
src/lib-smtp/smtp-params.c
src/lib-smtp/smtp-params.h
src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/test-smtp-params.c

index 9cec2146e4d95c1a3a3df8ee13db276b8039566e..c1293a9913af4e57c1714904230d84fef42087b4 100644 (file)
@@ -748,6 +748,7 @@ void smtp_params_mail_add_to_event(const struct smtp_params_mail *params,
 struct smtp_params_rcpt_parser {
        pool_t pool;
        struct smtp_params_rcpt *params;
+       enum smtp_param_rcpt_parse_flags flags;
        enum smtp_capability caps;
 
        enum smtp_param_parse_error error_code;
@@ -827,7 +828,8 @@ smtp_params_rcpt_parse_notify(struct smtp_params_rcpt_parser *prparser,
 }
 
 static int
-smtp_params_rcpt_parse_orcpt_rfc822(const char *addr_str, pool_t pool,
+smtp_params_rcpt_parse_orcpt_rfc822(struct smtp_params_rcpt_parser *prparser,
+                                   const char *addr_str, pool_t pool,
                                    const struct smtp_address **addr_r)
 {
        struct message_address *rfc822_addr;
@@ -836,9 +838,17 @@ smtp_params_rcpt_parse_orcpt_rfc822(const char *addr_str, pool_t pool,
        rfc822_addr = message_address_parse(pool_datastack_create(),
                                            (const unsigned char *)addr_str,
                                            strlen(addr_str), 2, 0);
-       if (rfc822_addr == NULL || rfc822_addr->invalid_syntax ||
-           rfc822_addr->next != NULL ||
-           smtp_address_create_from_msg(pool, rfc822_addr, &addr) < 0)
+       if (rfc822_addr == NULL || rfc822_addr->next != NULL)
+               return -1;
+       if (rfc822_addr->invalid_syntax) {
+               if (HAS_NO_BITS(prparser->flags,
+                               SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART) ||
+                   rfc822_addr->mailbox == NULL ||
+                   *rfc822_addr->mailbox == '\0')
+                       return -1;
+               rfc822_addr->invalid_syntax = FALSE;
+       }
+       if (smtp_address_create_from_msg(pool, rfc822_addr, &addr) < 0)
                return -1;
        *addr_r = addr;
        return 0;
@@ -935,7 +945,7 @@ smtp_params_rcpt_parse_orcpt(struct smtp_params_rcpt_parser *prparser,
 
        if (strcasecmp(params->orcpt.addr_type, "rfc822") == 0) {
                if (smtp_params_rcpt_parse_orcpt_rfc822(
-                       params->orcpt.addr_raw, prparser->pool,
+                       prparser, params->orcpt.addr_raw, prparser->pool,
                        &params->orcpt.addr) < 0) {
                        prparser->error = "Invalid ORCPT= address value: "
                                "Invalid RFC822 address";
@@ -948,6 +958,7 @@ smtp_params_rcpt_parse_orcpt(struct smtp_params_rcpt_parser *prparser,
 }
 
 int smtp_params_rcpt_parse(pool_t pool, const char *args,
+                          enum smtp_param_rcpt_parse_flags flags,
                           enum smtp_capability caps,
                           const char *const *extensions,
                           struct smtp_params_rcpt *params_r,
@@ -965,6 +976,7 @@ int smtp_params_rcpt_parse(pool_t pool, const char *args,
        i_zero(&prparser);
        prparser.pool = pool;
        prparser.params = params_r;
+       prparser.flags = flags;
        prparser.caps = caps;
 
        argv = t_strsplit(args, " ");
index 86970f49f803177bff92a69ebbe2a5b140cf81c0..451d11005a48467c5602eafe2ff6b1dd31c6aeb9 100644 (file)
@@ -130,7 +130,13 @@ void smtp_params_mail_add_to_event(const struct smtp_params_mail *params,
 
 /* parse */
 
+enum smtp_param_rcpt_parse_flags {
+       /* Allow address values without a domain part */
+       SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART = BIT(0),
+};
+
 int smtp_params_rcpt_parse(pool_t pool, const char *args,
+                          enum smtp_param_rcpt_parse_flags flags,
                           enum smtp_capability caps,
                           const char *const *param_extensions,
                           struct smtp_params_rcpt *params_r,
index c77634d109c481174fdf014ef18f987de8357963..12374e355c5801b1a918034e56cdbad110508324 100644 (file)
@@ -104,6 +104,7 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
        struct smtp_server_cmd_rcpt *rcpt_data;
        struct smtp_server_recipient *rcpt;
        enum smtp_address_parse_flags path_parse_flags;
+       enum smtp_param_rcpt_parse_flags param_parse_flags;
        const char *const *param_extensions = NULL;
        struct smtp_address *path;
        struct smtp_params_rcpt rcpt_params;
@@ -164,11 +165,14 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
        }
 
        /* [SP Rcpt-parameters] */
+       param_parse_flags = 0;
+       if (conn->set.rcpt_domain_optional)
+               param_parse_flags |= SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART;
        if (array_is_created(&conn->rcpt_param_extensions))
                param_extensions = array_front(&conn->rcpt_param_extensions);
-       if (smtp_params_rcpt_parse(pool_datastack_create(), params, caps,
-                                  param_extensions, &rcpt_params, &pperror,
-                                  &error) < 0) {
+       if (smtp_params_rcpt_parse(pool_datastack_create(), params,
+                                  param_parse_flags, caps, param_extensions,
+                                  &rcpt_params, &pperror, &error) < 0) {
                switch (pperror) {
                case SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX:
                        smtp_server_reply(cmd,
index 1e03afc47aa0d04f3fc21717ec8e4e0700d95859..35e215beba2e954ced66b4d9415b90c3c3faa8c6 100644 (file)
@@ -521,6 +521,7 @@ static void test_smtp_mail_params_parse_invalid(void)
 struct valid_rcpt_params_parse_test {
        const char *input, *output;
 
+       enum smtp_param_rcpt_parse_flags flags;
        enum smtp_capability caps;
        const char *const *extensions;
 
@@ -530,11 +531,28 @@ struct valid_rcpt_params_parse_test {
 static const struct valid_rcpt_params_parse_test
 valid_rcpt_params_parse_tests[] = {
        /* ORCPT */
-#if 0 // FIXME: message_address_parser() does not allow bare localpart
-      //         addresses.
        {
-
+               .input = "ORCPT=rfc822;e+3Dmc2@example.com",
+               .caps = SMTP_CAPABILITY_DSN,
+               .params = {
+                       .orcpt = {
+                               .addr = &test_address3
+                       }
+               }
+       },
+       {
+               .input = "ORCPT=rfc822;<e+3Dmc2@example.com>",
+               .output = "ORCPT=rfc822;e+3Dmc2@example.com",
+               .caps = SMTP_CAPABILITY_DSN,
+               .params = {
+                       .orcpt = {
+                               .addr = &test_address3
+                       }
+               }
+       },
+       {
                .input = "ORCPT=rfc822;user+2Bdetail",
+               .flags = SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART,
                .caps = SMTP_CAPABILITY_DSN,
                .params = {
                        .orcpt = {
@@ -542,13 +560,14 @@ valid_rcpt_params_parse_tests[] = {
                        }
                }
        },
-#endif
        {
-               .input = "ORCPT=rfc822;e+3Dmc2@example.com",
+               .input = "ORCPT=rfc822;<user+2Bdetail>",
+               .output = "ORCPT=rfc822;user+2Bdetail",
+               .flags = SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART,
                .caps = SMTP_CAPABILITY_DSN,
                .params = {
                        .orcpt = {
-                               .addr = &test_address3
+                               .addr = &test_address2
                        }
                }
        },
@@ -755,8 +774,8 @@ static void test_smtp_rcpt_params_parse_valid(void)
 
                test = &valid_rcpt_params_parse_tests[i];
                ret = smtp_params_rcpt_parse(pool_datastack_create(),
-                                            test->input, test->caps,
-                                            test->extensions,
+                                            test->input, test->flags,
+                                            test->caps, test->extensions,
                                             &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp rcpt params valid [%d]", i));
@@ -793,6 +812,7 @@ static void test_smtp_rcpt_params_parse_valid(void)
 struct invalid_rcpt_params_parse_test {
        const char *input;
 
+       enum smtp_param_rcpt_parse_flags flags;
        enum smtp_capability caps;
        const char *const *extensions;
 };
@@ -803,6 +823,14 @@ invalid_rcpt_params_parse_tests[] = {
        {
                .input = "ORCPT=rfc822;frop@example.com",
        },
+       {
+               .input = "ORCPT=rfc822;<>",
+               .caps = SMTP_CAPABILITY_DSN
+       },
+       {
+               .input = "ORCPT=rfc822;",
+               .caps = SMTP_CAPABILITY_DSN
+       },
        {
                .input = "ORCPT=++",
                .caps = SMTP_CAPABILITY_DSN
@@ -840,8 +868,8 @@ static void test_smtp_rcpt_params_parse_invalid(void)
 
                test = &invalid_rcpt_params_parse_tests[i];
                ret = smtp_params_rcpt_parse(pool_datastack_create(),
-                                            test->input, test->caps,
-                                            test->extensions,
+                                            test->input, test->flags,
+                                            test->caps, test->extensions,
                                             &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp rcpt params invalid [%d]", i));