diff --git a/doc/extensions/vacation.txt b/doc/extensions/vacation.txt index 20f82b19a35bde4b171aaec456ede5578b64f04f..9b9856f72669ee6c2a3d23f41c3de3978f073c83 100644 --- a/doc/extensions/vacation.txt +++ b/doc/extensions/vacation.txt @@ -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. diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 50c55385a4ef3eebb3515323e467b0cbff8be2e4..3c033af94eea449f202add2e474bda89f0e9fe84 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -817,9 +817,9 @@ static const char * const _my_address_headers[] = { */ static const char * const _sender_headers[] = { - "from", "sender", "resent-from", + "from", NULL }; @@ -899,6 +899,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; @@ -926,16 +927,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; @@ -959,8 +965,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; @@ -1001,7 +1010,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; @@ -1381,7 +1390,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; diff --git a/src/lib-sieve/plugins/vacation/ext-vacation-common.c b/src/lib-sieve/plugins/vacation/ext-vacation-common.c index f07a57a9d5ab51be2db72bdcce301632ba7a63bf..a556ebfacaa6b82d595c121fab8f26695582bfc7 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation-common.c +++ b/src/lib-sieve/plugins/vacation/ext-vacation-common.c @@ -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); @@ -65,6 +66,12 @@ 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; @@ -72,6 +79,7 @@ bool ext_vacation_load 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; diff --git a/src/lib-sieve/plugins/vacation/ext-vacation-common.h b/src/lib-sieve/plugins/vacation/ext-vacation-common.h index 9433c3369fab91732329490845cec817110f6c79..fffb610477d7ef52093a4a164ac30e225544c2ea 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation-common.h +++ b/src/lib-sieve/plugins/vacation/ext-vacation-common.h @@ -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; }; /* diff --git a/tests/extensions/vacation/message.svtest b/tests/extensions/vacation/message.svtest index e2abbfdaab55508b156d245c87e19f12282be5e1..4e26ffd422c2a094b9cd8321658ce654a0ad13f8 100644 --- a/tests/extensions/vacation/message.svtest +++ b/tests/extensions/vacation/message.svtest @@ -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 */