dovecot-2.2-pigeonhole: lib-sieve: Implemented sieve_redirect_en...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Tue Oct 14 22:24:11 UTC 2014


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/aaf7f0f48b99
changeset: 1923:aaf7f0f48b99
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Oct 15 00:23:55 2014 +0200
description:
lib-sieve: Implemented sieve_redirect_envelope_from setting, which allows configuring the envelope sender of redirected messages.
Can either be set to the envelope sender, recipient, or orignal recipient of the processed message or it can be set explicitly to a static address.

diffstat:

 INSTALL                         |   18 +++++
 src/lib-sieve/cmd-redirect.c    |   33 +++++++++
 src/lib-sieve/sieve-common.h    |   11 ++-
 src/lib-sieve/sieve-settings.c  |  101 +++++++++++++++++++++++++++++-
 src/lib-sieve/sieve-settings.h  |    9 ++-
 src/lib-sieve/sieve.c           |   26 +------
 src/testsuite/cmd-test-config.c |   41 +++++++-----
 tests/execute/smtp.svtest       |  134 +++++++++++++++++++++++++++++++++++++++-
 8 files changed, 327 insertions(+), 46 deletions(-)

diffs (truncated from 553 to 300 lines):

diff -r a0a5f61eea69 -r aaf7f0f48b99 INSTALL
--- a/INSTALL	Tue Oct 14 03:22:23 2014 +0200
+++ b/INSTALL	Wed Oct 15 00:23:55 2014 +0200
@@ -208,6 +208,24 @@
    part is left of the separator and the :detail part is right. This setting is
    also used by Dovecot's LMTP service.
 
+ sieve_redirect_envelope_from = sender
+   Specifies what envelope sender address is used for redirected messages.
+   Normally, the Sieve "redirect" command copies the sender address for the
+   redirected message from the  processed message. So, the redirected message
+   appears to originate from the original sender. The following values are
+   supported for this setting:
+   
+     "sender"         - The sender address is used (default)
+     "recipient"      - The final recipient address is used
+     "orig_recipient" - The original recipient is used
+     "<user at domain>"  - Redirected messages are always sent from user at domain.
+                        The angle brackets are mandatory. The null "<>" address
+                        is also supported.
+
+	 When the envelope sender of the processed message is the null address "<>",
+   the envelope sender of the redirected message is also always "<>",
+   irrespective of what is configured for this setting. 
+
 For example:
 
 plugin {
diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/cmd-redirect.c
--- a/src/lib-sieve/cmd-redirect.c	Tue Oct 14 03:22:23 2014 +0200
+++ b/src/lib-sieve/cmd-redirect.c	Wed Oct 15 00:23:55 2014 +0200
@@ -4,6 +4,7 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "str-sanitize.h"
+#include "strfuncs.h"
 #include "istream.h"
 #include "istream-header-filter.h"
 #include "ostream.h"
@@ -316,6 +317,8 @@
 	const struct sieve_script_env *senv = aenv->scriptenv;
 	const char *sender = sieve_message_get_sender(msgctx);
 	const char *recipient = sieve_message_get_final_recipient(msgctx);
+	enum sieve_redirect_envelope_from env_from =
+		aenv->svinst->redirect_from;
 	struct istream *input;
 	struct ostream *output;
 	const char *error;
@@ -332,6 +335,36 @@
 	if (mail_get_stream(mail, NULL, NULL, &input) < 0)
 		return SIEVE_EXEC_TEMP_FAILURE;
 
+	/* Determine which sender to use
+
+	   From RFC 5228, Section 4.2:
+
+		 The envelope sender address on the outgoing message is chosen by the
+		 sieve implementation.  It MAY be copied from the message being
+		 processed.  However, if the message being processed has an empty
+		 envelope sender address the outgoing message MUST also have an empty
+		 envelope sender address.  This last requirement is imposed to prevent
+		 loops in the case where a message is redirected to an invalid address
+		 when then returns a delivery status notification that also ends up
+		 being redirected to the same invalid address.
+	 */
+	if ( sender != NULL &&
+		env_from != SIEVE_REDIRECT_ENVELOPE_FROM_SENDER ) {
+		switch ( env_from ) {
+		case SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT:
+			sender = sieve_message_get_final_recipient(msgctx);
+			break;
+		case SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT:
+			sender = sieve_message_get_orig_recipient(msgctx);
+			break;
+		case SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT:
+			sender = aenv->svinst->redirect_from_explicit;
+			break;
+		default:
+			i_unreached();
+		}
+	}
+
 	/* Open SMTP transport */
 	sctx = sieve_smtp_start_single(senv, ctx->to_address, sender, &output);
 
diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-common.h
--- a/src/lib-sieve/sieve-common.h	Tue Oct 14 03:22:23 2014 +0200
+++ b/src/lib-sieve/sieve-common.h	Wed Oct 15 00:23:55 2014 +0200
@@ -22,6 +22,13 @@
 
 #define SIEVE_MAX_NUMBER ((sieve_number_t) -1)
 
+enum sieve_redirect_envelope_from {
+	SIEVE_REDIRECT_ENVELOPE_FROM_SENDER,
+	SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT,
+	SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT,
+	SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT
+};
+
 /*
  * Forward declarations
  */
@@ -194,10 +201,12 @@
 	enum sieve_env_location env_location;
 	enum sieve_delivery_phase delivery_phase;
 
-	/* Limits */
+	/* Settings */
 	size_t max_script_size;
 	unsigned int max_actions;
 	unsigned int max_redirects;
+	enum sieve_redirect_envelope_from redirect_from;
+	const char *redirect_from_explicit;
 };
 
 #endif /* __SIEVE_COMMON_H */
diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-settings.c
--- a/src/lib-sieve/sieve-settings.c	Tue Oct 14 03:22:23 2014 +0200
+++ b/src/lib-sieve/sieve-settings.c	Wed Oct 15 00:23:55 2014 +0200
@@ -4,12 +4,40 @@
 #include "lib.h"
 
 #include "sieve-common.h"
+#include "sieve-limits.h"
 #include "sieve-error.h"
 #include "sieve-settings.h"
 
 #include <stdlib.h>
 #include <ctype.h>
 
+// FIXME: add to dovecot
+static const char *t_str_trim(const char *str)
+{
+	const char *p, *pend, *begin;
+
+	p = str;
+	pend = str + strlen(str);
+	if (p == pend)
+		return "";
+
+	while (p < pend && (*p == ' ' || *p == '\t'))
+		p++;
+	begin = p;
+
+	p = pend - 1;
+	while (p > begin && (*p == ' ' || *p == '\t'))
+		p--;
+
+	if (p <= begin)
+		return "";
+	return t_strdup_until(begin, p+1);
+}
+
+/*
+ * Access to settings
+ */
+
 static bool sieve_setting_parse_uint
 (struct sieve_instance *svinst, const char *setting, const char *str_value,
 	char **endptr, unsigned long long int *value_r)
@@ -157,8 +185,11 @@
 	const char *str_value;
 
 	str_value = sieve_setting_get(svinst, setting);
+	if ( str_value == NULL )
+		return FALSE;
 
-	if ( str_value == NULL || *str_value == '\0' )
+	str_value = t_str_trim(str_value);
+	if ( *str_value == '\0' )
 		return FALSE;
 
  	if ( strcasecmp(str_value, "yes" ) == 0) {
@@ -185,8 +216,11 @@
 	char *endp;
 
 	str_value = sieve_setting_get(svinst, setting);
+	if ( str_value == NULL )
+		return FALSE;
 
-	if ( str_value == NULL || *str_value == '\0' )
+	str_value = t_str_trim(str_value);
+	if ( *str_value == '\0' )
 		return FALSE;
 
 	if ( !sieve_setting_parse_uint(svinst, setting, str_value, &endp, &value) )
@@ -225,3 +259,66 @@
 	return TRUE;
 }
 
