diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c index b7aa4ee883..ce5f2b5ab6 100644 --- a/src/lib-lda/mail-deliver.c +++ b/src/lib-lda/mail-deliver.c @@ -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) @@ -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; @@ -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) diff --git a/src/lib-smtp/smtp-address.c b/src/lib-smtp/smtp-address.c index 9969c36a97..72e5c08bfb 100644 --- a/src/lib-smtp/smtp-address.c +++ b/src/lib-smtp/smtp-address.c @@ -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 * @@ -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 * @@ -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 * diff --git a/src/lib-smtp/smtp-address.h b/src/lib-smtp/smtp-address.h index a822b981d9..2556e4feab 100644 --- a/src/lib-smtp/smtp-address.h +++ b/src/lib-smtp/smtp-address.h @@ -79,8 +79,8 @@ 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) @@ -88,9 +88,9 @@ smtp_address_clone(pool_t pool, const struct smtp_address *address) 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) @@ -98,8 +98,8 @@ smtp_address_clone_temp(const struct smtp_address *address) 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, diff --git a/src/lib-smtp/smtp-params.c b/src/lib-smtp/smtp-params.c index d677aa5e01..ac8aa66ef3 100644 --- a/src/lib-smtp/smtp-params.c +++ b/src/lib-smtp/smtp-params.c @@ -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; }