dovecot-2.0-pigeonhole: lib-sieve: vacation extension: finally a...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Tue Aug 2 18:56:01 EEST 2011


details:   http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/81f7acac82f2
changeset: 1517:81f7acac82f2
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Tue Aug 02 17:50:15 2011 +0200
description:
lib-sieve: vacation extension: finally added support for using the original recipient in vacation address check.

diffstat:

 doc/vacation.txt                                     |   27 ++++-
 src/lib-sieve/plugins/vacation/cmd-vacation.c        |  124 +++++++++++++-----------
 src/lib-sieve/plugins/vacation/ext-vacation-common.c |   15 ++-
 src/lib-sieve/plugins/vacation/ext-vacation-common.h |    2 +
 src/testsuite/testsuite-message.c                    |   17 +++-
 src/testsuite/testsuite-message.h                    |    2 +
 src/testsuite/testsuite-objects.c                    |    8 +
 tests/extensions/vacation/reply.svtest               |   98 +++++++++++++++++++
 8 files changed, 233 insertions(+), 60 deletions(-)

diffs (truncated from 506 to 300 lines):

diff -r efad75f779de -r 81f7acac82f2 doc/vacation.txt
--- a/doc/vacation.txt	Tue Aug 02 16:36:06 2011 +0200
+++ b/doc/vacation.txt	Tue Aug 02 17:50:15 2011 +0200
@@ -31,9 +31,9 @@
 day.  
 
 The vacation and vacation-seconds extensions have their own specific
-settings. The settings that specify a period (currently all of them) 
-are specified in s(econds), unless followed by a d(ay), h(our) or m(inute)
-specifier character. 
+settings. The settings that specify a period are specified in
+s(econds), unless followed by a d(ay), h(our) or m(inute) specifier
+character. 
 
 The following settings can be configured the vacation extension (default
 values are indicated):
@@ -56,6 +56,27 @@
   tag is specified. The configured value must lie between the
   sieve_vacation_min_period and sieve_vacation_max_period.
 
+sieve_vacation_use_original_recipient = no
+  This specifies whether the original envelope recipient should be used in
+  the check for implicit delivery.  The vacation command checks headers of
+  the incoming message, such as To: and Cc: for the address of the
+  recipient, to verify that the message is explicitly addressed at the
+  recipient. If the recipient address is not found, the vacation action
+  will not trigger a response to prevent sending a reply when it is not
+  appropriate. Normally only the final recipient address is used in this
+  check. This setting allows including the original recipient specified in
+  the SMTP session if available. This is useful to handle mail accounts
+  with aliases. Use this option with caution: if you are using aliases that
+  point to more than a single account, senders can get multiple vacation
+  responses for a single message. 
+  
+sieve_vacation_dont_check_recipient = no
+  This disables the checks for implicit delivery entirely. This means that
+  the vacation command does not verify that the message is explicitly
+  addressed at the recipient. Use this option with caution. Specifying
+  'yes' will violate the Sieve standards and can cause vacation replies to
+  be sent for messages not directly addressed at the recipient. 
+
 Invalid values for the settings above will make the Sieve interpreter log
 a warning and revert to the default values. 
 
diff -r efad75f779de -r 81f7acac82f2 src/lib-sieve/plugins/vacation/cmd-vacation.c
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c	Tue Aug 02 16:36:06 2011 +0200
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c	Tue Aug 02 17:50:15 2011 +0200
@@ -1017,11 +1017,11 @@
 	const struct sieve_script_env *senv = aenv->scriptenv;
 	struct act_vacation_context *ctx = 
 		(struct act_vacation_context *) action->context;
-	const char *const *hdsp;
 	unsigned char dupl_hash[MD5_RESULTLEN];
-	const char *const *headers;
 	const char *sender = sieve_message_get_sender(aenv->msgctx);
 	const char *recipient = sieve_message_get_final_recipient(aenv->msgctx);
