From 609125fd1271be86cecd66938dbee61fce7ffa64 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@open-xchange.com> Date: Tue, 20 Aug 2024 03:21:39 +0200 Subject: [PATCH] lib-sieve: sieve-extensions - Migrate Sieve extension settings to new config structure --- src/lib-sieve/sieve-extensions.c | 172 +++++++++++++++++-------------- src/lib-sieve/sieve-settings.c | 19 ++++ src/lib-sieve/sieve-settings.h | 4 + 3 files changed, 115 insertions(+), 80 deletions(-) diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index a6400c438..32eddc8c0 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -9,7 +9,6 @@ #include "sieve-common.h" #include "sieve-error.h" -#include "sieve-settings.old.h" #include "sieve-extensions.h" /* @@ -28,6 +27,11 @@ _sieve_extension_register(struct sieve_instance *svinst, bool load, bool required, struct sieve_extension **ext_r); +static int +sieve_extensions_set_array(struct sieve_instance *svinst, + const ARRAY_TYPE(const_string) *ext_names, + bool global, bool implicit); + /* * Instance global context */ @@ -115,7 +119,22 @@ extern const struct sieve_extension_def extracttext_extension; extern const struct sieve_extension_def mboxmetadata_extension; extern const struct sieve_extension_def servermetadata_extension; -const struct sieve_extension_def *sieve_core_extensions[] = { +extern const struct sieve_extension_def vacation_seconds_extension; +extern const struct sieve_extension_def spamtest_extension; +extern const struct sieve_extension_def spamtestplus_extension; +extern const struct sieve_extension_def virustest_extension; +extern const struct sieve_extension_def editheader_extension; +extern const struct sieve_extension_def special_use_extension; + +extern const struct sieve_extension_def vnd_debug_extension; +extern const struct sieve_extension_def vnd_environment_extension; +extern const struct sieve_extension_def vnd_report_extension; + +#ifdef HAVE_SIEVE_UNFINISHED +extern const struct sieve_extension_def ereject_extension; +#endif + +const struct sieve_extension_def *sieve_extensions[] = { /* Core extensions */ &fileinto_extension, &reject_extension, &envelope_extension, &encoded_character_extension, @@ -128,29 +147,12 @@ const struct sieve_extension_def *sieve_core_extensions[] = { &variables_extension, &enotify_extension, &environment_extension, &mailbox_extension, &date_extension, &index_extension, &ihave_extension, &duplicate_extension, &mime_extension, &foreverypart_extension, - &extracttext_extension -}; - -const unsigned int sieve_core_extensions_count = - N_ELEMENTS(sieve_core_extensions); - -/* Extra; - * These are not enabled by default, e.g. because explicit configuration is - * necessary to make these useful. - */ + &extracttext_extension, -extern const struct sieve_extension_def vacation_seconds_extension; -extern const struct sieve_extension_def spamtest_extension; -extern const struct sieve_extension_def spamtestplus_extension; -extern const struct sieve_extension_def virustest_extension; -extern const struct sieve_extension_def editheader_extension; -extern const struct sieve_extension_def special_use_extension; - -extern const struct sieve_extension_def vnd_debug_extension; -extern const struct sieve_extension_def vnd_environment_extension; -extern const struct sieve_extension_def vnd_report_extension; - -const struct sieve_extension_def *sieve_extra_extensions[] = { + /* Extra; + These are not enabled by default, e.g. because explicit configuration + is necessary to make these useful. + */ &vacation_seconds_extension, &spamtest_extension, &spamtestplus_extension, &virustest_extension, &editheader_extension, &mboxmetadata_extension, &servermetadata_extension, @@ -158,27 +160,14 @@ const struct sieve_extension_def *sieve_extra_extensions[] = { /* vnd.dovecot. */ &vnd_debug_extension, &vnd_environment_extension, &vnd_report_extension, -}; - -const unsigned int sieve_extra_extensions_count = - N_ELEMENTS(sieve_extra_extensions); - -/* - * Unfinished extensions - */ #ifdef HAVE_SIEVE_UNFINISHED - -extern const struct sieve_extension_def ereject_extension; - -const struct sieve_extension_def *sieve_unfinished_extensions[] = { - &ereject_extension + /* Unfinished extensions */ + &ereject_extension, +#endif }; -const unsigned int sieve_unfinished_extensions_count = - N_ELEMENTS(sieve_unfinished_extensions); - -#endif /* HAVE_SIEVE_UNFINISHED */ +const unsigned int sieve_extensions_count = N_ELEMENTS(sieve_extensions); /* * Extensions init/deinit @@ -226,60 +215,34 @@ int sieve_extensions_init(struct sieve_instance *svinst) } /* Pre-load core extensions */ - for (i = 0; i < sieve_core_extensions_count; i++) { - if (sieve_extension_register(svinst, sieve_core_extensions[i], - TRUE, NULL) < 0) - return -1; - } - - /* Pre-load extra extensions */ - for (i = 0; i < sieve_extra_extensions_count; i++) { - if (sieve_extension_register(svinst, sieve_extra_extensions[i], + for (i = 0; i < sieve_extensions_count; i++) { + if (sieve_extension_register(svinst, sieve_extensions[i], FALSE, NULL) < 0) return -1; } -#ifdef HAVE_SIEVE_UNFINISHED - /* Register unfinished extensions */ - for (i = 0; i < sieve_unfinished_extensions_count; i++) { - if (sieve_extension_register( - svinst, sieve_unfinished_extensions[i], FALSE, - NULL) < 0) - return -1; - } -#endif - /* More extensions can be added through plugins */ return 0; } int sieve_extensions_load(struct sieve_instance *svinst) { - const char *extensions; - /* Apply sieve_extensions configuration */ - if ((extensions = sieve_setting_get( - svinst, "sieve_extensions")) != NULL) { - if (sieve_extensions_set_string(svinst, extensions, - FALSE, FALSE) < 0) - return -1; - } + if (sieve_extensions_set_array(svinst, &svinst->set->extensions, + FALSE, FALSE) < 0) + return -1; /* Apply sieve_global_extensions configuration */ - if ((extensions = sieve_setting_get( - svinst, "sieve_global_extensions")) != NULL) { - if (sieve_extensions_set_string(svinst, extensions, - TRUE, FALSE) < 0) - return -1; - } + if (sieve_extensions_set_array(svinst, &svinst->set->global_extensions, + TRUE, FALSE) < 0) + return -1; /* Apply sieve_implicit_extensions configuration */ - if ((extensions = sieve_setting_get( - svinst, "sieve_implicit_extensions")) != NULL) { - if (sieve_extensions_set_string(svinst, extensions, - FALSE, TRUE) < 0) - return -1; - } + if (sieve_extensions_set_array(svinst, + &svinst->set->implicit_extensions, + FALSE, TRUE) < 0) + return -1; + return 0; } @@ -679,6 +642,55 @@ sieve_extension_set_implicit(struct sieve_extension *ext, bool enabled) return ret; } +static int +sieve_extensions_set_array(struct sieve_instance *svinst, + const ARRAY_TYPE(const_string) *ext_names, + bool global, bool implicit) +{ + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + const char *name; + + if (array_is_empty(ext_names)) + return 0; + + int ret = 0; + array_foreach_elem(ext_names, name) { + struct sieve_extension *ext; + + ext = hash_table_lookup(ext_reg->extension_index, name); + if (ext == NULL || ext->def == NULL || + *(ext->def->name) == '@') { + e_warning(svinst->event, + "ignored unknown extension '%s' " + "while configuring available extensions", + name); + continue; + } + if (ext->id < 0) + continue; + + /* Perform actual activation/deactivation */ + if (global) { + if (sieve_extension_set_global(ext, TRUE) < 0) { + ret = -1; + break; + } + } else if (implicit) { + if (sieve_extension_set_implicit(ext, TRUE) < 0) { + ret = -1; + break; + } + } else { + if (sieve_extension_set_enabled(ext, TRUE) < 0) { + ret = -1; + break; + } + } + } + + return ret; +} + int sieve_extensions_set_string(struct sieve_instance *svinst, const char *ext_string, bool global, bool implicit) diff --git a/src/lib-sieve/sieve-settings.c b/src/lib-sieve/sieve-settings.c index 8320d35d7..68ce06386 100644 --- a/src/lib-sieve/sieve-settings.c +++ b/src/lib-sieve/sieve-settings.c @@ -40,6 +40,10 @@ static const struct setting_define sieve_setting_defines[] = { DEF(BOOLLIST, plugins), DEF(STR, plugin_dir), + DEF(BOOLLIST, extensions), + DEF(BOOLLIST, global_extensions), + DEF(BOOLLIST, implicit_extensions), + SETTING_DEFINE_LIST_END, }; @@ -66,6 +70,20 @@ const struct sieve_settings sieve_default_settings = { .plugins = ARRAY_INIT, .plugin_dir = MODULEDIR"/sieve", + + .extensions = ARRAY_INIT, + .global_extensions = ARRAY_INIT, + .implicit_extensions = ARRAY_INIT, +}; + +static const struct setting_keyvalue sieve_default_settings_keyvalue[] = { + { "sieve_extensions", + "fileinto reject envelope encoded-character vacation subaddress " + "comparator-i;ascii-numeric relational regex imap4flags copy include " + "body variables enotify environment mailbox date index ihave " + "duplicate mime foreverypart extracttext" + }, + { NULL, NULL } }; const struct setting_parser_info sieve_setting_parser_info = { @@ -73,6 +91,7 @@ const struct setting_parser_info sieve_setting_parser_info = { .defines = sieve_setting_defines, .defaults = &sieve_default_settings, + .default_settings = sieve_default_settings_keyvalue, .struct_size = sizeof(struct sieve_settings), diff --git a/src/lib-sieve/sieve-settings.h b/src/lib-sieve/sieve-settings.h index dc63b621a..158ce0f59 100644 --- a/src/lib-sieve/sieve-settings.h +++ b/src/lib-sieve/sieve-settings.h @@ -35,6 +35,10 @@ struct sieve_settings { ARRAY_TYPE(const_string) plugins; const char *plugin_dir; + ARRAY_TYPE(const_string) extensions; + ARRAY_TYPE(const_string) global_extensions; + ARRAY_TYPE(const_string) implicit_extensions; + struct { struct sieve_address_source redirect_envelope_from; const struct smtp_address *user_email; -- GitLab