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