+	const char *const *hdsp;
+	const char *const *headers;
 	const char *reply_from = NULL;
 
 	/* Is the recipient unset? 
@@ -1037,14 +1037,14 @@
 	if ( sender == NULL ) {
 		sieve_result_global_log(aenv, "discarded vacation reply to <>");
 		return TRUE;
-	}    
-	
-	/* Are we perhaps trying to respond to ourselves ? 
+	}
+
+	/* Are we perhaps trying to respond to ourselves ?
 	 */
 	if ( sieve_address_compare(sender, recipient, TRUE) == 0 ) {
 		sieve_result_global_log(aenv,
 			"discarded vacation reply to own address <%s>",
-			str_sanitize(sender, 128));	
+			str_sanitize(sender, 128));
 		return TRUE;
 	}
 
@@ -1052,24 +1052,24 @@
 	 */
 	if ( ctx->addresses != NULL ) {
 		const char * const *alt_address = ctx->addresses;
-		
+
 		while ( *alt_address != NULL ) {
 			if ( sieve_address_compare(sender, *alt_address, TRUE) == 0 ) {
 				sieve_result_global_log(aenv,
 					"discarded vacation reply to own address <%s> "
 					"(as specified using :addresses argument)",
-					str_sanitize(sender, 128));	
+					str_sanitize(sender, 128));
 				return TRUE;
 			}
 			alt_address++;
-		}			
+		}
 	}
-	
+
 	/* Did whe respond to this user before? */
 	if ( sieve_action_duplicate_check_available(senv) ) {
 		act_vacation_hash(ctx, sender, dupl_hash);
-	
-		if ( sieve_action_duplicate_check(senv, dupl_hash, sizeof(dupl_hash)) ) 
+
+		if ( sieve_action_duplicate_check(senv, dupl_hash, sizeof(dupl_hash)) )
 		{
 			sieve_result_global_log(aenv,
 				"discarded duplicate vacation response to <%s>",
@@ -1077,7 +1077,7 @@
 			return TRUE;
 		}
 	}
-	
+
 	/* Are we trying to respond to a mailing list ? */
 	hdsp = _list_headers;
 	while ( *hdsp != NULL ) {
@@ -1101,7 +1101,7 @@
 			if ( strcasecmp(*hdsp, "no") != 0 ) {
 				sieve_result_global_log(aenv, 
 					"discarding vacation response to auto-submitted message from <%s>", 
-					str_sanitize(sender, 128));	
+ 					str_sanitize(sender, 128));	
 					return TRUE;				 
 			}
 			hdsp++;
@@ -1124,59 +1124,73 @@
 			hdsp++;
 		}
 	}
-	
+
 	/* Do not reply to system addresses */
 	if ( _is_system_address(sender) ) {
-		sieve_result_global_log(aenv, 
-			"not sending vacation response to system address <%s>", 
-			str_sanitize(sender, 128));	
-		return TRUE;				
-	} 
-	
+		sieve_result_global_log(aenv,
+			"not sending vacation response to system address <%s>",
+			str_sanitize(sender, 128));
+		return TRUE;
+	}
+
 	/* Is the original message directly addressed to the user or the addresses
-	 * specified using the :addresses tag? 
+	 * specified using the :addresses tag?
 	 */
