diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index c590117d32bfdf01e02c34903324a9e3560fdb42..e0010b2a87f36ff73c9cf618b909e419dd9c904a 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -36,8 +36,12 @@ bool sieve_script_name_is_valid(const char *scriptname) const unichar_t *name_chars; size_t namelen = strlen(scriptname); - /* Check maximum length */ - if ( namelen > SIEVE_MAX_SCRIPT_NAME_LEN ) + /* Check minimum length */ + if ( namelen == 0 ) + return FALSE; + + /* Check worst-case maximum length */ + if ( namelen > SIEVE_MAX_SCRIPT_NAME_LEN * 4 ) return FALSE; /* Intialize array for unicode characters */ @@ -46,16 +50,24 @@ bool sieve_script_name_is_valid(const char *scriptname) /* 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); + + /* Check true maximum length */ + if ( count > SIEVE_MAX_SCRIPT_NAME_LEN ) + return FALSE; + + /* Scan name for invalid characters + * FIXME: compliance with Net-Unicode Definition (Section 2 of + * RFC 5198) is not checked fully and no normalization + * is performed. + */ for ( i = 0; i < count; i++ ) { /* 0000-001F; [CONTROL CHARACTERS] */ if ( name_chars[i] <= 0x001f ) return FALSE; - - /* 002F; SLASH */ + + /* 002F; SLASH (not RFC-prohibited, but '/' is dangerous) */ if ( name_chars[i] == 0x002f ) return FALSE; @@ -67,6 +79,10 @@ bool sieve_script_name_is_valid(const char *scriptname) if ( name_chars[i] >= 0x0080 && name_chars[i] <= 0x009f ) return FALSE; + /* 00FF */ + if ( name_chars[i] == 0x00ff ) + return FALSE; + /* 2028; LINE SEPARATOR */ /* 2029; PARAGRAPH SEPARATOR */ if ( name_chars[i] == 0x2028 || name_chars[i] == 0x2029 ) @@ -88,8 +104,8 @@ static inline const char *_sieve_scriptfile_get_basename(const char *filename) ext = strrchr(filename, '.'); if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 ) return filename; - - return t_strdup_until(filename, ext); + + return t_strdup_until(filename, ext); } bool sieve_script_file_has_extension(const char *filename) diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c index 3f357da103b6974ca2509532985a1ab403925b69..f441c054599a01f619e727602eadf98927384a3d 100644 --- a/src/managesieve/cmd-putscript.c +++ b/src/managesieve/cmd-putscript.c @@ -431,7 +431,7 @@ bool cmd_putscript(struct client_command_context *cmd) const char *scriptname; /* <scriptname> */ - if ( !client_read_string_args(cmd, 1, FALSE, &scriptname) || *scriptname == '\0' ) + if ( !client_read_string_args(cmd, 1, FALSE, &scriptname) ) return FALSE; return cmd_putscript_start(cmd, scriptname);