dovecot-1.2-sieve: Spamtest extension: further developed configu...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sun Jan 3 20:26:29 EET 2010


details:   http://hg.rename-it.nl/dovecot-1.2-sieve/rev/fc604fb4b9ba
changeset: 1181:fc604fb4b9ba
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Jan 03 19:26:23 2010 +0100
description:
Spamtest extension: further developed configuration loading and testing.

diffstat:

 Makefile.am                                                    |   10 +-
 src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c |  139 +++++++++----
 src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h |    1 +
 tests/extensions/spamvirustest/spamtest.svtest                 |   41 ++++
 4 files changed, 142 insertions(+), 49 deletions(-)

diffs (294 lines):

diff -r cd5f4f907a6d -r fc604fb4b9ba Makefile.am
--- a/Makefile.am	Sun Jan 03 17:09:01 2010 +0100
+++ b/Makefile.am	Sun Jan 03 19:26:23 2010 +0100
@@ -38,6 +38,13 @@
 TEST_BIN = $(TESTSUITE_BIN)
 endif
 
+if BUILD_UNFINISHED
+test_unfinished = \
+	tests/extensions/spamvirustest/spamtest.svtest
+else
+test_unfinished = 
+endif
+
 test_cases = \
 	tests/testsuite.svtest\
 	tests/control-structures.svtest \
@@ -116,7 +123,8 @@
 	tests/deprecated/notify/mailto.svtest \
 	tests/deprecated/notify/errors.svtest \
 	tests/deprecated/notify/execute.svtest \
-	tests/deprecated/notify/denotify.svtest
+	tests/deprecated/notify/denotify.svtest \
+	$(test_unfinished)
 
 if HAVE_DOVECOT_LIBS
 
