dovecot-2.1-pigeonhole: lib-sieve: editheader: added simple conf...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Mon Nov 28 23:13:27 EET 2011


details:   http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/8d0cfe6f66f0
changeset: 1563:8d0cfe6f66f0
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Mon Nov 28 22:13:18 2011 +0100
description:
lib-sieve: editheader: added simple configuration for protected headers.

diffstat:

 Makefile.am                                              |    1 +
 TODO                                                     |    2 -
 src/lib-sieve/plugins/editheader/Makefile.am             |    3 +-
 src/lib-sieve/plugins/editheader/cmd-addheader.c         |   28 +++-
 src/lib-sieve/plugins/editheader/cmd-deleteheader.c      |   14 ++
 src/lib-sieve/plugins/editheader/ext-editheader-common.c |  135 +++++++++++++++++--
 src/lib-sieve/plugins/editheader/ext-editheader-common.h |   22 ++-
 src/lib-sieve/plugins/editheader/ext-editheader.c        |    3 +-
 tests/extensions/editheader/protected.svtest             |   74 ++++++++++
 9 files changed, 251 insertions(+), 31 deletions(-)

diffs (truncated from 433 to 300 lines):

diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 Makefile.am
--- a/Makefile.am	Mon Nov 28 08:53:43 2011 +0100
+++ b/Makefile.am	Mon Nov 28 22:13:18 2011 +0100
@@ -130,6 +130,7 @@
 	tests/extensions/editheader/deleteheader.svtest \
 	tests/extensions/editheader/alternating.svtest \
 	tests/extensions/editheader/utf8.svtest \
+	tests/extensions/editheader/protected.svtest \
 	tests/extensions/editheader/errors.svtest \
 	tests/extensions/vnd.dovecot/debug/execute.svtest \
 	tests/deprecated/notify/basic.svtest \
diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 TODO
--- a/TODO	Mon Nov 28 08:53:43 2011 +0100
+++ b/TODO	Mon Nov 28 22:13:18 2011 +0100
@@ -2,8 +2,6 @@
 
 * Implement editheader extension
 	- Implement configurable limit on header value length
-	- Implement configurable list of protected headers, with Received: and
-	  Auto-Submitted: headers always protected.
 	- Add command syntax checks to the test suite.
 
 Parallel plugin-based efforts:
diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 src/lib-sieve/plugins/editheader/Makefile.am
--- a/src/lib-sieve/plugins/editheader/Makefile.am	Mon Nov 28 08:53:43 2011 +0100
+++ b/src/lib-sieve/plugins/editheader/Makefile.am	Mon Nov 28 22:13:18 2011 +0100
@@ -10,7 +10,8 @@
 
 libsieve_ext_editheader_la_SOURCES = \
 	$(commands) \
-	ext-editheader.c
+	ext-editheader.c \
+	ext-editheader-common.c
 
 noinst_HEADERS = \
 	ext-editheader-common.h
diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 src/lib-sieve/plugins/editheader/cmd-addheader.c
--- a/src/lib-sieve/plugins/editheader/cmd-addheader.c	Mon Nov 28 08:53:43 2011 +0100
+++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c	Mon Nov 28 22:13:18 2011 +0100
@@ -88,18 +88,18 @@
  */
 
 static bool cmd_addheader_validate
-(struct sieve_validator *valdtr, struct sieve_command *tst)
+(struct sieve_validator *valdtr, struct sieve_command *cmd)
 {
-	struct sieve_ast_argument *arg = tst->first_positional;
+	struct sieve_ast_argument *arg = cmd->first_positional;
 
 	/* Check field-name syntax */
 
 	if ( !sieve_validate_positional_argument
-		(valdtr, tst, arg, "field-name", 1, SAAT_STRING) ) {
+		(valdtr, cmd, arg, "field-name", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
 
-	if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
+	if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) )
 		return FALSE;
 	
 	if ( sieve_argument_is_string_literal(arg) ) {
@@ -111,6 +111,12 @@
 					str_sanitize(str_c(fname), 80));
 			return FALSE;
 		}
