--- dovecot-2.2.33.2/src/lib-mail/message-address.c 2017-10-05 18:10:44.000000000 +0100 +++ dovecot-2.2.33.2.quoted-local-proxy/src/lib-mail/message-address.c 2017-11-02 12:21:57.572866755 +0000 @@ -34,7 +34,7 @@ } /* quote with "" and escape all '\', '"' and "'" characters if need */ -static void str_append_maybe_escape(string_t *dest, const char *cstr, bool escape_dot) +void str_append_maybe_escape(string_t *dest, const char *cstr, bool escape_dot) { const char *p; --- dovecot-2.2.33.2/src/lib-mail/message-address.h 2017-10-05 18:10:44.000000000 +0100 +++ dovecot-2.2.33.2.quoted-local-proxy/src/lib-mail/message-address.h 2017-11-02 13:22:45.093866755 +0000 @@ -39,4 +39,7 @@ const char *address, const char **username_r, const char **detail_r); +/* quote with "" and escape all '\', '"' and "'" characters if need */ +void str_append_maybe_escape(string_t *dest, const char *cstr, bool escape_dot); + #endif --- dovecot-2.2.33.2/src/lmtp/commands.c 2017-10-05 18:10:44.000000000 +0100 +++ dovecot-2.2.33.2.quoted-local-proxy/src/lmtp/commands.c 2017-11-02 13:50:25.794866755 +0000 @@ -441,34 +441,18 @@ static const char *lmtp_unescape_address(const char *name) { + struct rfc822_parser_context parser; string_t *str; - const char *p; if (*name != '"') return name; - /* quoted-string local-part. drop the quotes unless there's a - '@' character inside or there's an error. */ + /* decode quoted-string local-part */ str = t_str_new(128); - for (p = name+1; *p != '"'; p++) { - if (*p == '\0') - return name; - if (*p == '\\') { - if (p[1] == '\0') { - /* error */ - return name; - } - p++; - } - if (*p == '@') - return name; - str_append_c(str, *p); - } - p++; - if (*p != '@' && *p != '\0') - return name; + rfc822_parser_init(&parser, (const unsigned char*)name, strlen(name), NULL); + rfc822_parse_quoted_string(&parser, str); - str_append(str, p); + str_append(str, (const char*)parser.data); return str_c(str); } --- dovecot-2.2.33.2/src/lmtp/lmtp-proxy.c 2017-10-05 18:10:44.000000000 +0100 +++ dovecot-2.2.33.2.quoted-local-proxy/src/lmtp/lmtp-proxy.c 2017-11-02 13:49:41.154866755 +0000 @@ -8,6 +8,7 @@ #include "ostream.h" #include "str.h" #include "time-util.h" +#include "message-address.h" #include "lmtp-client.h" #include "lmtp-proxy.h" @@ -288,6 +289,24 @@ lmtp_proxy_try_finish(conn->proxy); } +static char *lmtp_proxy_escape_address(pool_t pool, const char *address) { + const char *domain; + string_t *dest; + + domain = strrchr(address, '@'); + dest = str_new(pool, 128); + + if (domain == NULL) { + str_append_maybe_escape(dest, address, FALSE); + } else { + const char *local_part = t_strdup_until(address, domain); + str_append_maybe_escape(dest, local_part, FALSE); + str_append(dest, domain); + } + + return str_free_without_data(&dest); +} + int lmtp_proxy_add_rcpt(struct lmtp_proxy *proxy, const char *address, const struct lmtp_proxy_rcpt_settings *set) { @@ -301,10 +320,10 @@ rcpt = p_new(proxy->pool, struct lmtp_proxy_recipient, 1); rcpt->idx = array_count(&proxy->rcpt_to); rcpt->conn = conn; - rcpt->address = p_strdup(proxy->pool, address); + rcpt->address = lmtp_proxy_escape_address(proxy->pool, address); array_append(&proxy->rcpt_to, &rcpt, 1); - lmtp_client_add_rcpt_params(conn->client, address, &set->params, + lmtp_client_add_rcpt_params(conn->client, rcpt->address, &set->params, lmtp_proxy_conn_rcpt_to, lmtp_proxy_conn_data, rcpt); return 0;