diff -r cd5f4f907a6d -r fc604fb4b9ba src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
--- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c	Sun Jan 03 17:09:01 2010 +0100
+++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c	Sun Jan 03 19:26:23 2010 +0100
@@ -32,6 +32,8 @@
 };
 
 struct ext_spamvirustest_data {
+	pool_t pool;
+
 	struct ext_spamvirustest_header_spec status_header;
 	struct ext_spamvirustest_header_spec max_header;
 
@@ -87,8 +89,8 @@
  * Configuration parser
  */
 
-static bool ext_spamvirustest_parse_header_spec
-(pool_t pool, const char *data, struct ext_spamvirustest_header_spec *spec,
+static bool ext_spamvirustest_header_spec_parse
+(struct ext_spamvirustest_header_spec *spec, pool_t pool, const char *data, 
 	const char **error_r)
 {
 	const char *p;
@@ -137,6 +139,12 @@
 	return TRUE;
 }
 
+static void ext_spamvirustest_header_spec_free
+(struct ext_spamvirustest_header_spec *spec)
+{
+	regfree(&spec->regexp);
+}
+
 static bool ext_spamvirustest_parse_strlen_value
 (const char *str_value, float *value_r, const char **error_r)
 {
@@ -147,7 +155,7 @@
 		*error_r = "empty value";		
 		return FALSE;
 	}
-
+	
 	while ( *p == ch ) p++;
 
 	if ( *p != '\0' ) {
@@ -229,13 +237,72 @@
  * Extension initialization
  */
 
+static bool ext_spamvirustest_config_load
+(struct ext_spamvirustest_data *ext_data, const char *ext_name, 
+	const char *status_header, const char *max_header, 
+	const char *status_type, const char *max_value)
+{
+	const char *error;
+
+	if ( !ext_spamvirustest_header_spec_parse
+		(&ext_data->status_header, ext_data->pool, status_header, &error) ) {
+		sieve_sys_error("%s: invalid status header specification "
+			"'%s': %s", ext_name, status_header, error);
+		return FALSE;
+	}
+
+	if ( max_header != NULL && !ext_spamvirustest_header_spec_parse
+		(&ext_data->max_header, ext_data->pool, max_header, &error) ) {
+		sieve_sys_error("%s: invalid max header specification "
+			"'%s': %s", ext_name, max_header, error);
+		return FALSE;
+	}
+
+	if ( status_type == NULL || strcmp(status_type, "value") == 0 ) {
+		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_VALUE;
+	} else if ( strcmp(status_type, "strlen") == 0 ) {
+		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN;
+	} else if ( strcmp(status_type, "yesno") == 0 ) {
+		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN;
+	} else {
+		sieve_sys_error("%s: invalid status type '%s'", ext_name, status_type);
+		return FALSE;
+	}
+
+	if ( max_value != NULL ) {
+		switch ( ext_data->status_type ) {
+		case EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN:
+		case EXT_SPAMVIRUSTEST_STATUS_TYPE_VALUE:	
+			if ( !ext_spamvirustest_parse_decimal_value
+				(max_value, &ext_data->max_value, &error) ) {
+				sieve_sys_error("%s: invalid max value specification "
+					"'%s': %s", ext_name, max_value, error);
+				return FALSE;
+			}
+			break;
+		case EXT_SPAMVIRUSTEST_STATUS_TYPE_YESNO:
+			ext_data->yes_string = p_strdup(ext_data->pool, max_value);
+			ext_data->max_value = 1;
+			break;
+		}	
+	}
+
+	return TRUE;
+}
+
+static void ext_spamvirustest_config_free(struct ext_spamvirustest_data *ext_data)
+{
+	ext_spamvirustest_header_spec_free(&ext_data->status_header);
+	ext_spamvirustest_header_spec_free(&ext_data->max_header);
+}
+
 bool ext_spamvirustest_load(const struct sieve_extension *ext, void **context)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	struct ext_spamvirustest_data *ext_data;
 	const char *status_header, *max_header, *status_type, *max_value;
 	const char *ext_name;
-	const char *error;
+	pool_t pool;
 
 	if ( *context != NULL ) {
 		ext_spamvirustest_unload(ext);
@@ -271,71 +338,47 @@
 	}
 
 	if ( max_header != NULL && max_value != NULL ) {
-		sieve_sys_warning("%s: sieve_%s_max_header and sieve_%s_max_value "
+		sieve_sys_error("%s: sieve_%s_max_header and sieve_%s_max_value "
 			"cannot both be configured", ext_name, ext_name, ext_name);
 		return TRUE;
 	}
 
 	if ( max_header == NULL && max_value == NULL ) {
-		sieve_sys_warning("%s: none of sieve_%s_max_header or sieve_%s_max_value "
+		sieve_sys_error("%s: none of sieve_%s_max_header or sieve_%s_max_value "
 			"is configured", ext_name, ext_name, ext_name);
 		return TRUE;
 	}
 
 	/* Pre-process configuration */
 
-	ext_data = p_new(svinst->pool, struct ext_spamvirustest_data, 1);
+	pool = pool_alloconly_create("spamvirustest_data", 512);
+	ext_data = p_new(pool, struct ext_spamvirustest_data, 1);
+	ext_data->pool = pool;
 
-	if ( !ext_spamvirustest_parse_header_spec
-		(svinst->pool, status_header, &ext_data->status_header, &error) ) {
-		sieve_sys_warning("%s: invalid status header specification "
-			"'%s': %s", ext_name, status_header, error);
-		return TRUE;
+	if ( !ext_spamvirustest_config_load
+		(ext_data, ext_name, status_header, max_header, status_type, max_value) ) {
+		sieve_sys_warning("%s: extension not configured, "
+			"tests will always match against \"0\"", ext_name);
+		ext_spamvirustest_config_free(ext_data);
+		pool_unref(&ext_data->pool);
+	} else { 
+		*context = (void *) ext_data;
 	}
 
-	if ( max_header != NULL && !ext_spamvirustest_parse_header_spec
-		(svinst->pool, max_header, &ext_data->max_header, &error) ) {
-		sieve_sys_warning("%s: invalid max header specification "
-			"'%s': %s", ext_name, max_header, error);
-		return TRUE;
-	}
-
-	if ( status_type == NULL || strcmp(status_type, "value") == 0 ) {
-		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_VALUE;
-	} else if ( strcmp(status_type, "strlen") == 0 ) {
-		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN;
-	} else if ( strcmp(status_type, "yesno") == 0 ) {
-		ext_data->status_type = EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN;
-	}
-
-	if ( max_value != NULL ) {
-		switch ( ext_data->status_type ) {
-		case EXT_SPAMVIRUSTEST_STATUS_TYPE_STRLEN:
-		case EXT_SPAMVIRUSTEST_STATUS_TYPE_VALUE:	
-			if ( !ext_spamvirustest_parse_decimal_value
-				(max_value, &ext_data->max_value, &error) ) {
-				sieve_sys_warning("%s: invalid max value specification "
-					"'%s': %s", ext_name, max_value, error);
-				return TRUE;
-			}
-			break;
-		case EXT_SPAMVIRUSTEST_STATUS_TYPE_YESNO:
-			ext_data->yes_string = p_strdup(svinst->pool, max_value);
-			ext_data->max_value = 1;
-			break;
-		}	
-	} 
-
-	*context = (void *) ext_data;
 	return TRUE;
 }
 
 void ext_spamvirustest_unload(const struct sieve_extension *ext)
 {
-	/* FIXME */
+	struct ext_spamvirustest_data *ext_data = 
+		(struct ext_spamvirustest_data *) ext->context;
+	
+	ext_spamvirustest_header_spec_free(&ext_data->status_header);
+	ext_spamvirustest_header_spec_free(&ext_data->max_header);
+	
+	pool_unref(&ext_data->pool);
 }
 
-
 /*
  * Score extraction
  */
diff -r cd5f4f907a6d -r fc604fb4b9ba src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h
--- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h	Sun Jan 03 17:09:01 2010 +0100
+++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h	Sun Jan 03 19:26:23 2010 +0100
@@ -15,6 +15,7 @@
 extern const struct sieve_extension_def virustest_extension;
 
 bool ext_spamvirustest_load(const struct sieve_extension *ext, void **context);
+void ext_spamvirustest_unload(const struct sieve_extension *ext);
 
 /* 
  * Tests
diff -r cd5f4f907a6d -r fc604fb4b9ba tests/extensions/spamvirustest/spamtest.svtest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/extensions/spamvirustest/spamtest.svtest	Sun Jan 03 19:26:23 2010 +0100
@@ -0,0 +1,41 @@
+require "vnd.dovecot.testsuite";
+require "spamtest";
+
+/*
+ * Value
+ */
+
+test_set "message" text:
+From: legitimate at example.com
+To: victim at dovecot.org
+Subject: Not spammish
+X-Company-MailScanner-SpamScore: -1.6 (-)
+X-Company-MailScanner-SpamCheck: 
+	No, score=-1.6 required=5.0 tests=AWL,BAYES_00,HTML_IMAGE_RATIO_02,HTML_MESSAGE,MIME_HTML_MOSTLY
+	autolearn=no version=3.2.5
+
+Test!
+.
+;
+
+test_config :set "sieve_spamtest_status_header"
+	"X-Company-MailScanner-SpamCheck: [ \\ta-zA-Z]+, score=(-?[0-9]+.[0-9]+)";
+test_config :set "sieve_spamtest_max_header"
+	"X-Company-MailScanner-SpamCheck: [ \\ta-zA-Z]+, score=-?[0-9]+.[0-9]+ required=(-?[0-9]+.[0-9]+)";
+test_config :set "sieve_spamtest_status_type" "value";
+test_config :reload "spamtest";
+
+test "Value: subzero" {
+	if spamtest :is "0" {
+		test_fail "spamtest not configured";
+	}
+
+	if not spamtest :is "1" {
+		test_fail "wrong spam value produced";
+	}
+
+	if spamtest :is "2" {
+		test_fail "spam test matches anything";
+	}
+}
+


More information about the dovecot-cvs mailing list