+
+		if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) {
+			sieve_argument_validate_warning(valdtr, arg, "addheader command: "
+				"specified header field `%s' is protected "
+				"(modification will be denied)", str_sanitize(str_c(fname), 80));
+		}
 	}
 
 	/* Check value syntax */
@@ -118,11 +124,11 @@
 	arg = sieve_ast_argument_next(arg);
 
 	if ( !sieve_validate_positional_argument
-		(valdtr, tst, arg, "value", 2, SAAT_STRING) ) {
+		(valdtr, cmd, arg, "value", 2, SAAT_STRING) ) {
 		return FALSE;
 	}
 
-	if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
+	if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) )
 		return FALSE;
 
 	if ( sieve_argument_is_string_literal(arg) ) {
@@ -207,6 +213,7 @@
 static int cmd_addheader_operation_execute
 (const struct sieve_runtime_env *renv, sieve_size_t *address)
 {
+	const struct sieve_extension *this_ext = renv->oprtn->ext;
 	string_t *field_name;
 	string_t *value;
 	struct edit_mail *edmail;
@@ -259,7 +266,14 @@
 			str_sanitize(str_c(field_name), 80));
 		return SIEVE_EXEC_FAILURE;
 	}
-
+	
+	if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) {
+		sieve_runtime_warning(renv, NULL, "addheader action: "
+			"specified header field `%s' is protected (modification denied)",
+			str_sanitize(str_c(field_name), 80));
+		return SIEVE_EXEC_OK;
+	}
+	
 	if ( !rfc2822_header_field_body_verify
 		(str_c(value), str_len(value), TRUE, TRUE) ) {
 		sieve_runtime_error(renv, NULL, "addheader action: "
diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 src/lib-sieve/plugins/editheader/cmd-deleteheader.c
--- a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c	Mon Nov 28 08:53:43 2011 +0100
+++ b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c	Mon Nov 28 22:13:18 2011 +0100
@@ -258,6 +258,12 @@
 				str_sanitize(str_c(fname), 80));
 			return FALSE;
 		}
+
+		if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) {
+			sieve_argument_validate_warning(valdtr, arg, "deleteheader command: "
+				"specified header field `%s' is protected "
+				"(modification will be denied)", str_sanitize(str_c(fname), 80));
+		}
 	}
 	
 	/* Value patterns argument */
@@ -363,6 +369,7 @@
 static int cmd_deleteheader_operation_execute
 (const struct sieve_runtime_env *renv, sieve_size_t *address)
 {
+	const struct sieve_extension *this_ext = renv->oprtn->ext;
 	int opt_code = 0;
 	struct sieve_operand oprnd;
 	struct sieve_comparator cmp = 
@@ -437,6 +444,13 @@
 		return SIEVE_EXEC_FAILURE;
 	}
 
+	if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) {
+		sieve_runtime_warning(renv, NULL, "deleteheader action: "
+			"specified header field `%s' is protected (modification denied)",
+			str_sanitize(str_c(field_name), 80));
+		return SIEVE_EXEC_OK;
+	}
+
 	/*
 	 * Execute command
 	 */
diff -r f13a2fc82fa0 -r 8d0cfe6f66f0 src/lib-sieve/plugins/editheader/ext-editheader-common.c
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c	Mon Nov 28 08:53:43 2011 +0100
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c	Mon Nov 28 22:13:18 2011 +0100
@@ -1,28 +1,135 @@
 /* Copyright (c) 2002-2011 Pigeonhole authors, see the included COPYING file
  */
 
-#ifndef __EXT_EDITHEADER_COMMON_H
-#define __EXT_EDITHEADER_COMMON_H
+#include "lib.h"
+#include "mempool.h"
+#include "array.h"
+
+#include "rfc2822.h"
+
+#include "sieve-common.h"
+#include "sieve-error.h"
+#include "sieve-settings.h"
+#include "sieve-extensions.h"
+
+#include "ext-editheader-common.h"
 
 /*
- * Extensions
+ * Extension configuration
  */
 
