From: Stephan Bosch Date: Tue, 8 Oct 2019 22:25:41 +0000 (+0200) Subject: lib-smtp: smtp-params - Add support for parsing RCPT ORCPT parameter without domain. X-Git-Tag: 2.3.9~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac0d750621b9c4ded02bf927eef16e7a372e1f05;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: smtp-params - Add support for parsing RCPT ORCPT parameter without domain. --- diff --git a/src/lib-smtp/smtp-params.c b/src/lib-smtp/smtp-params.c index 9cec2146e4..c1293a9913 100644 --- a/src/lib-smtp/smtp-params.c +++ b/src/lib-smtp/smtp-params.c @@ -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, ¶ms->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, " "); diff --git a/src/lib-smtp/smtp-params.h b/src/lib-smtp/smtp-params.h index 86970f49f8..451d11005a 100644 --- a/src/lib-smtp/smtp-params.h +++ b/src/lib-smtp/smtp-params.h @@ -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, diff --git a/src/lib-smtp/smtp-server-cmd-rcpt.c b/src/lib-smtp/smtp-server-cmd-rcpt.c index c77634d109..12374e355c 100644 --- a/src/lib-smtp/smtp-server-cmd-rcpt.c +++ b/src/lib-smtp/smtp-server-cmd-rcpt.c @@ -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, diff --git a/src/lib-smtp/test-smtp-params.c b/src/lib-smtp/test-smtp-params.c index 1e03afc47a..35e215beba 100644 --- a/src/lib-smtp/test-smtp-params.c +++ b/src/lib-smtp/test-smtp-params.c @@ -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;", + .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;", + .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, ¶ms, &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, ¶ms, &error_code, &error); test_begin(t_strdup_printf("smtp rcpt params invalid [%d]", i));