dovecot-2.1-pigeonhole: lib-sieve: added support for restricting...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Mon Dec 12 01:47:04 EET 2011


details:   http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/595ce12806d9
changeset: 1574:595ce12806d9
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Mon Dec 12 00:46:59 2011 +0100
description:
lib-sieve: added support for restricting certain extensions to (admin-controled) global scripts
- Added sieve_global_extensions setting.

diffstat:

 INSTALL                                            |   20 ++-
 src/lib-sieve-tool/sieve-tool.c                    |    6 +-
 src/lib-sieve/plugins/ihave/ext-ihave-binary.c     |   13 +-
 src/lib-sieve/plugins/ihave/tst-ihave.c            |   12 +-
 src/lib-sieve/plugins/include/ext-include-binary.c |    5 +-
 src/lib-sieve/plugins/include/ext-include-common.c |   21 ++-
 src/lib-sieve/sieve-binary.c                       |    6 +-
 src/lib-sieve/sieve-binary.h                       |    5 +-
 src/lib-sieve/sieve-common.h                       |    2 +-
 src/lib-sieve/sieve-extensions.c                   |  140 ++++++++++++++--------
 src/lib-sieve/sieve-extensions.h                   |    4 +-
 src/lib-sieve/sieve-interpreter.c                  |   33 ++++-
 src/lib-sieve/sieve-interpreter.h                  |    6 +-
 src/lib-sieve/sieve-plugins.c                      |   16 +-
 src/lib-sieve/sieve-runtime.h                      |    1 +
 src/lib-sieve/sieve-types.h                        |   18 ++-
 src/lib-sieve/sieve-validator.c                    |   28 ++++-
 src/lib-sieve/sieve-validator.h                    |    5 +-
 src/lib-sieve/sieve.c                              |   39 +++---
 src/lib-sieve/sieve.h                              |   15 +-
 src/managesieve/cmd-putscript.c                    |    3 +-
 src/plugins/lda-sieve/lda-sieve-plugin.c           |   56 +++++---
 src/sieve-tools/sieve-filter.c                     |    4 +-
 src/sieve-tools/sieve-test.c                       |    8 +-
 src/testsuite/testsuite-script.c                   |    9 +-
 src/testsuite/testsuite.c                          |    6 +-
 26 files changed, 316 insertions(+), 165 deletions(-)

diffs (truncated from 1370 to 300 lines):

diff -r d56a318174db -r 595ce12806d9 INSTALL
--- a/INSTALL	Mon Dec 12 00:25:47 2011 +0100
+++ b/INSTALL	Mon Dec 12 00:46:59 2011 +0100
@@ -104,10 +104,22 @@
    supported extensions are available, except for deprecated extensions or those 
    that are still under development. Some system administrators may want to 
    disable certain Sieve extensions or enable those that are not available by 
