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;
}
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;
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;
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";
}
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,
i_zero(&prparser);
prparser.pool = pool;
prparser.params = params_r;
+ prparser.flags = flags;
prparser.caps = caps;
argv = t_strsplit(args, " ");
/* 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,
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;
}
/* [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,
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;
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 = {
}
}
},
-#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
}
}
},
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));
struct invalid_rcpt_params_parse_test {
const char *input;
+ enum smtp_param_rcpt_parse_flags flags;
enum smtp_capability caps;
const char *const *extensions;
};
{
.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
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));