Skip to content

Commit

Permalink
lib-smtp: params: Allow only specific custom parameter extensions, ra…
Browse files Browse the repository at this point in the history
…ther than any parameter.

Before the choice was between allowing any extension or none.
  • Loading branch information
stephanbosch authored and villesavolainen committed Feb 12, 2019
1 parent 2038f79 commit d9b1b65
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 49 deletions.
34 changes: 20 additions & 14 deletions src/lib-smtp/smtp-params.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down
19 changes: 11 additions & 8 deletions src/lib-smtp/smtp-params.h
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/lib-smtp/smtp-server-cmd-mail.c
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/lib-smtp/smtp-server-cmd-rcpt.c
Expand Up @@ -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,
Expand Down
10 changes: 8 additions & 2 deletions src/lib-smtp/smtp-server-connection.c
Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down
9 changes: 8 additions & 1 deletion src/lib-smtp/smtp-server.c
Expand Up @@ -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);
Expand All @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion src/lib-smtp/smtp-server.h
Expand Up @@ -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;

Expand All @@ -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 {
Expand Down
41 changes: 22 additions & 19 deletions src/lib-smtp/test-smtp-params.c
Expand Up @@ -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 =
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {
Expand All @@ -183,7 +186,7 @@ valid_mail_params_parse_tests[] = {
}
},{
.input = "FROP=friep FRUP=frml",
.extensions = TRUE,
.extensions = test_extensions,
.params = {
.extra_params = {
.arr = {
Expand Down Expand Up @@ -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\")",
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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\")",
Expand All @@ -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;
};
Expand Down Expand Up @@ -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 = {
Expand All @@ -571,7 +574,7 @@ valid_rcpt_params_parse_tests[] = {
}
},{
.input = "FROP=friep FRUP=frml",
.extensions = TRUE,
.extensions = test_extensions,
.params = {
.extra_params = {
.arr = {
Expand Down Expand Up @@ -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\")",
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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\")",
Expand Down

0 comments on commit d9b1b65

Please sign in to comment.