]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: address: Add source syntax check for conversion from RFC5322 addresses.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Tue, 6 Mar 2018 20:43:22 +0000 (21:43 +0100)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Mon, 16 Apr 2018 08:14:53 +0000 (11:14 +0300)
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.

src/lib-lda/mail-deliver.c
src/lib-smtp/smtp-address.c
src/lib-smtp/smtp-address.h
src/lib-smtp/smtp-params.c

index b7aa4ee883aca22110e914549eaf408ba3a81e72..ce5f2b5ab628708cde3dfd3faa56f297113d144e 100644 (file)
@@ -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)
index 9969c36a974d3c69337d75e300fb609c24837514..72e5c08bfb31b394f63f68a45ff51489e3d38be5 100644 (file)
@@ -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 *
index a822b981d968b1a7ea45d341446dde52fc0fa080..2556e4feabc35ed7254b01c6a551c3ee6abc1ee5 100644 (file)
@@ -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,
index d677aa5e01b96d1fb7227ae97bb6aa4e9715b9e2..ac8aa66ef34436ad3a2c43c86167b9f6fb6d692d 100644 (file)
@@ -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;
 }