+/*
+ * Main Sieve engine settings
+ */
+
+void sieve_settings_load
+(struct sieve_instance *svinst)
+{
+	unsigned long long int uint_setting;
+	size_t size_setting;
+	const char *str_setting;
+
+	svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE;
+	if ( sieve_setting_get_size_value
+		(svinst, "sieve_max_script_size", &size_setting) ) {
+		svinst->max_script_size = size_setting;
+	}
+
+	svinst->max_actions = SIEVE_DEFAULT_MAX_ACTIONS;
+	if ( sieve_setting_get_uint_value
+		(svinst, "sieve_max_actions", &uint_setting) ) {
+		svinst->max_actions = (unsigned int) uint_setting;
+	}
+
+	svinst->max_redirects = SIEVE_DEFAULT_MAX_REDIRECTS;
+	if ( sieve_setting_get_uint_value
+		(svinst, "sieve_max_redirects", &uint_setting) ) {
+		svinst->max_redirects = (unsigned int) uint_setting;
+	}
+
+	svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER;
+	svinst->redirect_from_explicit = NULL;
+	if ( (str_setting=sieve_setting_get
+		(svinst, "sieve_redirect_envelope_from")) != NULL ) {
+		size_t set_len;
+
+		str_setting = t_str_trim(str_setting);
+		str_setting = t_str_lcase(str_setting);
+		set_len = strlen(str_setting);
+		if ( set_len > 0 ) {
+			if ( strcmp(str_setting, "sender") == 0 ) {
+				svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER;
+			} else if ( strcmp(str_setting, "recipient") == 0 ) {
+				svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT;
+			} else if ( strcmp(str_setting, "orig_recipient") == 0 ) {
+				svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT;
+			} else if ( str_setting[0] == '<' &&	str_setting[set_len-1] == '>') {
+				svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT;
+
+				str_setting = t_str_trim(t_strndup(str_setting+1, set_len-2));
+				if ( *str_setting != '\0' ) {
+					svinst->redirect_from_explicit =
+						p_strdup(svinst->pool, str_setting);
+				}
+			} else {
+				sieve_sys_warning(svinst,
+					"Invalid value `%s' for sieve_redirect_envelope_from setting",
+					str_setting);
+			}
+		}
+	}
+}
+
+
diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve-settings.h
--- a/src/lib-sieve/sieve-settings.h	Tue Oct 14 03:22:23 2014 +0200
+++ b/src/lib-sieve/sieve-settings.h	Wed Oct 15 00:23:55 2014 +0200
@@ -7,7 +7,7 @@
 #include "sieve-common.h"
 
 /*
- * Settings
+ * Access to settings
  */
 
 static inline const char *sieve_setting_get
@@ -38,6 +38,13 @@
 		sieve_number_t *value_r);
 
 /*
+ * Main Sieve engine settings
+ */
+
+void sieve_settings_load
+	(struct sieve_instance *svinst);
+
+/*
  * Home directory
  */
 
diff -r a0a5f61eea69 -r aaf7f0f48b99 src/lib-sieve/sieve.c
--- a/src/lib-sieve/sieve.c	Tue Oct 14 03:22:23 2014 +0200
+++ b/src/lib-sieve/sieve.c	Wed Oct 15 00:23:55 2014 +0200
@@ -8,7 +8,6 @@
 #include "eacces-error.h"
 #include "home-expand.h"
 
-#include "sieve-limits.h"
 #include "sieve-settings.h"
 #include "sieve-extensions.h"
 #include "sieve-plugins.h"
@@ -47,9 +46,7 @@
 	const struct sieve_callbacks *callbacks, void *context, bool debug)
 {
 	struct sieve_instance *svinst;
-	unsigned long long int uint_setting;
-	size_t size_setting;
-	const char  *domain;
+	const char *domain;
 	pool_t pool;
 


More information about the dovecot-cvs mailing list