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