-	hdsp = _my_address_headers;
-	while ( *hdsp != NULL ) {
-		if ( mail_get_headers
-			(msgdata->mail, *hdsp, &headers) >= 0 && headers[0] != NULL ) {	
-			
-			if ( _contains_my_address(headers, recipient) ) {
-				reply_from = recipient;
-				break;
+	if ( !config->dont_check_recipient ) {
+		const char *orig_recipient = NULL;
+
+		if ( config->use_original_recipient  )
+			orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx);
+
+		hdsp = _my_address_headers;
+		while ( *hdsp != NULL ) {
+			if ( mail_get_headers
+				(msgdata->mail, *hdsp, &headers) >= 0 && headers[0] != NULL ) {	
+
+				if ( _contains_my_address(headers, recipient) ) {
+					reply_from = recipient;
+					break;
+				}
+
+				if ( orig_recipient != NULL && _contains_my_address(headers, orig_recipient) ) {
+					reply_from = orig_recipient;
+					break;
+				}
+
+				if ( ctx->addresses != NULL ) {
+					bool found = FALSE;
+					const char * const *my_address = ctx->addresses;
+
+					while ( !found && *my_address != NULL ) {
+						if ( (found=_contains_my_address(headers, *my_address)) )
+							reply_from = *my_address;
+						my_address++;
+					}
+
+					if ( found ) break;
+				}
 			}
-			
-			if ( ctx->addresses != NULL ) {
-				bool found = FALSE;
-				const char * const *my_address = ctx->addresses;
-		
-				while ( !found && *my_address != NULL ) {
-					found = _contains_my_address(headers, *my_address);
-					reply_from = *my_address;
-					my_address++;
-				}
-				
-				if ( found ) break;
-			}
+			hdsp++;
 		}
-		hdsp++;
-	}	
 
-	if ( *hdsp == NULL ) {
-		/* No, bail out */
-		sieve_result_global_log(aenv, 
-			"discarding vacation response for message implicitly delivered to <%s>",
-			recipient );	
-		return TRUE;				 
-	}	
-	
+
+		/* My address not found in the headers; we got an implicit delivery */
+		if ( *hdsp == NULL ) {
+			/* No, bail out */
+			sieve_result_global_log(aenv,
+				"discarding vacation response for message implicitly delivered to <%s>",
+				recipient );
+			return TRUE;
+		}
+	}
+
 	/* Send the message */
-	
+
 	if ( act_vacation_send(aenv, ctx, sender, reply_from) ) {
 		sieve_number_t seconds; 
 
 		sieve_result_global_log(aenv, "sent vacation response to <%s>", 
-			str_sanitize(sender, 128));	
+			str_sanitize(sender, 128));
 
 		/* Check period limits once more */
 		seconds = ctx->seconds;
diff -r efad75f779de -r 81f7acac82f2 src/lib-sieve/plugins/vacation/ext-vacation-common.c
--- a/src/lib-sieve/plugins/vacation/ext-vacation-common.c	Tue Aug 02 16:36:06 2011 +0200
+++ b/src/lib-sieve/plugins/vacation/ext-vacation-common.c	Tue Aug 02 17:50:15 2011 +0200
@@ -16,6 +16,7 @@
 	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;
 
 	if ( *context != NULL ) {
 		ext_vacation_unload(ext);
@@ -48,11 +49,23 @@
 			"sieve_vacation_min_period < sieve_vacation_default_period < "
 			"sieve_vacation_max_period");
 	}
-	
+
+	if ( !sieve_setting_get_bool_value
+		(svinst, "sieve_vacation_use_original_recipient", &use_original_recipient) ) {
+		use_original_recipient = FALSE;
+	}
+
+	if ( !sieve_setting_get_bool_value
+		(svinst, "sieve_vacation_dont_check_recipient", &dont_check_recipient) ) {
+		dont_check_recipient = 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;
 
 	*context = (void *) config;
 
diff -r efad75f779de -r 81f7acac82f2 src/lib-sieve/plugins/vacation/ext-vacation-common.h
--- a/src/lib-sieve/plugins/vacation/ext-vacation-common.h	Tue Aug 02 16:36:06 2011 +0200
+++ b/src/lib-sieve/plugins/vacation/ext-vacation-common.h	Tue Aug 02 17:50:15 2011 +0200
@@ -18,6 +18,8 @@
 	unsigned int min_period;
 	unsigned int max_period;
 	unsigned int default_period;
+	bool use_original_recipient;
+	bool dont_check_recipient;
 };
 
 /* 
diff -r efad75f779de -r 81f7acac82f2 src/testsuite/testsuite-message.c
--- a/src/testsuite/testsuite-message.c	Tue Aug 02 16:36:06 2011 +0200
+++ b/src/testsuite/testsuite-message.c	Tue Aug 02 17:50:15 2011 +0200
@@ -33,6 +33,7 @@
 
 static string_t *envelope_from;
 static string_t *envelope_to;
+static string_t *envelope_orig_to;


More information about the dovecot-cvs mailing list