#include "unichar.h"
#include "rfc822-parser.h"
#include "message-address.h"
+#include "smtp-address.h"
#include "settings-parser.h"
#include "master-service.h"
#include "master-service-settings.h"
#include <stdio.h>
#include <sysexits.h>
-#define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
+#define DEFAULT_ENVELOPE_SENDER \
+ SMTP_ADDRESS_LITERAL("MAILER-DAEMON", NULL)
/* After buffer grows larger than this, create a temporary file to /tmp
where to read the mail. */
NULL
};
-static const char *escape_local_part(const char *local_part)
-{
- const char *p;
-
- /* if local_part isn't dot-atom-text, we need to return quoted-string
- dot-atom-text = 1*atext *("." 1*atext) */
- for (p = local_part; *p != '\0'; p++) {
- if (!IS_ATEXT(*p) && *p != '.')
- break;
- }
- if (*p != '\0' || *local_part == '.' ||
- (p != local_part && p[-1] == '.'))
- local_part = t_strdup_printf("\"%s\"", str_escape(local_part));
- return local_part;
-}
-
-static const char *address_sanitize(const char *address)
-{
- struct message_address *addr;
- const char *ret, *mailbox;
- pool_t pool;
-
- pool = pool_alloconly_create("address sanitizer", 256);
- addr = message_address_parse(pool, (const unsigned char *)address,
- strlen(address), 1, FALSE);
-
- if (addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
- *addr->mailbox == '\0')
- ret = DEFAULT_ENVELOPE_SENDER;
- else {
- mailbox = escape_local_part(addr->mailbox);
- if (*addr->domain == '\0')
- ret = t_strdup(mailbox);
- else
- ret = t_strdup_printf("%s@%s", mailbox, addr->domain);
- }
- pool_unref(&pool);
- return ret;
-}
-
static int seekable_fd_callback(const char **path_r, void *context)
{
struct mail_deliver_context *ctx = context;
{
struct istream *input, *input2, *input_list[2];
const unsigned char *data;
+ const char *error;
char *sender = NULL;
size_t i, size;
int ret, tz;
}
if (sender != NULL && ctx->mail_from == NULL) {
+ struct smtp_address *mail_from = NULL;
/* use the envelope sender from From_-line, but only if it
hasn't been specified with -f already. */
- ctx->mail_from = p_strdup(ctx->pool, sender);
+ if (smtp_address_parse_mailbox(ctx->pool,
+ sender, 0, &mail_from, &error) < 0) {
+ i_warning("Failed to parse address from `From_'-line: %s",
+ error);
+ }
+ ctx->mail_from = mail_from;
}
i_free(sender);
struct mailbox_transaction_context *t;
struct mail *mail;
struct mailbox_header_lookup_ctx *headers_ctx;
+ const struct smtp_address *mail_from;
struct istream *input;
void **sets;
- const char *mail_from;
time_t mtime;
int ret;
input = create_raw_stream(ctx, 0, &mtime);
i_stream_set_name(input, "stdin");
ret = raw_mailbox_alloc_stream(raw_mail_user, input, mtime,
- mail_from, &box);
+ smtp_address_encode(mail_from), &box);
i_stream_unref(&input);
} else {
ret = raw_mailbox_alloc_path(raw_mail_user, path, (time_t)-1,
- mail_from, &box);
+ smtp_address_encode(mail_from), &box);
}
if (ret < 0) {
i_fatal("Can't open delivery mail as raw: %s",
}
static void
-lda_set_rcpt_orig_to(struct mail_deliver_context *ctx, const char *user,
- const char *rcpt_to_source)
+lda_set_rcpt_to(struct mail_deliver_context *ctx,
+ const struct smtp_address *rcpt_to, const char *user,
+ const char *rcpt_to_source)
{
- if (ctx->rcpt_orig_to == NULL &&
+ const char *error;
+
+ if (rcpt_to == NULL &&
*ctx->set->lda_original_recipient_header != '\0') {
- ctx->rcpt_orig_to = mail_deliver_get_address(ctx->src_mail,
+ rcpt_to = mail_deliver_get_address(ctx->src_mail,
ctx->set->lda_original_recipient_header);
rcpt_to_source = t_strconcat(
ctx->set->lda_original_recipient_header, " header", NULL);
}
- if (ctx->rcpt_orig_to == NULL) {
- ctx->rcpt_orig_to = strchr(user, '@') != NULL ? user :
- t_strconcat(user, "@", ctx->set->hostname, NULL);
+ if (rcpt_to == NULL) {
+ struct smtp_address *user_addr;
+
+ if (smtp_address_parse_username(ctx->pool, user,
+ &user_addr, &error) < 0) {
+ i_fatal_status(EX_USAGE,
+ "Cannot obtain SMTP address from username `%s': %s",
+ user, error);
+ }
+ if (user_addr->domain == NULL)
+ user_addr->domain = ctx->set->hostname;
+ rcpt_to = user_addr;
rcpt_to_source = "user@hostname";
}
+
+ ctx->rcpt_orig_to = rcpt_to;
if (ctx->rcpt_to == NULL)
- ctx->rcpt_to = ctx->rcpt_orig_to;
+ ctx->rcpt_to = rcpt_to;
if (ctx->rcpt_user->mail_debug) {
i_debug("Destination address: %s (source: %s)",
- ctx->rcpt_orig_to, rcpt_to_source);
+ smtp_address_encode_path(rcpt_to), rcpt_to_source);
}
}
const char *user, *errstr, *path;
struct lda_settings *lda_set;
struct smtp_submit_settings *smtp_set;
+ struct smtp_address *rcpt_to, *final_rcpt_to, *mail_from;
struct mail_storage_service_ctx *storage_service;
struct mail_storage_service_user *service_user;
struct mail_storage_service_input service_input;
path = NULL;
user = getenv("USER");
+ mail_from = final_rcpt_to = rcpt_to = NULL;
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'a':
/* original recipient address */
- ctx.rcpt_orig_to = optarg;
+ if (smtp_address_parse_path(ctx.pool, optarg,
+ SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
+ SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL,
+ &rcpt_to, &errstr) < 0) {
+ i_fatal_status(EX_USAGE,
+ "Invalid -a parameter: %s", errstr);
+ }
rcpt_to_source = "-a parameter";
break;
case 'd':
break;
case 'f':
/* envelope sender address */
- ctx.mail_from =
- p_strdup(ctx.pool, address_sanitize(optarg));
+ if (smtp_address_parse_path(ctx.pool, optarg,
+ SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL,
+ &mail_from, &errstr) < 0) {
+ i_fatal_status(EX_USAGE,
+ "Invalid -f parameter: %s", errstr);
+ }
break;
case 'm':
/* destination mailbox.
break;
case 'r':
/* final recipient address */
- ctx.rcpt_to = optarg;
+ if (smtp_address_parse_path(ctx.pool, optarg,
+ SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
+ SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL,
+ &final_rcpt_to, &errstr) < 0) {
+ i_fatal_status(EX_USAGE,
+ "Invalid -a parameter: %s", errstr);
+ }
break;
default:
print_help();
user_source);
}
+ if (mail_from == NULL)
+ mail_from = DEFAULT_ENVELOPE_SENDER;
+
ctx.src_mail = lda_raw_mail_open(&ctx, path);
- lda_set_rcpt_orig_to(&ctx, user, rcpt_to_source);
+ ctx.mail_from = mail_from;
+ ctx.rcpt_to = final_rcpt_to;
+ lda_set_rcpt_to(&ctx, rcpt_to, user, rcpt_to_source);
if (mail_deliver(&ctx, &storage) < 0) {
if (ctx.tempfail_error != NULL) {
#include "unichar.h"
#include "var-expand.h"
#include "message-address.h"
+#include "smtp-address.h"
#include "lda-settings.h"
#include "mail-storage.h"
#include "mail-namespace.h"
static MODULE_CONTEXT_DEFINE_INIT(mail_deliver_storage_module,
&mail_storage_module_register);
-const char *mail_deliver_get_address(struct mail *mail, const char *header)
+const struct smtp_address *
+mail_deliver_get_address(struct mail *mail, const char *header)
{
struct message_address *addr;
const char *str;
strlen(str), 1, FALSE);
return addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
*addr->mailbox == '\0' || *addr->domain == '\0' ?
- NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL);
+ NULL : smtp_address_create_from_msg_temp(addr);
}
static void update_cache(pool_t pool, const char **old_str, const char *new_str)
subject = str_sanitize(subject, 80);
update_cache(pool, &cache->subject, subject);
- from = str_sanitize(mail_deliver_get_address(mail, "From"), 80);
+ from = smtp_address_encode(mail_deliver_get_address(mail, "From"));
update_cache(pool, &cache->from, from);
if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE, &from_envelope) > 0)
{ 'w', dec2str(ctx->cache->vsize), "vsize" },
{ '\0', dec2str(delivery_time_msecs), "delivery_time" },
{ '\0', dec2str(ctx->session_time_msecs), "session_time" },
- { '\0', ctx->rcpt_orig_to, "to_envelope" },
+ { '\0', smtp_address_encode(ctx->rcpt_orig_to), "to_envelope" },
{ '\0', ctx->cache->storage_id, "storage_id" },
{ '\0', NULL, NULL }
};
kw = str_array_length(keywords) == 0 ? NULL :
mailbox_keywords_create_valid(box, keywords);
save_ctx = mailbox_save_alloc(t);
- if (ctx->mail_from != NULL)
- mailbox_save_set_from_envelope(save_ctx, ctx->mail_from);
+ if (ctx->mail_from != NULL) {
+ mailbox_save_set_from_envelope(save_ctx,
+ smtp_address_encode(ctx->mail_from));
+ }
mailbox_save_set_flags(save_ctx, flags, kw);
headers_ctx = mailbox_header_lookup_init(box, lda_log_wanted_headers);
return ret;
}
-const char *mail_deliver_get_return_address(struct mail_deliver_context *ctx)
+const struct smtp_address *
+mail_deliver_get_return_address(struct mail_deliver_context *ctx)
{
+ struct smtp_address *address;
+ const char *path, *error;
+ int ret;
+
if (ctx->mail_from != NULL)
return ctx->mail_from;
- return mail_deliver_get_address(ctx->src_mail, "Return-Path");
+ if ((ret=mail_get_first_header(ctx->src_mail,
+ "Return-Path", &path)) <= 0) {
+ if (ret < 0) {
+ struct mailbox *box = ctx->src_mail->box;
+ i_warning("Failed read return-path header: %s",
+ mailbox_get_last_internal_error(box, NULL));
+ }
+ return NULL;
+ }
+ if (smtp_address_parse_path(ctx->pool, path,
+ SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL,
+ &address, &error) < 0) {
+ i_warning("Failed to parse return-path header: %s", error);
+ return NULL;
+ }
+ return address;
}
const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
#include "master-service-ssl.h"
#include "iostream-ssl.h"
#include "rfc822-parser.h"
+#include "smtp-address.h"
#include "message-date.h"
+#include "message-address.h"
#include "auth-master.h"
#include "mail-storage-service.h"
#include "index/raw/raw-storage.h"
return 0;
}
-static int parse_address(const char *str, const char **address_r,
- const char **rest_r)
-{
- const char *start;
-
- if (*str++ != '<')
- return -1;
- start = str;
- if (*str == '"') {
- /* "quoted-string"@domain */
- for (str++; *str != '"'; str++) {
- if (*str == '\\')
- str++;
- if (*str == '\0')
- return -1;
- }
- str++;
- }
- for (; *str != '>'; str++) {
- if (*str == '\0' || *str == ' ')
- return -1;
- }
- *address_r = t_strdup_until(start, str);
- if (*str++ != '>')
- return -1;
-
- if (*str == ' ')
- str++;
- else if (*str != '\0')
- return -1;
- *rest_r = str;
- return 0;
-}
-
static const char *
parse_xtext(struct client *client, const char *value)
{
int cmd_mail(struct client *client, const char *args)
{
- const char *addr, *const *argv;
+ struct smtp_address *address;
+ const char *const *argv;
+ const char *error;
if (client->state.mail_from != NULL) {
client_send_line(client, "503 5.5.1 MAIL already given");
return 0;
}
- if (strncasecmp(args, "FROM:", 5) != 0 ||
- parse_address(args + 5, &addr, &args) < 0) {
+ if (strncasecmp(args, "FROM:", 5) != 0) {
client_send_line(client, "501 5.5.4 Invalid parameters");
return 0;
}
+ if (smtp_address_parse_path_full(pool_datastack_create(), args + 5,
+ SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY,
+ &address, &error, &args) < 0) {
+ client_send_line(client, "501 5.5.4 Invalid FROM: %s", error);
+ return 0;
+ }
+ if (*args == ' ')
+ args++;
+ else if (*args != '\0') {
+ client_send_line(client, "501 5.5.4 Invalid FROM: "
+ "Invalid character in path");
+ return 0;
+ }
argv = t_strsplit(args, " ");
for (; *argv != NULL; argv++) {
}
}
- client->state.mail_from = p_strdup(client->state_pool, addr);
+ client->state.mail_from =
+ smtp_address_clone(client->state_pool, address);
p_array_init(&client->state.rcpt_to, client->state_pool, 64);
client_send_line(client, "250 2.1.0 OK");
- client_state_set(client, "MAIL FROM", client->state.mail_from);
+ client_state_set(client, "MAIL FROM",
+ smtp_address_encode(address));
if (client->lmtp_set->lmtp_user_concurrency_limit > 0) {
/* connect to anvil before dropping privileges */
return TRUE;
}
-static const char *
-address_add_detail(const char *username, char delim_c,
- const char *detail)
-{
- const char *domain;
- const char delim[] = {delim_c, '\0'};
-
- domain = strchr(username, '@');
- if (domain == NULL)
- return t_strconcat(username, delim, detail, NULL);
- else {
- username = t_strdup_until(username, domain);
- return t_strconcat(username, delim, detail, domain, NULL);
- }
-}
-
-static bool client_proxy_rcpt(struct client *client, const char *address,
+static bool client_proxy_rcpt(struct client *client,
+ struct smtp_address *address,
const char *username, const char *detail, char delim,
const struct lmtp_recipient_params *params)
{
struct auth_user_info info;
struct mail_storage_service_input input;
const char *args, *const *fields, *errstr, *orig_username = username;
+ struct smtp_address *user;
pool_t pool;
int ret;
pool, &fields);
if (ret <= 0) {
errstr = ret < 0 && fields[0] != NULL ? t_strdup(fields[0]) :
- t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL, address);
+ t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL,
+ smtp_address_encode(address));
pool_unref(&pool);
if (ret < 0) {
client_send_line(client, "%s", errstr);
return FALSE;
}
if (strcmp(username, orig_username) != 0) {
+ if (smtp_address_parse_username(pool_datastack_create(),
+ username, &user, &errstr) < 0) {
+ i_error("%s: Username `%s' returned by passdb lookup is not a valid SMTP address",
+ orig_username, username);
+ client_send_line(client, "550 5.3.5 <%s> "
+ "Internal user lookup failure",
+ smtp_address_encode(address));
+ pool_unref(&pool);
+ return FALSE;
+ }
/* username changed. change the address as well */
- if (*detail == '\0')
- address = username;
- else
- address = address_add_detail(username, delim, detail);
+ if (*detail == '\0') {
+ address = user;
+ } else {
+ address = smtp_address_add_detail_temp(user, detail, delim);
+ }
} else if (client_proxy_is_ourself(client, &set)) {
i_error("Proxying to <%s> loops to itself", username);
client_send_line(client, "554 5.4.6 <%s> "
- "Proxying loops to itself", address);
+ "Proxying loops to itself",
+ smtp_address_encode(address));
pool_unref(&pool);
return TRUE;
}
if (array_count(&client->state.rcpt_to) != 0) {
client_send_line(client, "451 4.3.0 <%s> "
"Can't handle mixed proxy/non-proxy destinations",
- address);
+ smtp_address_encode(address));
pool_unref(&pool);
return TRUE;
}
args = " BODY=7BIT";
else
args = "";
- lmtp_proxy_mail_from(client->proxy, t_strdup_printf(
- "<%s>%s", client->state.mail_from, args));
+ lmtp_proxy_mail_from(client->proxy,
+ t_strdup_printf("<%s>%s",
+ smtp_address_encode(client->state.mail_from), args));
}
- if (lmtp_proxy_add_rcpt(client->proxy, address, &set) < 0)
+ if (lmtp_proxy_add_rcpt(client->proxy,
+ smtp_address_encode(address), &set) < 0)
client_send_line(client, ERRSTR_TEMP_REMOTE_FAILURE);
else
client_send_line(client, "250 2.1.5 OK");
return TRUE;
}
-static const char *lmtp_unescape_address(const char *name)
-{
- 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. */
- 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;
-
- str_append(str, p);
- return str_c(str);
-}
-
static void
client_send_line_overquota(struct client *client,
const struct mail_recipient *rcpt, const char *error)
struct lda_settings *lda_set =
mail_storage_service_user_get_set(rcpt->service_user)[2];
- client_send_line(client, "%s <%s> %s", lda_set->quota_full_tempfail ?
- "452 4.2.2" : "552 5.2.2", rcpt->address, error);
+ client_send_line(client, "%s <%s> %s",
+ lda_set->quota_full_tempfail ? "452 4.2.2" : "552 5.2.2",
+ smtp_address_encode(rcpt->address), error);
}
static int
&user, &errstr);
if (ret < 0) {
- i_error("Failed to initialize user %s: %s", rcpt->address, errstr);
+ i_error("Failed to initialize user %s: %s",
+ smtp_address_encode(rcpt->address), errstr);
return -1;
}
if ((ret = lmtp_rcpt_to_is_over_quota(client, rcpt)) != 0) {
if (ret < 0) {
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->address);
+ smtp_address_encode(rcpt->address));
}
mail_storage_service_user_unref(&rcpt->service_user);
return FALSE;
if (parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) {
client_send_line(client, ERRSTR_TEMP_USERDB_FAIL_PREFIX
"Too many concurrent deliveries for user",
- rcpt->address);
+ smtp_address_encode(rcpt->address));
mail_storage_service_user_unref(&rcpt->service_user);
} else if (cmd_rcpt_finish(client, rcpt)) {
rcpt->anvil_connect_sent = TRUE;
{
struct mail_recipient *rcpt;
struct mail_storage_service_input input;
- const char *params, *address, *username, *detail;
+ struct smtp_address *address;
+ const char *username, *detail;
const char *const *argv;
const char *error = NULL;
char delim = '\0';
return 0;
}
- if (strncasecmp(args, "TO:", 3) != 0 ||
- parse_address(args + 3, &address, ¶ms) < 0) {
+ if (strncasecmp(args, "TO:", 3) != 0) {
client_send_line(client, "501 5.5.4 Invalid parameters");
return 0;
}
+ if (smtp_address_parse_path_full(pool_datastack_create(), args + 3,
+ SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART,
+ &address, &error, &args) < 0) {
+ client_send_line(client, "501 5.5.4 Invalid TO: %s", error);
+ return 0;
+ }
+ if (*args == ' ')
+ args++;
+ else if (*args != '\0') {
+ client_send_line(client, "501 5.5.4 Invalid TO: "
+ "Invalid character in path");
+ return 0;
+ }
rcpt = p_new(client->state_pool, struct mail_recipient, 1);
rcpt->client = client;
- address = lmtp_unescape_address(address);
- argv = t_strsplit(params, " ");
+ argv = t_strsplit(args, " ");
for (; *argv != NULL; argv++) {
if (strncasecmp(*argv, "ORCPT=", 6) == 0) {
rcpt->params.dsn_orcpt = parse_xtext(client, *argv + 6);
return 0;
}
}
- message_detail_address_parse(client->unexpanded_lda_set->recipient_delimiter,
- address, &username, &delim, &detail);
- client_state_set(client, "RCPT TO", address);
+ smtp_address_detail_parse_temp(
+ client->unexpanded_lda_set->recipient_delimiter,
+ address, &username, &delim, &detail);
+
+ client_state_set(client, "RCPT TO",
+ smtp_address_encode(address));
if (client->lmtp_set->lmtp_proxy) {
if (client_proxy_rcpt(client, address, username, detail, delim,
if (ret < 0) {
i_error("Failed to lookup user %s: %s", username, error);
- client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, address);
+ client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
+ smtp_address_encode(address));
return 0;
}
if (ret == 0) {
client_send_line(client,
"550 5.1.1 <%s> User doesn't exist: %s",
- address, username);
+ smtp_address_encode(address), username);
return 0;
}
if (client->proxy != NULL) {
(with and without Return-Path: header) */
client_send_line(client, "451 4.3.0 <%s> "
"Can't handle mixed proxy/non-proxy destinations",
- address);
+ smtp_address_encode(address));
mail_storage_service_user_unref(&rcpt->service_user);
return 0;
}
- rcpt->address = p_strdup(client->state_pool, address);
+ rcpt->address = smtp_address_clone(client->state_pool, address);
rcpt->detail = p_strdup(client->state_pool, detail);
if (client->lmtp_set->lmtp_user_concurrency_limit == 0) {
return 0;
}
-static bool orcpt_get_valid_rfc822(const char *orcpt, const char **addr_r)
+static bool orcpt_get_valid_rfc822(const char *orcpt,
+ const struct smtp_address **addr_r)
{
+ struct message_address *rfc822_addr;
+
if (orcpt == NULL || strncasecmp(orcpt, "rfc822;", 7) != 0)
return FALSE;
- /* FIXME: we should verify the address further */
- *addr_r = orcpt + 7;
+
+ rfc822_addr = message_address_parse(pool_datastack_create(),
+ (const unsigned char *)orcpt+7, strlen(orcpt+7), 2, FALSE);
+ if (rfc822_addr == NULL || rfc822_addr->invalid_syntax ||
+ rfc822_addr->next != NULL)
+ return FALSE;
+ *addr_r = smtp_address_create_temp(rfc822_addr->mailbox, rfc822_addr->domain);
return TRUE;
}
&dest_user, &error) < 0) {
i_error("Failed to initialize user: %s", error);
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->address);
+ smtp_address_encode(rcpt->address));
return -1;
}
client->state.dest_user = dest_user;
if (ret <= 0) {
i_error("Failed to expand settings: %s", error);
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->address);
+ smtp_address_encode(rcpt->address));
return -1;
}
i_error("Failed to expand mail_log_prefix=%s: %s",
dest_user->set->mail_log_prefix, error);
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->address);
+ smtp_address_encode(rcpt->address));
return -1;
}
i_set_failure_prefix("%s", str_c(str));
client->state.first_saved_mail = dctx.dest_mail;
}
client_send_line(client, "250 2.0.0 <%s> %s Saved",
- rcpt->address, rcpt->session_id);
+ smtp_address_encode(rcpt->address),
+ rcpt->session_id);
ret = 0;
} else if (dctx.tempfail_error != NULL) {
client_send_line(client, "451 4.2.0 <%s> %s",
- rcpt->address, dctx.tempfail_error);
+ smtp_address_encode(rcpt->address),
+ dctx.tempfail_error);
ret = -1;
} else if (storage != NULL) {
error = mail_storage_get_last_error(storage, &mail_error);
client_send_line_overquota(client, rcpt, error);
} else {
client_send_line(client, "451 4.2.0 <%s> %s",
- rcpt->address, error);
+ smtp_address_encode(rcpt->address), error);
}
ret = -1;
} else {
/* This shouldn't happen */
i_error("BUG: Saving failed to unknown storage");
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->address);
+ smtp_address_encode(rcpt->address));
ret = -1;
}
return ret;
array_foreach(&client->state.rcpt_to, rcptp) {
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- (*rcptp)->address);
+ smtp_address_encode((*rcptp)->address));
}
}
enum mail_error error;
if (raw_mailbox_alloc_stream(client->raw_mail_user, input,
- (time_t)-1, client->state.mail_from,
+ (time_t)-1, smtp_address_encode(client->state.mail_from),
&box) < 0) {
i_error("Can't open delivery mail as raw: %s",
mailbox_get_last_internal_error(box, &error));
string_t *str = t_str_new(200);
void **sets;
const struct lmtp_settings *lmtp_set;
- const char *host, *rcpt_to = NULL;
+ const struct smtp_address *rcpt_to = NULL;
+ const char *host;
if (array_count(&client->state.rcpt_to) == 1) {
struct mail_recipient *const *rcptp =
/* don't set Return-Path when proxying so it won't get added twice */
if (array_count(&client->state.rcpt_to) > 0) {
str_printfa(str, "Return-Path: <%s>\r\n",
- client->state.mail_from);
- if (rcpt_to != NULL)
- str_printfa(str, "Delivered-To: %s\r\n", rcpt_to);
+ smtp_address_encode(client->state.mail_from));
+ if (rcpt_to != NULL) {
+ str_printfa(str, "Delivered-To: %s\r\n",
+ smtp_address_encode(rcpt_to));
+ }
}
str_printfa(str, "Received: from %s", client->lhlo);
str_append(str, "\r\n\t");
if (rcpt_to != NULL)
- str_printfa(str, "for <%s>", rcpt_to);
+ str_printfa(str, "for <%s>", smtp_address_encode(rcpt_to));
str_printfa(str, "; %s\r\n", message_date_create(ioloop_time));
return str_c(str);
}