-   default. Supported extensions are listed on this page. This setting can use 
-   '+' and '-' to specify differences relative to the default. For example 
-   `sieve_extensions = +imapflags' will enable the deprecated imapflags
-   extension in addition to all extensions enabled by default. 
+   default. This setting can use '+' and '-' to specify differences relative to
+	 the default. For example `sieve_extensions = +imapflags' will enable the
+	 deprecated imapflags extension in addition to all extensions were already
+   enabled by default. 
+
+ sieve_global_extensions =
+   Which Sieve language extensions are ONLY avalable in global scripts. This can
+   be used to restrict the use of certain Sieve extensions to administrator
+   control, for instance when these extensions can cause security concerns. This
+	 setting has higher precedence than the `sieve_extensions' setting (above),
+   meaning that the extensions enabled with this setting are never available to
+   the user's personal script no matter what is specified for the 
+   `sieve_extensions' setting. The syntax of this setting is similar to
+   the `sieve_extensions' setting, with the difference that extensions are
+   enabled or disabled for exclusive use in global scripts. Currently, no
+   extensions are marked as such by default.
 
  sieve_plugins =
    The Pigeonhole Sieve interpreter can have plugins of its own. Using this
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve-tool/sieve-tool.c
--- a/src/lib-sieve-tool/sieve-tool.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve-tool/sieve-tool.c	Mon Dec 12 00:46:59 2011 +0100
@@ -519,7 +519,8 @@
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 	sieve_error_handler_accept_debuglog(ehandler, svinst->debug);
 
-	if ( (sbin = sieve_compile(svinst, filename, name, ehandler, NULL)) == NULL )
+	if ( (sbin = sieve_compile
+		(svinst, filename, name, ehandler, 0, NULL)) == NULL )
 		i_error("failed to compile sieve script '%s'", filename);
 
 	sieve_error_handler_unref(&ehandler);
@@ -536,7 +537,8 @@
 	ehandler = sieve_stderr_ehandler_create(svinst, 0);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
-	if ( (sbin = sieve_open(svinst, filename, NULL, ehandler, NULL)) == NULL ) {
+	if ( (sbin = sieve_open
+		(svinst, filename, NULL, ehandler, 0, NULL)) == NULL ) {
 		sieve_error_handler_unref(&ehandler);
 		i_fatal("failed to compile sieve script");
 	}
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/ihave/ext-ihave-binary.c
--- a/src/lib-sieve/plugins/ihave/ext-ihave-binary.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/plugins/ihave/ext-ihave-binary.c	Mon Dec 12 00:46:59 2011 +0100
@@ -25,7 +25,8 @@
 static bool ext_ihave_binary_open
 	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 static bool ext_ihave_binary_up_to_date
-	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
+	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context,
+		enum sieve_compile_flags cpflags);
 
 /* 
  * Binary include extension
@@ -187,16 +188,18 @@
 
 static bool ext_ihave_binary_up_to_date
 (const struct sieve_extension *ext, struct sieve_binary *sbin ATTR_UNUSED, 
-	void *context)
+	void *context, enum sieve_compile_flags cpflags)
 {
 	struct ext_ihave_binary_context *binctx = 
 		(struct ext_ihave_binary_context *) context;
-	const char *const *exts;
+	const struct sieve_extension *mext;
+	const char *const *mexts;
 	unsigned int count, i;
 	
-	exts = array_get(&binctx->missing_extensions, &count);
+	mexts = array_get(&binctx->missing_extensions, &count);
 	for ( i = 0; i < count; i++ ) {
-		if ( sieve_extension_get_by_name(ext->svinst, exts[i]) != NULL )
+		if ( (mext=sieve_extension_get_by_name(ext->svinst, mexts[i])) != NULL &&
+			((cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) == 0 || !mext->global) )
 			return FALSE;
 	}
 	
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/ihave/tst-ihave.c
--- a/src/lib-sieve/plugins/ihave/tst-ihave.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/plugins/ihave/tst-ihave.c	Mon Dec 12 00:46:59 2011 +0100
@@ -49,6 +49,8 @@
 
 	struct sieve_ast_argument *arg = tst->first_positional;
 	struct sieve_ast_argument *stritem;
+	enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr);
+	bool no_global = ( (cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0 );	
 	ARRAY_DEFINE(capabilities, struct _capability);
 	struct _capability capability;
 	const struct _capability *caps;
@@ -71,13 +73,14 @@
 		capability.arg = arg;
 		capability.ext = sieve_extension_get_by_name
 			(tst->ext->svinst, sieve_ast_argument_strc(arg));
-		array_append(&capabilities, &capability, 1);
 
-		if ( capability.ext == NULL ) {
+		if ( capability.ext == NULL || (no_global && capability.ext->global)) {
 			all_known = FALSE;
 
 			ext_ihave_ast_add_missing_extension
 				(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg));
+		} else {
+			array_append(&capabilities, &capability, 1);
 		}
 
 		break;
@@ -90,13 +93,14 @@
 			capability.arg = stritem;
 			capability.ext = sieve_extension_get_by_name
 				(tst->ext->svinst, sieve_ast_argument_strc(stritem));
-			array_append(&capabilities, &capability, 1);
 
-			if ( capability.ext == NULL ) {
+			if ( capability.ext == NULL || (no_global && capability.ext->global)) {
 				all_known = FALSE;
 
 				ext_ihave_ast_add_missing_extension
 					(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem));
+			} else {
+				array_append(&capabilities, &capability, 1);
 			}
 	
 			stritem = sieve_ast_strlist_next(stritem);
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/include/ext-include-binary.c
--- a/src/lib-sieve/plugins/include/ext-include-binary.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/plugins/include/ext-include-binary.c	Mon Dec 12 00:46:59 2011 +0100
@@ -28,7 +28,8 @@
 static bool ext_include_binary_open
 	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 static bool ext_include_binary_up_to_date
-	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
+	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context,
+		enum sieve_compile_flags cpflags);
 static void ext_include_binary_free
 	(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context);
 
@@ -327,7 +328,7 @@
 
 static bool ext_include_binary_up_to_date
 (const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin, 
-	void *context)
+	void *context, enum sieve_compile_flags cpflags ATTR_UNUSED)
 {
 	struct ext_include_binary_context *binctx = 
 		(struct ext_include_binary_context *) context;
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/include/ext-include-common.c
--- a/src/lib-sieve/plugins/include/ext-include-common.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/plugins/include/ext-include-common.c	Mon Dec 12 00:46:59 2011 +0100
@@ -520,6 +520,7 @@
 	{	
 		struct sieve_binary_block *inc_block;
 		const char *script_name = sieve_script_name(script);
+		enum sieve_compile_flags cpflags = 0;
 
 		/* Check whether include limit is exceeded */
 		if ( ext_include_binary_script_get_count(binctx) >= 
@@ -546,8 +547,11 @@
 		/* Included scripts inherit global variable scope */
 		(void)ext_include_create_ast_context(this_ext, ast, cmd->ast_node->ast);
 
+		if ( location != EXT_INCLUDE_LOCATION_GLOBAL )
+				cpflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL;
+
 		/* Validate */
-		if ( !sieve_validate(ast, ehandler, NULL) ) {
+		if ( !sieve_validate(ast, ehandler, cpflags, NULL) ) {
 			sieve_command_generate_error(gentr, cmd, 
 				"failed to validate included script '%s'", 
 				str_sanitize(script_name, 80));
@@ -681,12 +685,17 @@
 		/* We are the top-level interpreter instance */	
 		
 		if ( result == SIEVE_EXEC_OK ) {
+			enum sieve_runtime_flags rtflags = 0;
+	
+			if ( included->location != EXT_INCLUDE_LOCATION_GLOBAL )
+				rtflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL;
+
 			/* Create interpreter for top-level included script
 			 * (first sub-interpreter) 
 			 */
 			subinterp = sieve_interpreter_create_for_block
 				(included->block, included->script, renv->msgdata, renv->scriptenv, 
-					ehandler);
+					ehandler, rtflags);
 
 			if ( subinterp != NULL ) {			
 				curctx = ext_include_interpreter_context_init_child
@@ -734,14 +743,18 @@
 					result = ( sieve_interpreter_continue(subinterp, &interrupted) == 1 );
 				} else {
 					if ( curctx->include != NULL ) {
-
 						/* Sub-include requested */
 																	
 						if ( result == SIEVE_EXEC_OK ) {
+							enum sieve_runtime_flags rtflags = 0;
+	
+							if ( curctx->include->location != EXT_INCLUDE_LOCATION_GLOBAL )
+								rtflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL;
+
 							/* Create sub-interpreter */
 							subinterp = sieve_interpreter_create_for_block
 								(curctx->include->block, curctx->include->script, renv->msgdata,
-									renv->scriptenv, ehandler);			
+									renv->scriptenv, ehandler, rtflags);			
 
 							if ( subinterp != NULL ) {
 								curctx = ext_include_interpreter_context_init_child
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-binary.c
--- a/src/lib-sieve/sieve-binary.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/sieve-binary.c	Mon Dec 12 00:46:59 2011 +0100
@@ -290,7 +290,8 @@
  * Up-to-date checking
  */
 
-bool sieve_binary_up_to_date(struct sieve_binary *sbin)
+bool sieve_binary_up_to_date
+(struct sieve_binary *sbin, enum sieve_compile_flags cpflags)
 {
 	struct sieve_binary_extension_reg *const *regs;
 	unsigned int ext_count, i;
@@ -306,7 +307,8 @@
 		const struct sieve_binary_extension *binext = regs[i]->binext;
 		
 		if ( binext != NULL && binext->binary_up_to_date != NULL && 
-			!binext->binary_up_to_date(regs[i]->extension, sbin, regs[i]->context) )
+			!binext->binary_up_to_date
+				(regs[i]->extension, sbin, regs[i]->context, cpflags) )
 			return FALSE;
 	}
 	
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-binary.h
--- a/src/lib-sieve/sieve-binary.h	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/sieve-binary.h	Mon Dec 12 00:46:59 2011 +0100
@@ -64,7 +64,8 @@
 struct sieve_binary *sieve_binary_open
 	(struct sieve_instance *svinst, const char *path, 
 		struct sieve_script *script, enum sieve_error *error_r);
-bool sieve_binary_up_to_date(struct sieve_binary *sbin);
+bool sieve_binary_up_to_date
+	(struct sieve_binary *sbin, enum sieve_compile_flags cpflags);
 	
 /* 
  * Block management 
@@ -117,7 +118,7 @@
 	
 	bool (*binary_up_to_date)
 		(const struct sieve_extension *ext, struct sieve_binary *sbin,
-			void *context);	
+			void *context, enum sieve_compile_flags cpflags);	
 };
  
 void sieve_binary_extension_set_context
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-common.h
--- a/src/lib-sieve/sieve-common.h	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/sieve-common.h	Mon Dec 12 00:46:59 2011 +0100
@@ -145,7 +145,7 @@
 		enum sieve_error *error_r);
 bool sieve_validate
 	(struct sieve_ast *ast, struct sieve_error_handler *ehandler,
-		enum sieve_error *error_r);	
+		enum sieve_compile_flags flags, enum sieve_error *error_r);	
 
 /*
  * Sieve engine instance
diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-extensions.c
--- a/src/lib-sieve/sieve-extensions.c	Mon Dec 12 00:25:47 2011 +0100
+++ b/src/lib-sieve/sieve-extensions.c	Mon Dec 12 00:46:59 2011 +0100
@@ -197,7 +197,6 @@
 	unsigned int i;	
 	struct sieve_extension_registry *ext_reg = 
 		p_new(svinst->pool, struct sieve_extension_registry, 1);
-	const char *extensions;
 	struct sieve_extension *ext;
 
 	svinst->ext_reg = ext_reg;
@@ -260,16 +259,26 @@
 	}
 #endif
 
-	/* Use sieve_extensions if set */
-
-	if ( (extensions=sieve_setting_get(svinst, "sieve_extensions")) != NULL )
-		sieve_extensions_set_string(svinst, extensions);
-
 	/* More extensions can be added through plugins */
 


More information about the dovecot-cvs mailing list