From 12a317ad6f62f60192c26175828c50f2a37544f6 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 20 Dec 2009 10:25:08 +0100 Subject: [PATCH] Implemented script name checking using the requirements specified in the ManageSieve draft. --- TODO | 1 - src/lib-sieve/plugins/include/cmd-include.c | 4 +- src/lib-sieve/sieve-script.c | 48 +++++++++++++++++++++ src/lib-sieve/sieve-script.h | 7 +++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 6f2d23202..3917fd269 100644 --- a/TODO +++ b/TODO @@ -15,7 +15,6 @@ Next (in order of descending priority/precedence): * Implement namespace support for variables extension (to complete include extension) * Update include extension to latest draft: - - Perform script name check - Implement global namespace - Allow placing the global command anywhere in the script - Implement required ManageSieve behavior diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c index 473c9e6c0..4cfc4b96c 100644 --- a/src/lib-sieve/plugins/include/cmd-include.c +++ b/src/lib-sieve/plugins/include/cmd-include.c @@ -226,9 +226,9 @@ static bool cmd_include_validate script_name = sieve_ast_argument_strc(arg); - if ( strchr(script_name, '/') != NULL ) { + if ( !sieve_script_name_is_valid(script_name) ) { sieve_argument_validate_error(valdtr, arg, - "include: '/' not allowed in script name (%s)", + "include: invalid script name '%s'", str_sanitize(script_name, 80)); return FALSE; } diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 3d41d8f79..bda41a77b 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -3,6 +3,8 @@ #include "lib.h" #include "compat.h" +#include "unichar.h" +#include "array.h" #include "istream.h" #include "eacces-error.h" @@ -21,6 +23,52 @@ #define SIEVE_READ_BLOCK_SIZE (1024*8) +/* + * Script name + */ + +bool sieve_script_name_is_valid(const char *scriptname) +{ + ARRAY_TYPE(unichars) uni_name; + unsigned int count, i; + const unichar_t *name_chars; + + /* Intialize array for unicode characters */ + t_array_init(&uni_name, strlen(scriptname)* 4); + + /* Convert UTF-8 to UCS4/UTF-32 */ + if ( uni_utf8_to_ucs4(scriptname, &uni_name) < 0 ) + return FALSE; + + /* Scan name for invalid characters */ + name_chars = array_get(&uni_name, &count); + for ( i = 0; i < count; i++ ) { + + /* 0000-001F; [CONTROL CHARACTERS] */ + if ( name_chars[i] <= 0x001f ) + return FALSE; + + /* 002F; SLASH */ + if ( name_chars[i] == 0x002f ) + return FALSE; + + /* 007F; DELETE */ + if ( name_chars[i] == 0x007f ) + return FALSE; + + /* 0080-009F; [CONTROL CHARACTERS] */ + if ( name_chars[i] >= 0x0080 && name_chars[i] <= 0x009f ) + return FALSE; + + /* 2028; LINE SEPARATOR */ + /* 2029; PARAGRAPH SEPARATOR */ + if ( name_chars[i] == 0x2028 || name_chars[i] == 0x2029 ) + return FALSE; + } + + return TRUE; +} + /* * Filename to name/name to filename */ diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h index 2970e5fa4..ebd8bc0e4 100644 --- a/src/lib-sieve/sieve-script.h +++ b/src/lib-sieve/sieve-script.h @@ -8,6 +8,13 @@ #include <sys/types.h> + +/* + * Sieve script name + */ + +bool sieve_script_name_is_valid(const char *scriptname); + /* * Sieve script object */ -- GitLab