-extern const struct sieve_extension_def editheader_extension;
+struct ext_editheader_header {
+	const char *name;
+	
+	/* may extend this later */
+	unsigned int protected:1;
+};
+
+struct ext_editheader_config {
+	pool_t pool;
+
+	ARRAY_DEFINE(headers, struct ext_editheader_header);
+};
+
+static struct ext_editheader_header *ext_editheader_config_header_find
+(struct ext_editheader_config *ext_config, const char *hname)
+{
+	struct ext_editheader_header *headers;
+	unsigned int count, i;
+	
+	headers = array_get_modifiable(&ext_config->headers, &count);
+	for ( i = 0; i < count; i++ ) {
+		if ( strcasecmp(hname, headers[i].name) == 0 )
+			return &headers[i];
+	}
+
+	return NULL;	
+}
+
+bool ext_editheader_load
+(const struct sieve_extension *ext, void **context)
+{
+	struct ext_editheader_config *ext_config =
+		(struct ext_editheader_config *) *context;
+	struct sieve_instance *svinst = ext->svinst;
+	const char *protected;
+	pool_t pool;
+
+	if ( *context != NULL ) {
+		ext_editheader_unload(ext);
+		*context = NULL;
+	}
+
+	T_BEGIN {
+		pool = pool_alloconly_create("editheader_config", 512);
+		ext_config = p_new(pool, struct ext_editheader_config, 1);
+		ext_config->pool = pool;
+
+		p_array_init(&ext_config->headers, pool, 16);
+
+		protected = sieve_setting_get(svinst, "sieve_editheader_protected");
+		if ( protected != NULL ) {
+			const char **headers = t_strsplit_spaces(protected, " \t");
+
+			while ( *headers != NULL ) {
+				struct ext_editheader_header *header;
+
+				if ( !rfc2822_header_field_name_verify(*headers, strlen(*headers)) ) {
+					sieve_sys_warning(svinst, 
+						"editheader: setting sieve_editheader_protected contains "
+						"invalid header field name `%s' (ignored)", *headers);
+					continue;
+				}
+
+				header=ext_editheader_config_header_find(ext_config, *headers);
+				if ( header == NULL ) {
+					header = array_append_space(&ext_config->headers);
+					header->name = p_strdup(pool, *headers);
+				}
+
+				header->protected = TRUE;
+
+				headers++;
+			}
+		}
+	} T_END;
+
+	*context = (void *) ext_config;
+	return TRUE;	
+}
+
+void ext_editheader_unload(const struct sieve_extension *ext)
+{
+	struct ext_editheader_config *ext_config = 
+		(struct ext_editheader_config *) ext->context;
+	
+	if ( ext_config != NULL ) {
+		pool_unref(&ext_config->pool);
+	}
+}
 
 /*
- * Commands
+ * Protected headers
  */
 
-extern const struct sieve_command_def addheader_command;
-//extern const struct sieve_command_def deleteheader_command;
+bool ext_editheader_header_is_protected
+(const struct sieve_extension *ext, const char *hname)
+{
+	struct ext_editheader_config *ext_config = 
+		(struct ext_editheader_config *) ext->context;
+	const struct ext_editheader_header *header;
+	
+	if ( strcasecmp(hname, "received") == 0 
+		|| strcasecmp(hname, "auto-submitted") == 0 ) {
+		return TRUE;
+	}
 
-/*
- * Operations
- */
+	if ( strcasecmp(hname, "subject") == 0 ) {
+		return FALSE;
+	}
 
-extern const struct sieve_operation_def addheader_operation;
-//extern const struct sieve_operation_def deleteheader_operation;
+	if ( (header=ext_editheader_config_header_find(ext_config, hname)) == NULL )
+		return FALSE;
 


More information about the dovecot-cvs mailing list