[Patch] Allow sieve redirects to specified domains only
Hello, The use case is simple: we have to forbid sieve redirects to outside, but should be able to redirect inside. The patch below adds a new sieve configuration option sieve_allowed_redirects to list the domains to which redirects are permitted and otherwise are not allowed. Please consider it. diff --git a/pigeonhole/doc/example-config/conf.d/90-sieve.conf b/pigeonhole/doc/example-config/conf.d/90-sieve.conf index 238bcf4..3b4ac65 100644 --- a/pigeonhole/doc/example-config/conf.d/90-sieve.conf +++ b/pigeonhole/doc/example-config/conf.d/90-sieve.conf @@ -126,6 +126,10 @@ plugin { # script execution. If set to 0, no redirect actions are allowed. #sieve_max_redirects = 4 + # The comma/space separated list of email domains where redirection is allowed. + # If the list is empty, there is no restriction. + sieve_allowed_redirects = + # The maximum number of personal Sieve scripts a single user can have. If set # to 0, no limit on the number of scripts is enforced. # (Currently only relevant for ManageSieve) diff --git a/pigeonhole/src/lib-sieve/cmd-redirect.c b/pigeonhole/src/lib-sieve/cmd-redirect.c index 6a3b0a4..17e9031 100644 --- a/pigeonhole/src/lib-sieve/cmd-redirect.c +++ b/pigeonhole/src/lib-sieve/cmd-redirect.c @@ -107,6 +107,24 @@ const struct sieve_action_def act_redirect = { .commit = act_redirect_commit, }; +static bool +cmd_redirect_allowed(struct sieve_instance *svinst, + const struct smtp_address *to_address) +{ + const char **domain; + bool result = TRUE; + + if (!svinst->allowed_redirects) + return TRUE; + for (domain = svinst->allowed_redirects; *domain != NULL; ++domain) { + if (strcasecmp(*domain, to_address->domain) == 0) { + return TRUE; + } + result = FALSE; + } + return result; +} + /* * Validation */ @@ -127,6 +145,12 @@ cmd_redirect_validate(struct sieve_validator *validator, if (!sieve_validator_argument_activate(validator, cmd, arg, FALSE)) return FALSE; + if (svinst->max_redirects == 0) { + sieve_command_validate_error(validator, cmd, + "local policy prohibits the use of a redirect action"); + return FALSE; + } + /* We can only assess the validity of the outgoing address when it is * a string literal. For runtime-generated strings this needs to be * done at runtime. @@ -148,14 +172,17 @@ cmd_redirect_validate(struct sieve_validator *validator, } } T_END; + if (!result && + !cmd_redirect_allowed(svinst, + sieve_address_parse_str(raw_address, &error))) { + sieve_command_validate_error(validator, cmd, + "local policy prohibits the use of a redirect action"); + return FALSE; + } + return result; } - if (svinst->max_redirects == 0) { - sieve_command_validate_error(validator, cmd, - "local policy prohibits the use of a redirect action"); - return FALSE; - } return TRUE; } @@ -238,6 +265,11 @@ cmd_redirect_operation_execute(const struct sieve_runtime_env *renv, "local policy prohibits the use of a redirect action"); return SIEVE_EXEC_FAILURE; } + if (!cmd_redirect_allowed(svinst, to_address)) { + sieve_runtime_error(renv, NULL, + "local policy prohibits the use of a redirect action"); + return SIEVE_EXEC_FAILURE; + } if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS)) { sieve_runtime_trace(renv, 0, "redirect action"); diff --git a/pigeonhole/src/lib-sieve/sieve-common.h b/pigeonhole/src/lib-sieve/sieve-common.h index e79fb4d..d980c9d 100644 --- a/pigeonhole/src/lib-sieve/sieve-common.h +++ b/pigeonhole/src/lib-sieve/sieve-common.h @@ -209,6 +209,7 @@ struct sieve_instance { const struct smtp_address *user_email, *user_email_implicit; struct sieve_address_source redirect_from; unsigned int redirect_duplicate_period; + const char **allowed_redirects; }; /* diff --git a/pigeonhole/src/lib-sieve/sieve-settings.c b/pigeonhole/src/lib-sieve/sieve-settings.c index 47f70da..70addc7 100644 --- a/pigeonhole/src/lib-sieve/sieve-settings.c +++ b/pigeonhole/src/lib-sieve/sieve-settings.c @@ -267,4 +267,10 @@ void sieve_settings_load(struct sieve_instance *svinst) svinst->user_email = address; } } + svinst->allowed_redirects = NULL; + str_setting = sieve_setting_get(svinst, "sieve_allowed_redirects"); + if (str_setting != NULL && *str_setting != '\0') { + svinst->allowed_redirects = + (const char **)p_strsplit_spaces(svinst->pool, str_setting, ", "); + } } Best regards, Jozsef -- E-mail : kadlecsik.jozsef@wigner.hun-ren.hu PGP key: https://wigner.hu/~kadlec/pgp_public_key.txt Address: Wigner Research Centre for Physics H-1525 Budapest 114, POB. 49, Hungary
participants (1)
-
Kadlecsik József