Skip to content

Commit

Permalink
lib-smtp: address: Add source syntax check for conversion from RFC532…
Browse files Browse the repository at this point in the history
…2 addresses.

The message-address parser (for RFC 5322) allows UTF-8 characters in the
localpart, which is not acceptable for SMTP addresses. This change adds a check
that determines whether the source RFC5222 address can be converted into a
SMTP address.
  • Loading branch information
stephanbosch authored and sirainen committed Apr 12, 2018
1 parent 78345c6 commit 6719b6c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 26 deletions.
13 changes: 8 additions & 5 deletions src/lib-lda/mail-deliver.c
Expand Up @@ -86,11 +86,13 @@ const struct smtp_address *
mail_deliver_get_address(struct mail *mail, const char *header)
{
struct message_address *addr;
struct smtp_address *smtp_addr;

addr = mail_deliver_get_message_address(mail, header);
if (addr == NULL)
if (addr == NULL ||
smtp_address_create_from_msg_temp(addr, &smtp_addr) < 0)
return NULL;
return smtp_address_create_from_msg_temp(addr);
return smtp_addr;
}

static void update_cache(pool_t pool, const char **old_str, const char *new_str)
Expand Down Expand Up @@ -421,6 +423,7 @@ const struct smtp_address *
mail_deliver_get_return_address(struct mail_deliver_context *ctx)
{
struct message_address *addr;
struct smtp_address *smtp_addr;
const char *path;
int ret;

Expand All @@ -438,12 +441,12 @@ mail_deliver_get_return_address(struct mail_deliver_context *ctx)
}
if (message_address_parse_path(pool_datastack_create(),
(const unsigned char *)path,
strlen(path), &addr) < 0) {
strlen(path), &addr) < 0 ||
smtp_address_create_from_msg(ctx->pool, addr, &smtp_addr) < 0) {
i_warning("Failed to parse return-path header");
return NULL;
}

return smtp_address_create_from_msg(ctx->pool, addr);
return smtp_addr;
}

const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
Expand Down
47 changes: 35 additions & 12 deletions src/lib-smtp/smtp-address.c
Expand Up @@ -591,12 +591,26 @@ void smtp_address_init(struct smtp_address *address,
address->domain = (localpart == NULL ? NULL : domain);
}

void smtp_address_init_from_msg(struct smtp_address *address,
const struct message_address *msg_addr)
int smtp_address_init_from_msg(struct smtp_address *address,
const struct message_address *msg_addr)
{
const char *p;

i_zero(address);
if (msg_addr->mailbox == NULL)
return 0;

/* The message_address_parse() function allows UTF-8 codepoints in
the localpart. For SMTP addresses that is not an option, so we
need to check this upon conversion. */
for (p = msg_addr->mailbox; *p != '\0'; p++) {
if (!smtp_char_is_qpair(*p))
return -1;
}

address->localpart = msg_addr->mailbox;
address->domain = (msg_addr->mailbox == NULL ? NULL : msg_addr->domain);
address->domain = msg_addr->domain;
return 0;
}

struct smtp_address *
Expand Down Expand Up @@ -643,14 +657,19 @@ smtp_address_create(pool_t pool,
return smtp_address_clone(pool, &addr);
}

struct smtp_address *
smtp_address_create_from_msg(pool_t pool,
const struct message_address *msg_addr)

int smtp_address_create_from_msg(pool_t pool,
const struct message_address *msg_addr,
struct smtp_address **address_r)
{
struct smtp_address addr;

smtp_address_init_from_msg(&addr, msg_addr);
return smtp_address_clone(pool, &addr);
if (smtp_address_init_from_msg(&addr, msg_addr) < 0) {
*address_r = NULL;
return -1;
}
*address_r = smtp_address_clone(pool, &addr);
return 0;
}

struct smtp_address *
Expand All @@ -676,13 +695,17 @@ smtp_address_create_temp(const char *localpart, const char *domain)
return smtp_address_clone_temp(&addr);
}

struct smtp_address *
smtp_address_create_from_msg_temp(const struct message_address *msg_addr)
int smtp_address_create_from_msg_temp(const struct message_address *msg_addr,
struct smtp_address **address_r)
{
struct smtp_address addr;

smtp_address_init_from_msg(&addr, msg_addr);
return smtp_address_clone_temp(&addr);
if (smtp_address_init_from_msg(&addr, msg_addr) < 0) {
*address_r = NULL;
return -1;
}
*address_r = smtp_address_clone_temp(&addr);
return 0;
}

struct smtp_address *
Expand Down
14 changes: 7 additions & 7 deletions src/lib-smtp/smtp-address.h
Expand Up @@ -79,27 +79,27 @@ smtp_address_encode_path(const struct smtp_address *address)

void smtp_address_init(struct smtp_address *address,
const char *localpart, const char *domain) ATTR_NULL(2,3);
void smtp_address_init_from_msg(struct smtp_address *address,
const struct message_address *msg_addr);
int smtp_address_init_from_msg(struct smtp_address *address,
const struct message_address *msg_addr);

struct smtp_address *
smtp_address_clone(pool_t pool, const struct smtp_address *address)
ATTR_NULL(2);
struct smtp_address *
smtp_address_create(pool_t pool, const char *localpart, const char *domain)
ATTR_NULL(2, 3);
struct smtp_address *
smtp_address_create_from_msg(pool_t pool,
const struct message_address *msg_addr);
int smtp_address_create_from_msg(pool_t pool,
const struct message_address *msg_addr,
struct smtp_address **address_r);

struct smtp_address *
smtp_address_clone_temp(const struct smtp_address *address)
ATTR_NULL(1);
struct smtp_address *
smtp_address_create_temp(const char *localpart, const char *domain)
ATTR_NULL(2, 3);
struct smtp_address *
smtp_address_create_from_msg_temp(const struct message_address *msg_addr);
int smtp_address_create_from_msg_temp(const struct message_address *msg_addr,
struct smtp_address **address_r);

struct smtp_address *
smtp_address_add_detail(pool_t pool, const struct smtp_address *address,
Expand Down
6 changes: 4 additions & 2 deletions src/lib-smtp/smtp-params.c
Expand Up @@ -705,13 +705,15 @@ smtp_params_rcpt_parse_orcpt_rfc822(const char *addr_str,
pool_t pool, const struct smtp_address **addr_r)
{
struct message_address *rfc822_addr;
struct smtp_address *addr;

rfc822_addr = message_address_parse(pool_datastack_create(),
(const unsigned char *)addr_str, strlen(addr_str), 2, FALSE);
if (rfc822_addr == NULL || rfc822_addr->invalid_syntax ||
rfc822_addr->next != NULL)
rfc822_addr->next != NULL ||
smtp_address_create_from_msg(pool, rfc822_addr, &addr) < 0)
return -1;
*addr_r = smtp_address_create_from_msg(pool, rfc822_addr);
*addr_r = addr;
return 0;
}

Expand Down

0 comments on commit 6719b6c

Please sign in to comment.