]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: params: Allow only specific custom parameter extensions, rather than any...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 13 Sep 2018 20:48:51 +0000 (22:48 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 10 Oct 2018 10:20:37 +0000 (10:20 +0000)
Before the choice was between allowing any extension or none.

src/lib-smtp/smtp-params.c
src/lib-smtp/smtp-params.h
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
src/lib-smtp/test-smtp-params.c

index 8e9786f7659b4a7df905f756c3124e6174d35459..9217d3ffdf1f1e3ce5b8b4f86386bfb5e827f66b 100644 (file)
@@ -171,7 +171,7 @@ static int smtp_params_mail_parse_auth(
 
 static int smtp_params_mail_parse_body(
        struct smtp_params_mail_parser *pmparser,
-       const char *value, bool extensions)
+       const char *value, const char *const *extensions)
 {
        struct smtp_params_mail *params = pmparser->params;
        enum smtp_capability caps = pmparser->caps;
@@ -206,7 +206,8 @@ static int smtp_params_mail_parse_body(
                        strcmp(value, "BINARYMIME") == 0) {
                params->body.type = SMTP_PARAM_MAIL_BODY_TYPE_BINARYMIME;
        /* =?? */
-       } else if (extensions) {
+       } else if (extensions != NULL &&
+                  str_array_icase_find(extensions, value)) {
                params->body.type = SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION;
                params->body.ext = p_strdup(pmparser->pool, value);
        } else {
@@ -333,10 +334,12 @@ smtp_params_mail_parse_size(
 }
 
 int smtp_params_mail_parse(pool_t pool, const char *args,
-       enum smtp_capability caps, bool extensions,
-       struct smtp_params_mail *params_r,
-       enum smtp_param_parse_error *error_code_r,
-       const char **error_r)
+                          enum smtp_capability caps,
+                          const char *const *extensions,
+                          const char *const *body_extensions,
+                          struct smtp_params_mail *params_r,
+                          enum smtp_param_parse_error *error_code_r,
+                          const char **error_r)
 {
        struct smtp_params_mail_parser pmparser;
        struct smtp_param param;
@@ -371,8 +374,8 @@ int smtp_params_mail_parse(pool_t pool, const char *args,
                                break;
                        }
                } else if (strcmp(param.keyword, "BODY") == 0) {
-                       if (smtp_params_mail_parse_body
-                               (&pmparser, param.value, extensions) < 0) {
+                       if (smtp_params_mail_parse_body(
+                               &pmparser, param.value, body_extensions) < 0) {
                                ret = -1;
                                break;
                        }
@@ -397,7 +400,8 @@ int smtp_params_mail_parse(pool_t pool, const char *args,
                                ret = -1;
                                break;
                        }
-               } else if (extensions) {
+               } else if (extensions != NULL &&
+                          str_array_icase_find(extensions, param.keyword)) {
                        /* add the rest to ext_param for specific
                           applications */
                        if (!array_is_created(&params_r->extra_params))
@@ -823,10 +827,11 @@ smtp_params_rcpt_parse_orcpt(struct smtp_params_rcpt_parser *prparser,
 }
 
 int smtp_params_rcpt_parse(pool_t pool, const char *args,
-       enum smtp_capability caps, bool extensions,
-       struct smtp_params_rcpt *params_r,
-       enum smtp_param_parse_error *error_code_r,
-       const char **error_r)
+                          enum smtp_capability caps,
+                          const char *const *extensions,
+                          struct smtp_params_rcpt *params_r,
+                          enum smtp_param_parse_error *error_code_r,
+                          const char **error_r)
 {
        struct smtp_params_rcpt_parser prparser;
        struct smtp_param param;
@@ -868,7 +873,8 @@ int smtp_params_rcpt_parse(pool_t pool, const char *args,
                                ret = -1;
                                break;
                        }
-               } else if (extensions) {
+               } else if (extensions != NULL &&
+                          str_array_icase_find(extensions, param.keyword)) {
                        /* add the rest to ext_param for specific applications
                         */
                        if (!array_is_created(&params_r->extra_params))
index fe9d77938802b698388c6e6194a123c40ef2343d..11cfb66ed496c675a581d545585536ec481208fe 100644 (file)
@@ -87,10 +87,12 @@ void smtp_param_write(string_t *out, const struct smtp_param *param);
  */
 
 int smtp_params_mail_parse(pool_t pool, const char *args,
-       enum smtp_capability caps, bool extensions,
-       struct smtp_params_mail *params_r,
-       enum smtp_param_parse_error *error_code_r,
-       const char **error_r);
+                          enum smtp_capability caps,
+                          const char *const *param_extensions,
+                          const char *const *body_param_extensions,
+                          struct smtp_params_mail *params_r,
+                          enum smtp_param_parse_error *error_code_r,
+                          const char **error_r) ATTR_NULL(4, 5);
 
 void smtp_params_mail_copy(pool_t pool,
        struct smtp_params_mail *dst, const struct smtp_params_mail *src)
@@ -109,10 +111,11 @@ smtp_params_mail_get_extra(const struct smtp_params_mail *params,
  */
 
 int smtp_params_rcpt_parse(pool_t pool, const char *args,
-       enum smtp_capability caps, bool extensions,
-       struct smtp_params_rcpt *params_r,
-       enum smtp_param_parse_error *error_code_r,
-       const char **error_r);
+                          enum smtp_capability caps,
+                          const char *const *param_extensions,
+                          struct smtp_params_rcpt *params_r,
+                          enum smtp_param_parse_error *error_code_r,
+                          const char **error_r) ATTR_NULL(4);
 
 void smtp_params_rcpt_copy(pool_t pool,
        struct smtp_params_rcpt *dst, const struct smtp_params_rcpt *src)
index e9ee4b09dbbc986ad1d64758160b1f1b315e5cbc..b4b5b8a482480c4787edcc235bc9a49038b73b48 100644 (file)
@@ -140,8 +140,8 @@ void smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd,
 
        /* [SP Mail-parameters] */
        if (smtp_params_mail_parse(cmd->pool, params, caps,
-                                  set->param_extensions, &mail_data->params,
-                                  &pperror, &error) < 0) {
+                                  set->mail_param_extensions, NULL,
+                                  &mail_data->params, &pperror, &error) < 0) {
                switch (pperror) {
                case SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX:
                        smtp_server_reply(cmd, 501, "5.5.4", "%s", error);
index 2ce34fd67f4c388e389d6eb992591cc02599306d..f05f05d96a002352062af7385886541160c215e8 100644 (file)
@@ -156,8 +156,8 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
 
        /* [SP Rcpt-parameters] */
        if (smtp_params_rcpt_parse(cmd->pool, params, caps,
-                                  set->param_extensions, &rcpt_data->params,
-                                  &pperror, &error) < 0) {
+                                  set->rcpt_param_extensions,
+                                  &rcpt_data->params, &pperror, &error) < 0) {
                switch (pperror) {
                case SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX:
                        smtp_server_reply(cmd,
index 00505332a8f07075229f0c5d244b0765cbfe3c05..82689498be00d474c53ca8e8a005915184a2555a 100644 (file)
@@ -874,6 +874,14 @@ smtp_server_connection_alloc(struct smtp_server *server,
                                        SMTP_SERVER_DEFAULT_MAX_SIZE_EXCESS_LIMIT;
                }
 
+               if (set->mail_param_extensions != NULL) {
+                       conn->set.mail_param_extensions =
+                               p_strarray_dup(pool, set->mail_param_extensions);
+               }
+               if (set->rcpt_param_extensions != NULL) {
+                       conn->set.rcpt_param_extensions =
+                               p_strarray_dup(pool, set->rcpt_param_extensions);
+               }
                if (set->xclient_extensions != NULL) {
                        server->set.xclient_extensions =
                                p_strarray_dup(pool, set->xclient_extensions);
@@ -895,8 +903,6 @@ smtp_server_connection_alloc(struct smtp_server *server,
                conn->set.rcpt_domain_optional =
                        conn->set.rcpt_domain_optional ||
                                set->rcpt_domain_optional;
-               conn->set.param_extensions =
-                       conn->set.param_extensions || set->param_extensions;
                conn->set.debug = conn->set.debug || set->debug;
        }
 
index d83652046e8aaa44c119350ed20ea646791a9c19..4bc6e5df2a6c8fae2add0eb4b7e7bbc7361ba854 100644 (file)
@@ -59,6 +59,14 @@ struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
        server->set.command_limits = set->command_limits;
        server->set.max_message_size = set->max_message_size;
 
+       if (set->mail_param_extensions != NULL) {
+               server->set.mail_param_extensions =
+                       p_strarray_dup(pool, set->mail_param_extensions);
+       }
+       if (set->rcpt_param_extensions != NULL) {
+               server->set.rcpt_param_extensions =
+                       p_strarray_dup(pool, set->rcpt_param_extensions);
+       }
        if (set->xclient_extensions != NULL) {
                server->set.xclient_extensions =
                        p_strarray_dup(pool, set->xclient_extensions);
@@ -70,7 +78,6 @@ struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
        server->set.tls_required = set->tls_required;
        server->set.auth_optional = set->auth_optional;
        server->set.rcpt_domain_optional = set->rcpt_domain_optional;
-       server->set.param_extensions = set->param_extensions;
        server->set.debug = set->debug;
 
        server->conn_list = smtp_server_connection_list_init();
index c65f2165bccc26e87fce79a43c2fad867ea31e30..9e5a9058e905927457e29bbf0137e3ef58106317 100644 (file)
@@ -266,6 +266,10 @@ struct smtp_server_settings {
        /* message size limit */
        uoff_t max_message_size;
 
+       /* accept these additional custom MAIL parameters */
+       const char *const *mail_param_extensions;
+       /* accept these additional custom RCPT parameters */
+       const char *const *rcpt_param_extensions;
        /* accept these additional custom XCLIENT fields */
        const char *const *xclient_extensions;
 
@@ -279,7 +283,6 @@ struct smtp_server_settings {
        bool auth_optional:1;
        bool tls_required:1;
        bool rcpt_domain_optional:1;
-       bool param_extensions:1;
 };
 
 struct smtp_server_stats {
index 5c0384ba82cdec7af01848b41e6a68e2b47093a1..ac05e1cad03471265676d72e665b47ba71a4d946 100644 (file)
@@ -8,6 +8,8 @@
 #include "smtp-address.h"
 #include "smtp-params.h"
 
+static const char *test_extensions[] = { "FROP", "FRUP", NULL };
+
 static struct smtp_address test_address1 =
        { .localpart = NULL, .domain = NULL };
 static struct smtp_address test_address2 =
@@ -38,7 +40,8 @@ struct valid_mail_params_parse_test {
        const char *input, *output;
 
        enum smtp_capability caps;
-       bool extensions;
+       const char *const *extensions;
+       const char *const *body_extensions;
 
        struct smtp_params_mail params;
 };
@@ -104,7 +107,7 @@ valid_mail_params_parse_tests[] = {
                .caps = SMTP_CAPABILITY_8BITMIME |
                        SMTP_CAPABILITY_BINARYMIME |
                        SMTP_CAPABILITY_CHUNKING,
-               .extensions = TRUE,
+               .body_extensions = test_extensions,
                .params = {
                        .body = {
                                .type = SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION,
@@ -172,7 +175,7 @@ valid_mail_params_parse_tests[] = {
        },{
                .input = "FROP=friep",
                .caps = SMTP_CAPABILITY_SIZE,
-               .extensions = TRUE,
+               .extensions = test_extensions,
                .params = {
                        .extra_params = {
                                .arr = {
@@ -183,7 +186,7 @@ valid_mail_params_parse_tests[] = {
                }
        },{
                .input = "FROP=friep FRUP=frml",
-               .extensions = TRUE,
+               .extensions = test_extensions,
                .params = {
                        .extra_params = {
                                .arr = {
@@ -365,8 +368,8 @@ static void test_smtp_mail_params_parse_valid(void)
 
                test = &valid_mail_params_parse_tests[i];
                ret = smtp_params_mail_parse(pool_datastack_create(),
-                       test->input, test->caps, test->extensions, &params,
-                       &error_code, &error);
+                       test->input, test->caps, test->extensions,
+                       test->body_extensions, &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp mail params valid [%d]", i));
                test_out_reason(t_strdup_printf("parse(\"%s\")",
@@ -392,7 +395,7 @@ static void test_smtp_mail_params_parse_valid(void)
                        if ((test->caps & SMTP_CAPABILITY_SIZE) != 0)
                                test_smtp_mail_params_size(&test->params, &params);
                        /* <extensions> */
-                       if (test->extensions)
+                       if (test->extensions != NULL)
                                test_smtp_mail_params_extensions(&test->params, &params);
 
                        encoded = t_str_new(256);
@@ -413,7 +416,7 @@ struct invalid_mail_params_parse_test {
        const char *input;
 
        enum smtp_capability caps;
-       bool extensions;
+       const char *const *extensions;
 };
 
 static const struct invalid_mail_params_parse_test
@@ -474,8 +477,8 @@ static void test_smtp_mail_params_parse_invalid(void)
 
                test = &invalid_mail_params_parse_tests[i];
                ret = smtp_params_mail_parse(pool_datastack_create(),
-                       test->input, test->caps, test->extensions, &params,
-                       &error_code, &error);
+                       test->input, test->caps, test->extensions, NULL,
+                       &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp mail params invalid [%d]", i));
                test_out_reason(t_strdup_printf("parse(\"%s\")",
@@ -490,7 +493,7 @@ struct valid_rcpt_params_parse_test {
        const char *input, *output;
 
        enum smtp_capability caps;
-       bool extensions;
+       const char *const *extensions;
 
        struct smtp_params_rcpt params;
 };
@@ -560,7 +563,7 @@ valid_rcpt_params_parse_tests[] = {
        },{
                .input = "FROP=friep",
                .caps = SMTP_CAPABILITY_SIZE,
-               .extensions = TRUE,
+               .extensions = test_extensions,
                .params = {
                        .extra_params = {
                                .arr = {
@@ -571,7 +574,7 @@ valid_rcpt_params_parse_tests[] = {
                }
        },{
                .input = "FROP=friep FRUP=frml",
-               .extensions = TRUE,
+               .extensions = test_extensions,
                .params = {
                        .extra_params = {
                                .arr = {
@@ -714,8 +717,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, &params,
-                       &error_code, &error);
+                       test->input, test->caps, test->extensions,
+                       &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp rcpt params valid [%d]", i));
                test_out_reason(t_strdup_printf("parse(\"%s\")",
@@ -731,7 +734,7 @@ static void test_smtp_rcpt_params_parse_valid(void)
                        if ((test->caps & SMTP_CAPABILITY_DSN) != 0)
                                test_smtp_rcpt_params_notify(&test->params, &params);
                        /* <extensions> */
-                       if (test->extensions)
+                       if (test->extensions != NULL)
                                test_smtp_rcpt_params_extensions(&test->params, &params);
 
                        encoded = t_str_new(256);
@@ -752,7 +755,7 @@ struct invalid_rcpt_params_parse_test {
        const char *input;
 
        enum smtp_capability caps;
-       bool extensions;
+       const char *const *extensions;
 };
 
 static const struct invalid_rcpt_params_parse_test
@@ -793,8 +796,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, &params,
-                       &error_code, &error);
+                       test->input, test->caps, test->extensions,
+                       &params, &error_code, &error);
 
                test_begin(t_strdup_printf("smtp rcpt params invalid [%d]", i));
                test_out_reason(t_strdup_printf("parse(\"%s\")",