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.joz...@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
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org

Reply via email to