From 7d8dc7b051c737577ab0c19dcf2dc3d773945f96 Mon Sep 17 00:00:00 2001
From: root <root@f11391a1.federatedcomputer.cloud>
Date: Fri, 20 Sep 2024 16:09:58 +0000
Subject: [PATCH] Added sieve support for mail.sh

---
 lib/mail.sh | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/lib/mail.sh b/lib/mail.sh
index d023038..66d9bb9 100644
--- a/lib/mail.sh
+++ b/lib/mail.sh
@@ -13,7 +13,11 @@ config_mail() {
     mkdir -p /federated/apps/mail/data/var/mail-state &> /dev/null
     mkdir -p /federated/apps/mail/data/var/log/mail &> /dev/null
     mkdir -p /federated/apps/mail/data/tmp/docker-mailserver &> /dev/null
+    mkdir -p /federated/apps/mail/data/etc/dovecot/conf.d &> /dev/null
+    mkdir -p /federated/apps/mail/data/home &> /dev/null
     cp /federated/certs/certs/$DOMAIN.crt /federated/certs/private/$DOMAIN.key /federated/apps/mail/data/root/certs/
+    chgrp 5000 /federated/apps/mail/data/home
+    chmod g+rwx /federated/apps/mail/data/home
   fi
 
 cat > /federated/apps/mail/docker-compose.yml <<EOF
@@ -35,7 +39,10 @@ services:
       - "465:465"
       - "587:587"
       - "993:993"
+      - "4190:4190"
     volumes:
+      - ./data/etc/dovecot/conf.d/90-sieve.conf:/etc/dovecot/conf.d/90-sieve.conf
+      - ./data/home:/home
       - ./data/root/certs:/root/certs
       - ./data/var/mail:/var/mail/
       - ./data/var/mail-state:/var/mail-state/
@@ -97,6 +104,7 @@ SASLAUTHD_LDAP_SEARCH_BASE=ou=people,dc=federatedcomputer,dc=cloud
 SASLAUTHD_LDAP_FILTER=(&(objectClass=inetOrgPerson)(mail=%U@%r))
 POSTMASTER_ADDRESS=postmaster@localhost.localdomain
 POSTFIX_MESSAGE_SIZE_LIMIT=100000000
+ENABLE_MANAGESIEVE=1
 EOF
 chmod 600 /federated/apps/mail/.env
 
@@ -107,6 +115,121 @@ smtpd_sender_login_maps = ldap:/etc/postfix/ldap-aliases.cf
 smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname
 EOF
 
+cat > /federated/apps/mail/data/etc/dovecot/conf.d/90-sieve.conf <<'EOF'
+##
+## Settings for the Sieve interpreter
+##
+
+# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf
+# by adding it to the respective mail_plugins= settings.
+
+plugin {
+  # The path to the user's main active script. If ManageSieve is used, this the
+  # location of the symbolic link controlled by ManageSieve.
+  sieve = ~/.dovecot.sieve
+
+  # The default Sieve script when the user has none. This is a path to a global
+  # sieve script file, which gets executed ONLY if user's private Sieve script
+  # doesn't exist. Be sure to pre-compile this script manually using the sievec
+  # command line tool.
+  # --> See sieve_before fore executing scripts before the user's personal
+  #     script.
+  #sieve_default = /var/lib/dovecot/sieve/default.sieve
+
+  # Directory for :personal include scripts for the include extension. This
+  # is also where the ManageSieve service stores the user's scripts.
+  sieve_dir = ~/sieve
+
+  # Directory for :global include scripts for the include extension.
+  #sieve_global_dir =
+
+  # Path to a script file or a directory containing script files that need to be
+  # executed before the user's script. If the path points to a directory, all
+  # the Sieve scripts contained therein (with the proper .sieve extension) are
+  # executed. The order of execution within a directory is determined by the
+  # file names, using a normal 8bit per-character comparison. Multiple script
+  # file or directory paths can be specified by appending an increasing number.
+  sieve_before = /usr/lib/dovecot/sieve-global/before/
+  #sieve_before2 =
+  #sieve_before3 = (etc...)
+
+  # Identical to sieve_before, only the specified scripts are executed after the
+  # user's script (only when keep is still in effect!). Multiple script file or
+  # directory paths can be specified by appending an increasing number.
+  sieve_after = /usr/lib/dovecot/sieve-global/after/
+  #sieve_after2 =
+  #sieve_after2 = (etc...)
+
+  # Which Sieve language extensions are available to users. By default, all
+  # supported extensions are available, except for deprecated extensions or
+  # those that are still under development. Some system administrators may want
+  # to disable certain Sieve extensions or enable those that are not available
+  # by default. This setting can use '+' and '-' to specify differences relative
+  # to the default. For example `sieve_extensions = +imapflags' will enable the
+  # deprecated imapflags extension in addition to all extensions were already
+  # enabled by default.
+  #sieve_extensions = +notify +imapflags
+  sieve_extensions = +notify +imapflags +vnd.dovecot.pipe +vnd.dovecot.filter
+
+  # Which Sieve language extensions are ONLY available in global scripts. This
+  # can be used to restrict the use of certain Sieve extensions to administrator
+  # control, for instance when these extensions can cause security concerns.
+  # This setting has higher precedence than the `sieve_extensions' setting
+  # (above), meaning that the extensions enabled with this setting are never
+  # available to the user's personal script no matter what is specified for the
+  # `sieve_extensions' setting. The syntax of this setting is similar to the
+  # `sieve_extensions' setting, with the difference that extensions are
+  # enabled or disabled for exclusive use in global scripts. Currently, no
+  # extensions are marked as such by default.
+  #sieve_global_extensions =
+
+  # The Pigeonhole Sieve interpreter can have plugins of its own. Using this
+  # setting, the used plugins can be specified. Check the Dovecot wiki
+  # (wiki2.dovecot.org) or the pigeonhole website
+  # (http://pigeonhole.dovecot.org) for available plugins.
+  # The sieve_extprograms plugin is included in this release.
+  #sieve_plugins =
+  sieve_plugins = sieve_imapsieve sieve_extprograms
+
+  # The separator that is expected between the :user and :detail
+  # address parts introduced by the subaddress extension. This may
+  # also be a sequence of characters (e.g. '--'). The current
+  # implementation looks for the separator from the left of the
+  # localpart and uses the first one encountered. The :user part is
+  # left of the separator and the :detail part is right. This setting
+  # is also used by Dovecot's LMTP service.
+  #recipient_delimiter = +
+
+  # The maximum size of a Sieve script. The compiler will refuse to compile any
+  # script larger than this limit. If set to 0, no limit on the script size is
+  # enforced.
+  #sieve_max_script_size = 1M
+
+  # The maximum number of actions that can be performed during a single script
+  # execution. If set to 0, no limit on the total number of actions is enforced.
+  #sieve_max_actions = 32
+
+  # The maximum number of redirect actions that can be performed during a single
+  # script execution. If set to 0, no redirect actions are allowed.
+  #sieve_max_redirects = 4
+
+  # 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)
+  #sieve_quota_max_scripts = 0
+
+  # The maximum amount of disk storage a single user's scripts may occupy. If
+  # set to 0, no limit on the used amount of disk storage is enforced.
+  # (Currently only relevant for ManageSieve)
+  #sieve_quota_max_storage = 0
+
+  # Locations of programs that can be called by the sieve_extprograms plugin
+  sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe
+  sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter
+  sieve_vacation_send_from_recipient = yes
+}
+EOF
+
 cat > /federated/apps/mail/data/tmp/docker-mailserver/fail2ban-jail.cf <<'EOF'
 [DEFAULT]
 
@@ -177,3 +300,24 @@ start_mail() {
 
   echo -ne "done."
 }
+uninstall_mail() {
+  echo -ne "* Uninstalling mail container.."
+  spin &
+  SPINPID=$!
+
+  # First stop the service
+  cd /federated/apps/mail && docker-compose -f docker-compose.yml -p mail down &> /dev/null
+
+  # Delete the app directory
+  rm -rf /federated/apps/mail
+
+  # Delete the image
+  docker.io/mailserver/docker-mailserver:$IMAGE_VERSION &> /dev/null
+
+  # Delete the DNS record
+  docker exec pdns pdnsutil delete-rrset $DOMAIN mail._domainkey TXT
+  docker exec pdns pdnsutil delete-rrset $DOMAIN _dmarc TXT
+
+  kill -9 $SPINPID &> /dev/null
+  echo -ne "done.\n"
+}