Skip to content

Commit

Permalink
lib-sieve: vacation extension: Allow ignoring the envelope sender whi…
Browse files Browse the repository at this point in the history
…le composing the "To:" header for the reply.

This adds a new setting "sieve_vacation_to_header_ignore_envelope".
With this setting enabled, the "To:" header is always composed from the first "Sender", "Resent-From" or "From" header found in the message (in that order).
Normally, the "To:" header is composed from the address found in the "Sender", "Resent-From" or "From" headers that is equal to the envelope sender.
If none is then found, the bare envelope sender is used.
The new setting allows ignoring the envelope, which is useful e.g. when SRS is used.
  • Loading branch information
stephanbosch committed Sep 13, 2017
1 parent 94bf044 commit 70c218b
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 13 deletions.
12 changes: 12 additions & 0 deletions doc/extensions/vacation.txt
Expand Up @@ -81,6 +81,18 @@ sieve_vacation_send_from_recipient = no
situations for which a valid sender address is required and this setting can
be used to accommodate for those.

sieve_vacation_to_header_ignore_envelope = no
With this setting disabled (the default), the "To:" header in the composed
vacation reply is determined by finding the envelope sender address in the
first "Sender:", "Resent-From:", or "From:" headers (in that order). The
matching address is used in the "To:" header of the reply, which then includes
the "phrase" part of the address; i.e., usually the name of the person
associated with that address. If no match is found, the bare envelope sender
address is used instead. In contrast, with this setting enabled, the envelope
is completely ignored for this purpose and the first address found from the
mentioned headers is always used. This is useful when the envelope sender is
mangled somehow; e.g. by the Sender Rewriting Scheme (SRS).

Invalid values for the settings above will make the Sieve interpreter log a
warning and revert to the default values.

Expand Down
33 changes: 21 additions & 12 deletions src/lib-sieve/plugins/vacation/cmd-vacation.c
Expand Up @@ -818,9 +818,9 @@ static const char * const _my_address_headers[] = {
*/

static const char * const _sender_headers[] = {
"from",
"sender",
"resent-from",
"from",
NULL
};

Expand Down Expand Up @@ -900,6 +900,7 @@ static bool _contains_8bit(const char *text)

static int _get_full_reply_recipient
(const struct sieve_action_exec_env *aenv,
const struct ext_vacation_config *config,
const char *smtp_to, const char **reply_to_r)
{
const struct sieve_message_data *msgdata = aenv->msgdata;
Expand Down Expand Up @@ -927,16 +928,21 @@ static int _get_full_reply_recipient
if ( addr->domain != NULL && !addr->invalid_syntax ) {
struct sieve_address svaddr;
const char *hdr_address;
bool matched = config->to_header_ignore_envelope;

i_assert(addr->mailbox != NULL);
if (!matched) {
i_assert(addr->mailbox != NULL);

i_zero(&svaddr);
svaddr.local_part = addr->mailbox;
svaddr.domain = addr->domain;
i_zero(&svaddr);
svaddr.local_part = addr->mailbox;
svaddr.domain = addr->domain;

hdr_address = sieve_address_to_string(&svaddr);
if ( sieve_address_compare
(hdr_address, smtp_to, TRUE) == 0 ) {
hdr_address = sieve_address_to_string(&svaddr);
matched = ( sieve_address_compare
(hdr_address, smtp_to, TRUE) == 0 );
}

if (matched) {
struct message_address this_addr;

this_addr = *addr;
Expand All @@ -960,8 +966,11 @@ static int _get_full_reply_recipient
}

static int act_vacation_send
(const struct sieve_action_exec_env *aenv, struct act_vacation_context *ctx,
const char *smtp_to, const char *smtp_from, const char *reply_from)
(const struct sieve_action_exec_env *aenv,
const struct ext_vacation_config *config,
struct act_vacation_context *ctx,
const char *smtp_to, const char *smtp_from,
const char *reply_from)
{
const struct sieve_message_data *msgdata = aenv->msgdata;
const struct sieve_script_env *senv = aenv->scriptenv;
Expand Down Expand Up @@ -1002,7 +1011,7 @@ static int act_vacation_send
/* Obtain full To address for reply */

reply_to = smtp_to;
if ((ret=_get_full_reply_recipient(aenv,
if ((ret=_get_full_reply_recipient(aenv, config,
smtp_to, &reply_to)) <= 0)
return ret;

Expand Down Expand Up @@ -1382,7 +1391,7 @@ static int act_vacation_commit
/* Send the message */

T_BEGIN {
ret = act_vacation_send(aenv, ctx, sender,
ret = act_vacation_send(aenv, config, ctx, sender,
(config->send_from_recipient ? smtp_from : NULL),
reply_from);
} T_END;
Expand Down
10 changes: 9 additions & 1 deletion src/lib-sieve/plugins/vacation/ext-vacation-common.c
Expand Up @@ -16,7 +16,8 @@ bool ext_vacation_load
struct sieve_instance *svinst = ext->svinst;
struct ext_vacation_config *config;
sieve_number_t min_period, max_period, default_period;
bool use_original_recipient, dont_check_recipient, send_from_recipient;
bool use_original_recipient, dont_check_recipient, send_from_recipient,
to_header_ignore_envelope;

if ( *context != NULL ) {
ext_vacation_unload(ext);
Expand Down Expand Up @@ -65,13 +66,20 @@ bool ext_vacation_load
send_from_recipient = FALSE;
}

if ( !sieve_setting_get_bool_value(svinst,
"sieve_vacation_to_header_ignore_envelope",
&to_header_ignore_envelope) ) {
to_header_ignore_envelope = FALSE;
}

config = i_new(struct ext_vacation_config, 1);
config->min_period = min_period;
config->max_period = max_period;
config->default_period = default_period;
config->use_original_recipient = use_original_recipient;
config->dont_check_recipient = dont_check_recipient;
config->send_from_recipient = send_from_recipient;
config->to_header_ignore_envelope = to_header_ignore_envelope;

*context = (void *) config;

Expand Down
1 change: 1 addition & 0 deletions src/lib-sieve/plugins/vacation/ext-vacation-common.h
Expand Up @@ -21,6 +21,7 @@ struct ext_vacation_config {
bool use_original_recipient;
bool dont_check_recipient;
bool send_from_recipient;
bool to_header_ignore_envelope;
};

/*
Expand Down
38 changes: 38 additions & 0 deletions tests/extensions/vacation/message.svtest
Expand Up @@ -189,6 +189,44 @@ test "Reply to unknown" {
}
}

/*
* Reply to (ignored envelope)
*/

test_set "message" text:
From: "Stephan Bosch" <stephan@example.org>
Sender: "Hendrik-Jan Tuinman" <h.j.tuinman@example.org>
Subject: Reply to me
To: nico@frop.example.org

Frop
.
;

test_set "envelope.from" "srs0=hmc8=v7=example.com=arie@example.org";

test_config_set "sieve_vacation_to_header_ignore_envelope" "yes";
test_config_reload :extension "vacation";

test_result_reset;
test "Reply to (ignored envelope)" {
vacation "I am not in today!";

if not test_result_execute {
test_fail "execution of result failed";
}

test_message :smtp 0;

if not address :is "to" "h.j.tuinman@example.org" {
test_fail "To header has incorrect address";
}

if not header :is "to" "\"Hendrik-Jan Tuinman\" <h.j.tuinman@example.org>" {
test_fail "To header is incorrect";
}
}

/*
* References
*/
Expand Down

0 comments on commit 70c218b

Please sign in to comment.