From dc9e2a3e70954d460963e25b43889d0e55508024 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 11:34:58 +0100
Subject: [PATCH 01/27] Upgrade Snappymail to 2.21 and merge the webmail
 containers

---
 .github/workflows/build_test_deploy.yml       |   6 +-
 setup/flavors/compose/docker-compose.yml      |   2 +-
 setup/flavors/stack/docker-compose.yml        |   2 +-
 tests/build.hcl                               |  20 +--
 towncrier/newsfragments/2526.misc             |   1 +
 webmails/{roundcube => }/Dockerfile           |  48 ++++---
 ...ginx-roundcube.conf => nginx-webmail.conf} |   2 +-
 .../php-roundcube.conf => php-webmail.conf}   |   6 +-
 webmails/{roundcube/config => }/php.ini       |   2 +-
 webmails/snappymail/Dockerfile                |  54 --------
 webmails/snappymail/config.py                 |  16 ---
 .../snappymail/config/php-snappymail.conf     | 118 ------------------
 webmails/snappymail/defaults/default.ini      |  15 ---
 webmails/snappymail/defaults/default.json     |  50 ++++++++
 webmails/snappymail/defaults/php.ini          |   5 -
 webmails/snappymail/start.py                  |  34 -----
 webmails/{roundcube => }/start.py             |  31 +++--
 17 files changed, 120 insertions(+), 292 deletions(-)
 create mode 100644 towncrier/newsfragments/2526.misc
 rename webmails/{roundcube => }/Dockerfile (55%)
 rename webmails/{roundcube/config/nginx-roundcube.conf => nginx-webmail.conf} (97%)
 rename webmails/{roundcube/config/php-roundcube.conf => php-webmail.conf} (98%)
 rename webmails/{roundcube/config => }/php.ini (77%)
 delete mode 100644 webmails/snappymail/Dockerfile
 delete mode 100755 webmails/snappymail/config.py
 delete mode 100644 webmails/snappymail/config/php-snappymail.conf
 delete mode 100644 webmails/snappymail/defaults/default.ini
 create mode 100644 webmails/snappymail/defaults/default.json
 delete mode 100644 webmails/snappymail/defaults/php.ini
 delete mode 100755 webmails/snappymail/start.py
 rename webmails/{roundcube => }/start.py (71%)

diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml
index d1395bec..3b5dafc3 100644
--- a/.github/workflows/build_test_deploy.yml
+++ b/.github/workflows/build_test_deploy.yml
@@ -340,7 +340,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        target: ["core", "fetchmail", "filters", "snappymail", "roundcube", "webdav"]
+        target: ["core", "fetchmail", "filters", "webmail", "webdav"]
         time: ["2"]
         include:
           - target: "filters"
@@ -394,7 +394,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        target: ["setup", "docs", "fetchmail", "roundcube", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx", "snappymail"]
+        target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
     steps:
       - uses: actions/checkout@v3
       - name: Retrieve global variables
@@ -439,7 +439,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        target: ["setup", "docs", "fetchmail", "roundcube", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx", "snappymail"]
+        target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
     steps:
       - uses: actions/checkout@v3
       - name: Retrieve global variables
diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml
index 6dac166b..c7f37e01 100644
--- a/setup/flavors/compose/docker-compose.yml
+++ b/setup/flavors/compose/docker-compose.yml
@@ -168,7 +168,7 @@ services:
   # Webmail
   {% if webmail_type != 'none' %}
   webmail:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}}
+    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-{{ version }}}
     restart: always
     env_file: {{ env }}
     volumes:
diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml
index 89da923c..809362df 100644
--- a/setup/flavors/stack/docker-compose.yml
+++ b/setup/flavors/stack/docker-compose.yml
@@ -119,7 +119,7 @@ services:
 
   {% if webmail_type != 'none' %}
   webmail:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}}
+    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-{{ version }}}
     env_file: {{ env }}
     volumes:
       - "{{ root }}/webmail:/data"
diff --git a/tests/build.hcl b/tests/build.hcl
index 34955270..fd546ae4 100644
--- a/tests/build.hcl
+++ b/tests/build.hcl
@@ -36,8 +36,7 @@ group "default" {
     "imap",
     "smtp",
 
-    "snappymail",
-    "roundcube",
+    "webmail",
 
     "antivirus",
     "fetchmail",
@@ -169,24 +168,15 @@ target "smtp" {
 }
 
 # -----------------------------------------------------------------------------------------
-# Webmail images
+# Webmail image
 # -----------------------------------------------------------------------------------------
-target "snappymail" {
+target "webmail" {
   inherits = ["defaults"]
-  context = "webmails/snappymail/"
+  context = "webmails/"
   contexts = {
     base = "target:base"
   }
-  tags = tag("snappymail")
-}
-
-target "roundcube" {
-  inherits = ["defaults"]
-  context = "webmails/roundcube/"
-  contexts = {
-    base = "target:base"
-  }
-  tags = tag("roundcube")
+  tags = tag("webmail")
 }
 
 # -----------------------------------------------------------------------------------------
diff --git a/towncrier/newsfragments/2526.misc b/towncrier/newsfragments/2526.misc
new file mode 100644
index 00000000..9425e88a
--- /dev/null
+++ b/towncrier/newsfragments/2526.misc
@@ -0,0 +1 @@
+Upgrade Snappymail to 2.21 and merge the webmail containers
diff --git a/webmails/roundcube/Dockerfile b/webmails/Dockerfile
similarity index 55%
rename from webmails/roundcube/Dockerfile
rename to webmails/Dockerfile
index 8db6f984..ccc2da0c 100644
--- a/webmails/roundcube/Dockerfile
+++ b/webmails/Dockerfile
@@ -1,6 +1,5 @@
 # syntax=docker/dockerfile-upstream:1.4.3
 
-#roundcube image
 FROM base
 
 ARG VERSION
@@ -19,6 +18,7 @@ RUN set -euxo pipefail \
   ; mkdir -p /run/nginx \
   ; mkdir -p /conf
 
+# roundcube
 ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.5.3/roundcubemail-1.5.3-complete.tar.gz
 ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.4.3/carddav-v4.4.3.tar.gz
 
@@ -26,26 +26,44 @@ RUN set -euxo pipefail \
   ; cd /var/www \
   ; curl -sL ${ROUNDCUBE_URL} | tar xz \
   ; curl -sL ${CARDDAV_URL} | tar xz \
-  ; mv roundcubemail-* webmail \
-  ; mkdir -p /var/www/webmail/config \
-  ; mv carddav webmail/plugins/ \
-  ; cd webmail \
+  ; mv roundcubemail-* roundcube \
+  ; mkdir -p /var/www/roundcube/config \
+  ; mv carddav roundcube/plugins/ \
+  ; cd roundcube \
   ; rm -rf CHANGELOG.md SECURITY.md INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \
-  ; ln -sf index.php /var/www/webmail/sso.php \
-  ; chmod -R u+w,a+rX /var/www/webmail \
-  ; chown -R nginx:nginx /var/www/webmail \
+  ; ln -sf index.php /var/www/roundcube/sso.php \
+  ; chmod -R u+w,a+rX /var/www/roundcube \
+  ; chown -R nginx:nginx /var/www/roundcube \
   ; rm -rf plugins/{autologon,example_addressbook,http_authentication,krb_authentication,new_user_identity,password,redundant_attachments,squirrelmail_usercopy,userinfo,virtuser_file,virtuser_query}
 
+COPY roundcube/config/config.inc.php /conf/
+COPY roundcube/login/mailu.php /var/www/roundcube/plugins/mailu/
+COPY roundcube/config/config.inc.carddav.php /var/www/roundcube/plugins/carddav/config.inc.php
 
-# nginx / PHP config files
-COPY config/nginx-roundcube.conf /conf/
-COPY config/php-roundcube.conf /etc/php81/php-fpm.d/roundcube.conf
-COPY config/php.ini /conf/
-COPY config/config.inc.php /conf/
-COPY login/mailu.php /var/www/webmail/plugins/mailu/
-COPY config/config.inc.carddav.php /var/www/webmail/plugins/carddav/config.inc.php
+# snappymail
 
+ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.21.0/snappymail-2.21.0.tar.gz
+
+RUN set -euxo pipefail \
+  ; mkdir  /var/www/snappymail \
+  ; cd /var/www/snappymail \
+  ; curl -sL  ${SNAPPYMAIL_URL} | tar xz \
+  ; chmod -R u+w,a+rX /var/www/snappymail \
+  ; chown -R nginx:nginx /var/www/snappymail
+
+# SnappyMail login
+COPY snappymail/login/include.php /var/www/snappymail/
+COPY snappymail/login/sso.php /var/www/snappymail/
+
+# Parsed and moved at startup
+COPY snappymail/defaults/application.ini /defaults/
+COPY snappymail/defaults/default.json /defaults/
+
+# common
 COPY start.py /
+COPY php.ini /defaults/
+COPY php-webmail.conf /etc/php81/php-fpm.d/php-webmail.conf
+COPY nginx-webmail.conf /conf/
 
 EXPOSE 80/tcp
 VOLUME /data
diff --git a/webmails/roundcube/config/nginx-roundcube.conf b/webmails/nginx-webmail.conf
similarity index 97%
rename from webmails/roundcube/config/nginx-roundcube.conf
rename to webmails/nginx-webmail.conf
index 80268340..5e5f8ec3 100644
--- a/webmails/roundcube/config/nginx-roundcube.conf
+++ b/webmails/nginx-webmail.conf
@@ -2,7 +2,7 @@ server {
     listen 80 default_server;
     listen [::]:80 default_server;
 
-    root /var/www/webmail;
+    root /var/www/{{ WEBMAIL }};
 
     include /etc/nginx/mime.types;
 
diff --git a/webmails/roundcube/config/php-roundcube.conf b/webmails/php-webmail.conf
similarity index 98%
rename from webmails/roundcube/config/php-roundcube.conf
rename to webmails/php-webmail.conf
index ac0c3375..47c1f6dd 100644
--- a/webmails/roundcube/config/php-roundcube.conf
+++ b/webmails/php-webmail.conf
@@ -1,7 +1,7 @@
-; Start a new pool named 'roundcube'.
+; Start a new pool named 'php'.
 ; the variable $pool can be used in any directive and will be replaced by the
-; pool name ('roundcube' here)
-[roundcube]
+; pool name ('php' here)
+[php]
 
 ; Redirect worker stdout and stderr into main error log. If not set, stdout and
 ; stderr will be redirected to /dev/null according to FastCGI specs.
diff --git a/webmails/roundcube/config/php.ini b/webmails/php.ini
similarity index 77%
rename from webmails/roundcube/config/php.ini
rename to webmails/php.ini
index 9f45dc80..af9ce8c5 100644
--- a/webmails/roundcube/config/php.ini
+++ b/webmails/php.ini
@@ -2,7 +2,7 @@ expose_php=Off
 date.timezone={{ TZ }}
 upload_max_filesize = {{ MAX_FILESIZE }}M
 post_max_size = {{ MAX_FILESIZE }}M
-suhosin.session.encrypt=Off
 session.auto_start=Off
 mbstring.func_overload=Off
 file_uploads=On
+error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile
deleted file mode 100644
index 3bc4ef53..00000000
--- a/webmails/snappymail/Dockerfile
+++ /dev/null
@@ -1,54 +0,0 @@
-# syntax=docker/dockerfile-upstream:1.4.3
-
-#snappymail image
-FROM base
-
-ARG VERSION
-LABEL version=$VERSION
-
-RUN set -euxo pipefail \
-  ; apk add --no-cache \
-    nginx curl \
-    php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml \
-    php81-dom php81-curl php81-exif gd php81-gd php81-iconv php81-intl php81-openssl \
-    php81-pdo_sqlite php81-pdo php81-sodium libsodium php81-tidy php81-pecl-uuid \
-  ; ln -s /usr/bin/php81 /usr/bin/php \
-  ; rm /etc/nginx/http.d/default.conf \
-  ; rm /etc/php81/php-fpm.d/www.conf \
-  ; mkdir -p /run/nginx \
-  ; mkdir -p /var/www/webmail \
-  ; mkdir -p /config
-
-# nginx / PHP config files
-COPY config/nginx-snappymail.conf /config/
-COPY config/php-snappymail.conf /etc/php81/php-fpm.d/snappymail.conf
-
-# Parsed and moved at startup
-COPY defaults/php.ini /defaults/
-COPY defaults/application.ini /defaults/
-COPY defaults/default.ini /defaults/
-
-# Install Snappymail from source
-ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.19.4/snappymail-2.19.4.tar.gz
-# Note. This is the last working snappymail version. 2.19.6 up to 2.20.6 do not work.
-
-RUN set -euxo pipefail \
-  ; cd /var/www/webmail \
-  ; curl -sL  ${SNAPPYMAIL_URL} | tar xz \
-  ; chmod -R u+w,a+rX /var/www/webmail \
-  ; chown -R nginx:nginx /var/www/webmail
-
-# SnappyMail login
-COPY login/include.php /var/www/webmail/
-COPY login/sso.php /var/www/webmail/
-
-COPY start.py /
-COPY config.py /
-
-EXPOSE 80/tcp
-VOLUME ["/data"]
-
-CMD /start.py
-
-HEALTHCHECK CMD curl -f -L http://localhost/ping || exit 1
-RUN echo $VERSION >> /version
diff --git a/webmails/snappymail/config.py b/webmails/snappymail/config.py
deleted file mode 100755
index f9fa363c..00000000
--- a/webmails/snappymail/config.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import logging as log
-import sys
-
-from socrate import system, conf
-
-args = os.environ.copy()
-
-log.basicConfig(stream=sys.stderr, level=args.get("LOG_LEVEL", "WARNING"))
-
-# Build final configuration paths
-conf.jinja("/config/nginx-snappymail.conf", args, "/etc/nginx/http.d/snappymail.conf")
-if os.path.exists("/var/run/nginx.pid"):
-    os.system("nginx -s reload")
diff --git a/webmails/snappymail/config/php-snappymail.conf b/webmails/snappymail/config/php-snappymail.conf
deleted file mode 100644
index 74b1889f..00000000
--- a/webmails/snappymail/config/php-snappymail.conf
+++ /dev/null
@@ -1,118 +0,0 @@
-; Start a new pool named 'snappymail'.
-; the variable $pool can be used in any directive and will be replaced by the
-; pool name ('snappymail' here)
-[snappymail]
-
-; Redirect worker stdout and stderr into main error log. If not set, stdout and
-; stderr will be redirected to /dev/null according to FastCGI specs.
-; Default value: no.
-catch_workers_output = 1
-
-; Unix user/group of processes
-; Note: The user is mandatory. If the group is not set, the default user's group
-;       will be used.
-user = nginx
-group = nginx
-
-; The address on which to accept FastCGI requests.
-; Valid syntaxes are:
-;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
-;                            a specific port;
-;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
-;                            a specific port;
-;   'port'                 - to listen on a TCP socket to all addresses
-;                            (IPv6 and IPv4-mapped) on a specific port;
-;   '/path/to/unix/socket' - to listen on a unix socket.
-; Note: This value is mandatory.
-listen = /var/run/php8-fpm.sock
-
-; Set permissions for unix socket, if one is used. In Linux, read/write
-; permissions must be set in order to allow connections from a web server. Many
-; BSD-derived systems allow connections regardless of permissions.
-; Default Values: user and group are set as the running user
-;                 mode is set to 0660
-listen.owner = nginx
-listen.group = nginx
-listen.mode = 0660
-
-; Choose how the process manager will control the number of child processes.
-; Possible Values:
-;   static  - a fixed number (pm.max_children) of child processes;
-;   dynamic - the number of child processes are set dynamically based on the
-;             following directives. With this process management, there will be
-;             always at least 1 children.
-;             pm.max_children      - the maximum number of children that can
-;                                    be alive at the same time.
-;             pm.start_servers     - the number of children created on startup.
-;             pm.min_spare_servers - the minimum number of children in 'idle'
-;                                    state (waiting to process). If the number
-;                                    of 'idle' processes is less than this
-;                                    number then some children will be created.
-;             pm.max_spare_servers - the maximum number of children in 'idle'
-;                                    state (waiting to process). If the number
-;                                    of 'idle' processes is greater than this
-;                                    number then some children will be killed.
-;  ondemand - no children are created at startup. Children will be forked when
-;             new requests will connect. The following parameter are used:
-;             pm.max_children           - the maximum number of children that
-;                                         can be alive at the same time.
-;             pm.process_idle_timeout   - The number of seconds after which
-;                                         an idle process will be killed.
-; Note: This value is mandatory.
-pm = ondemand
-
-; The number of child processes to be created when pm is set to 'static' and the
-; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
-; This value sets the limit on the number of simultaneous requests that will be
-; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
-; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
-; CGI. The below defaults are based on a server without much resources. Don't
-; forget to tweak pm.* to fit your needs.
-; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
-; Note: This value is mandatory.
-pm.max_children = 5
-
-; The number of child processes created on startup.
-; Note: Used only when pm is set to 'dynamic'
-; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
-; pm.start_servers = 2
-
-; The desired minimum number of idle server processes.
-; Note: Used only when pm is set to 'dynamic'
-; Note: Mandatory when pm is set to 'dynamic'
-; pm.min_spare_servers = 1
-
-; The desired maximum number of idle server processes.
-; Note: Used only when pm is set to 'dynamic'
-; Note: Mandatory when pm is set to 'dynamic'
-; pm.max_spare_servers = 3
-
-; This sets the maximum time in seconds a script is allowed to run before it is
-; terminated by the parser. This helps prevent poorly written scripts from tying up
-; the server. The default setting is 30s.
-; Note: Used only when pm is set to 'ondemand'
-pm.process_idle_timeout = 10s
-
-; The number of requests each child process should execute before respawning.
-; This can be useful to work around memory leaks in 3rd party libraries. For endless
-; request processing specify '0'.
-; Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0.
-; Noted: Used only when pm is set to 'ondemand'
-pm.max_requests = 200
-
-; The ping URI to call the monitoring page of FPM. If this value is not set, no
-; URI will be recognized as a ping page. This could be used to test from outside
-; that FPM is alive and responding, or to
-; - create a graph of FPM availability (rrd or such);
-; - remove a server from a group if it is not responding (load balancing);
-; - trigger alerts for the operating team (24/7).
-; Note: The value must start with a leading slash (/). The value can be
-;       anything, but it may not be a good idea to use the .php extension or it
-;       may conflict with a real PHP file.
-; Default Value: not set
-ping.path = /ping
-
-; This directive may be used to customize the response of a ping request. The
-; response is formatted as text/plain with a 200 response code.
-; Default Value: pong
-;ping.response = pong
diff --git a/webmails/snappymail/defaults/default.ini b/webmails/snappymail/defaults/default.ini
deleted file mode 100644
index be9a0969..00000000
--- a/webmails/snappymail/defaults/default.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-imap_host = "{{ FRONT_ADDRESS }}"
-imap_port = 10143
-imap_secure = "None"
-imap_short_login = Off
-sieve_use = On
-sieve_allow_raw = Off
-sieve_host = "{{ IMAP_ADDRESS }}"
-sieve_port = 4190
-sieve_secure = "None"
-smtp_host = "{{ FRONT_ADDRESS }}"
-smtp_port = 10025
-smtp_secure = "None"
-smtp_short_login = Off
-smtp_auth = On
-smtp_php_mail = Off
diff --git a/webmails/snappymail/defaults/default.json b/webmails/snappymail/defaults/default.json
new file mode 100644
index 00000000..ecbf116c
--- /dev/null
+++ b/webmails/snappymail/defaults/default.json
@@ -0,0 +1,50 @@
+{
+    "name": "*",
+    "IMAP": {
+        "host": "{{ FRONT_ADDRESS }}",
+        "port": 10143,
+        "secure": 0,
+        "shortLogin": false,
+        "ssl": {
+            "verify_peer": false,
+            "verify_peer_name": false,
+            "allow_self_signed": false,
+            "SNI_enabled": true,
+            "disable_compression": true,
+            "security_level": 1
+        }
+    },
+    "SMTP": {
+        "host": "{{ FRONT_ADDRESS }}",
+        "port": 10025,
+        "secure": 0,
+        "shortLogin": false,
+        "ssl": {
+            "verify_peer": false,
+            "verify_peer_name": false,
+            "allow_self_signed": false,
+            "SNI_enabled": true,
+            "disable_compression": true,
+            "security_level": 1
+        },
+        "useAuth": true,
+        "setSender": false,
+        "usePhpMail": false
+    },
+    "Sieve": {
+        "host": "{{ IMAP_ADDRESS }}",
+        "port": 4190,
+        "secure": 0,
+        "shortLogin": false,
+        "ssl": {
+            "verify_peer": false,
+            "verify_peer_name": false,
+            "allow_self_signed": false,
+            "SNI_enabled": true,
+            "disable_compression": true,
+            "security_level": 1
+        },
+        "enabled": true
+    },
+    "whiteList": ""
+}
diff --git a/webmails/snappymail/defaults/php.ini b/webmails/snappymail/defaults/php.ini
deleted file mode 100644
index d3d4d9f1..00000000
--- a/webmails/snappymail/defaults/php.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-expose_php=Off
-date.timezone={{ TZ }}
-upload_max_filesize = {{ MAX_FILESIZE }}M
-post_max_size = {{ MAX_FILESIZE }}M
-
diff --git a/webmails/snappymail/start.py b/webmails/snappymail/start.py
deleted file mode 100755
index 5307f23b..00000000
--- a/webmails/snappymail/start.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import shutil
-import logging as log
-import sys
-import subprocess
-
-from socrate import system, conf
-
-log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
-
-# Actual startup script
-os.environ["FRONT_ADDRESS"] = system.resolve_address(os.environ.get("HOST_FRONT", "front"))
-os.environ["IMAP_ADDRESS"] = system.resolve_address(os.environ.get("HOST_IMAP", "imap"))
-
-os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576))
-
-base = "/data/_data_/_default_/"
-shutil.rmtree(base + "domains/", ignore_errors=True)
-os.makedirs(base + "domains", exist_ok=True)
-os.makedirs(base + "configs", exist_ok=True)
-
-conf.jinja("/defaults/default.ini", os.environ, "/data/_data_/_default_/domains/default.ini")
-conf.jinja("/defaults/application.ini", os.environ, "/data/_data_/_default_/configs/application.ini")
-conf.jinja("/defaults/php.ini", os.environ, "/etc/php81/php.ini")
-# Start the fastcgi process manager now that config files have been adjusted
-os.system("php-fpm81")
-
-os.system("chown -R nginx:nginx /data")
-os.system("chmod -R a+rX /var/www/webmail/")
-
-subprocess.call(["/config.py"])
-os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"])
diff --git a/webmails/roundcube/start.py b/webmails/start.py
similarity index 71%
rename from webmails/roundcube/start.py
rename to webmails/start.py
index b5a4dca5..464d50e8 100755
--- a/webmails/roundcube/start.py
+++ b/webmails/start.py
@@ -4,9 +4,10 @@ import os
 import logging
 import sys
 import subprocess
+import shutil
 import hmac
 
-from socrate import conf
+from socrate import conf, system
 
 env = os.environ
 
@@ -17,6 +18,8 @@ context = {}
 context.update(env)
 
 context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))
+context["FRONT_ADDRESS"] = system.resolve_address(os.environ.get("HOST_FRONT", "front"))
+context["IMAP_ADDRESS"] = system.resolve_address(os.environ.get("HOST_IMAP", "imap"))
 
 db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
 if db_flavor == "sqlite":
@@ -52,7 +55,7 @@ context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUN
 
 # roundcube plugins
 # (using "dict" because it is ordered and "set" is not)
-plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/webmail/plugins", p)))
+plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/roundcube/plugins", p)))
 if plugins:
     plugins["mailu"] = None
 else:
@@ -67,15 +70,14 @@ context["INCLUDES"] = sorted(inc for inc in os.listdir("/overrides") if inc.ends
 context["SESSION_TIMEOUT_MINUTES"] = max(int(env.get("SESSION_TIMEOUT", "3600")) // 60, 1)
 
 # create config files
-conf.jinja("/conf/php.ini", context, "/etc/php81/php.ini")
-conf.jinja("/conf/config.inc.php", context, "/var/www/webmail/config/config.inc.php")
+conf.jinja("/conf/config.inc.php", context, "/var/www/roundcube/config/config.inc.php")
 
 # create dirs
 os.system("mkdir -p /data/gpg")
 
 print("Initializing database")
 try:
-    result = subprocess.check_output(["/var/www/webmail/bin/initdb.sh", "--dir", "/var/www/webmail/SQL"],
+    result = subprocess.check_output(["/var/www/roundcube/bin/initdb.sh", "--dir", "/var/www/roundcube/SQL"],
                                      stderr=subprocess.STDOUT)
     print(result.decode())
 except subprocess.CalledProcessError as exc:
@@ -88,22 +90,31 @@ except subprocess.CalledProcessError as exc:
 
 print("Upgrading database")
 try:
-    subprocess.check_call(["/var/www/webmail/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
+    subprocess.check_call(["/var/www/roundcube/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
 except subprocess.CalledProcessError as exc:
     exit(4)
 else:
     print("Cleaning database")
     try:
-        subprocess.check_call(["/var/www/webmail/bin/cleandb.sh"], stderr=subprocess.STDOUT)
+        subprocess.check_call(["/var/www/roundcube/bin/cleandb.sh"], stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as exc:
         exit(5)
 
+base = "/data/_data_/_default_/"
+shutil.rmtree(base + "domains/", ignore_errors=True)
+os.makedirs(base + "domains", exist_ok=True)
+os.makedirs(base + "configs", exist_ok=True)
+
+conf.jinja("/defaults/default.json", context, "/data/_data_/_default_/domains/default.json")
+conf.jinja("/defaults/application.ini", context, "/data/_data_/_default_/configs/application.ini")
+conf.jinja("/defaults/php.ini", context, "/etc/php81/php.ini")
+
 # setup permissions
-os.system("chown -R nginx:nginx /data")
-os.system("chmod -R a+rX /var/www/webmail/")
+os.system("chown -R nginx:nginx /data /var/www")
+os.system("chmod -R a+rX /var/www/")
 
 # Configure nginx
-conf.jinja("/conf/nginx-roundcube.conf", context, "/etc/nginx/http.d/roundcube.conf")
+conf.jinja("/conf/nginx-webmail.conf", context, "/etc/nginx/http.d/webmail.conf")
 if os.path.exists("/var/run/nginx.pid"):
     os.system("nginx -s reload")
 

From 1edef755f1a61312b2fee19fff0991e61f2798e3 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 11:40:23 +0100
Subject: [PATCH 02/27] Fix bug #2466

---
 webmails/Dockerfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index ccc2da0c..9a4f5c8e 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -12,6 +12,7 @@ RUN set -euxo pipefail \
     php81-dom php81-curl php81-exif gd php81-gd php81-iconv php81-intl php81-openssl \
     php81-pdo_sqlite php81-pdo_mysql php81-pdo_pgsql php81-pdo php81-sodium libsodium php81-tidy php81-pecl-uuid \
     php81-pspell php81-pecl-imagick php81-opcache php81-session php81-sockets php81-fileinfo \
+    aspell-uk aspell-ru aspell-fr aspell-de aspell-en \
   ; rm /etc/nginx/http.d/default.conf \
   ; rm /etc/php81/php-fpm.d/www.conf \
   ; ln -s /usr/bin/php81 /usr/bin/php \

From 13adf4aeec639cc9f9f4010c7aff79c273480fc4 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 11:46:59 +0100
Subject: [PATCH 03/27] Fix tests

---
 tests/compose/snappymail/docker-compose.yml   | 106 --------------
 tests/compose/snappymail/mailu.env            | 138 ------------------
 .../{roundcube => webmail}/docker-compose.yml |   0
 .../compose/{roundcube => webmail}/mailu.env  |   2 +-
 4 files changed, 1 insertion(+), 245 deletions(-)
 delete mode 100644 tests/compose/snappymail/docker-compose.yml
 delete mode 100644 tests/compose/snappymail/mailu.env
 rename tests/compose/{roundcube => webmail}/docker-compose.yml (100%)
 rename tests/compose/{roundcube => webmail}/mailu.env (99%)

diff --git a/tests/compose/snappymail/docker-compose.yml b/tests/compose/snappymail/docker-compose.yml
deleted file mode 100644
index b9df7332..00000000
--- a/tests/compose/snappymail/docker-compose.yml
+++ /dev/null
@@ -1,106 +0,0 @@
-# This file is auto-generated by the Mailu configuration wizard.
-# Please read the documentation before attempting any change.
-# Generated for compose flavor
-
-version: '3.6'
-
-services:
-
-  # External dependencies
-  redis:
-    image: redis:alpine
-    restart: always
-    volumes:
-      - "/mailu/redis:/data"
-
-  # Core services
-  front:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    logging:
-      driver: json-file
-    ports:
-      - "127.0.0.1:80:80"
-      - "127.0.0.1:443:443"
-      - "127.0.0.1:25:25"
-      - "127.0.0.1:465:465"
-      - "127.0.0.1:587:587"
-      - "127.0.0.1:110:110"
-      - "127.0.0.1:995:995"
-      - "127.0.0.1:143:143"
-      - "127.0.0.1:993:993"
-    volumes:
-      - "/mailu/certs:/certs"
-
-  admin:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    volumes:
-      - "/mailu/data:/data"
-      - "/mailu/dkim:/dkim"
-    depends_on:
-      - redis
-      - resolver
-    dns:
-      - 192.168.203.254
-
-  imap:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    volumes:
-      - "/mailu/mail:/mail"
-      - "/mailu/overrides:/overrides"
-    depends_on:
-      - front
-
-  smtp:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    volumes:
-      - "/mailu/overrides:/overrides"
-    depends_on:
-      - front
-
-  antispam:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    volumes:
-      - "/mailu/filter:/var/lib/rspamd"
-      - "/mailu/dkim:/dkim"
-      - "/mailu/overrides/rspamd:/etc/rspamd/override.d"
-    depends_on:
-      - front
-
-  # Optional services
-
-  resolver:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local}
-    env_file: mailu.env
-    restart: always
-    networks:
-      default:
-        ipv4_address: 192.168.203.254
-
-  # Webmail
-  webmail:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}snappymail:${MAILU_VERSION:-local}
-    restart: always
-    env_file: mailu.env
-    volumes:
-      - "/mailu/webmail:/data"
-    depends_on:
-      - imap
-
-
-networks:
-  default:
-    driver: bridge
-    ipam:
-      driver: default
-      config:
-        - subnet: 192.168.203.0/24
diff --git a/tests/compose/snappymail/mailu.env b/tests/compose/snappymail/mailu.env
deleted file mode 100644
index 50271fc7..00000000
--- a/tests/compose/snappymail/mailu.env
+++ /dev/null
@@ -1,138 +0,0 @@
-# Mailu main configuration file
-#
-# Generated for compose flavor
-#
-# This file is autogenerated by the configuration management wizard.
-# For a detailed list of configuration variables, see the documentation at
-# https://mailu.io
-
-###################################
-# Common configuration variables
-###################################
-
-# Set this to the path where Mailu data and configuration is stored
-# This variable is now set directly in `docker-compose.yml by the setup utility
-# ROOT=/mailu
-
-# Mailu version to run (1.0, 1.1, etc. or master)
-#VERSION=master
-
-# Set to a randomly generated 16 bytes string
-SECRET_KEY=V5J4SHRYVW9PZIQU
-
-# Address where listening ports should bind
-# This variables are now set directly in `docker-compose.yml by the setup utility
-# PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1)
-# PUBLIC_IPV6=  (default: ::1)
-
-# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!)
-SUBNET=192.168.203.0/24
-
-# Main mail domain
-DOMAIN=mailu.io
-
-# Hostnames for this server, separated with comas
-HOSTNAMES=localhost
-
-# Postmaster local part (will append the main mail domain)
-POSTMASTER=admin
-
-# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
-TLS_FLAVOR=cert
-
-# Authentication rate limit (per source IP address)
-AUTH_RATELIMIT=10/minute;1000/hour 
-
-# Opt-out of statistics, replace with "True" to opt out
-DISABLE_STATISTICS=False
-
-###################################
-# Optional features
-###################################
-
-# Expose the admin interface (value: true, false)
-ADMIN=false
-
-# Choose which webmail to run if any (values: roundcube, snappymail, none)
-WEBMAIL=snappymail
-
-# Dav server implementation (value: radicale, none)
-WEBDAV=none
-
-# Antivirus solution (value: clamav, none)
-#ANTIVIRUS=none
-
-#Antispam solution
-ANTISPAM=none
-
-###################################
-# Mail settings
-###################################
-
-# Message size limit in bytes
-# Default: accept messages up to 50MB
-MESSAGE_SIZE_LIMIT=50000000
-
-# Networks granted relay permissions
-# Use this with care, all hosts in this networks will be able to send mail without authentication!
-RELAYNETS=
-
-# Will relay all outgoing mails if configured
-RELAYHOST=
-
-# Fetchmail delay
-FETCHMAIL_DELAY=600
-
-# Recipient delimiter, character used to delimiter localpart from custom address part
-RECIPIENT_DELIMITER=+
-
-# DMARC rua and ruf email
-DMARC_RUA=admin
-DMARC_RUF=admin
-
-
-# Maildir Compression
-# choose compression-method, default: none (value: gz, bz2, lz4, zstd)
-COMPRESSION=
-# change compression-level, default: 6 (value: 1-9)
-COMPRESSION_LEVEL=
-
-###################################
-# Web settings
-###################################
-
-# Path to the admin interface if enabled
-WEB_ADMIN=/admin
-
-# Path to the webmail if enabled
-WEB_WEBMAIL=/webmail
-
-# Website name
-SITENAME=Mailu
-
-# Linked Website URL
-WEBSITE=https://mailu.io
-
-
-
-###################################
-# Advanced settings
-###################################
-
-# Log driver for front service. Possible values:
-# json-file (default)
-# journald (On systemd platforms, useful for Fail2Ban integration)
-# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker-compose log` for front!)
-# LOG_DRIVER=json-file
-
-# Docker-compose project name, this will prepended to containers names.
-COMPOSE_PROJECT_NAME=mailu
-
-# Header to take the real ip from
-REAL_IP_HEADER=
-
-# IPs for nginx set_real_ip_from (CIDR list separated by commas)
-REAL_IP_FROM=
-
-# choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no)
-REJECT_UNLISTED_RECIPIENT=
diff --git a/tests/compose/roundcube/docker-compose.yml b/tests/compose/webmail/docker-compose.yml
similarity index 100%
rename from tests/compose/roundcube/docker-compose.yml
rename to tests/compose/webmail/docker-compose.yml
diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/webmail/mailu.env
similarity index 99%
rename from tests/compose/roundcube/mailu.env
rename to tests/compose/webmail/mailu.env
index 7f000f2c..f87f3262 100644
--- a/tests/compose/roundcube/mailu.env
+++ b/tests/compose/webmail/mailu.env
@@ -54,7 +54,7 @@ DISABLE_STATISTICS=False
 ADMIN=false
 
 # Choose which webmail to run if any (values: roundcube, snappymail, none)
-WEBMAIL=roundcube
+WEBMAIL=snappymail
 
 # Dav server implementation (value: radicale, none)
 WEBDAV=none

From ae64c6cc306bad0344d7c0af8082ecd8c0ef135d Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 11:51:12 +0100
Subject: [PATCH 04/27] Doh

---
 tests/compose/webmail/docker-compose.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/compose/webmail/docker-compose.yml b/tests/compose/webmail/docker-compose.yml
index f2c43686..14d1dae9 100644
--- a/tests/compose/webmail/docker-compose.yml
+++ b/tests/compose/webmail/docker-compose.yml
@@ -88,7 +88,7 @@ services:
 
   # Webmail
   webmail:
-    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-local}
+    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-local}
     restart: always
     env_file: mailu.env
     volumes:

From a8d405cb487365ff50b1124eabed5e8308814ad3 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 12:25:03 +0100
Subject: [PATCH 05/27] Verify the gpg signature of webmails

---
 webmails/Dockerfile            |  15 ++++-
 webmails/roundcube/pubkey.asc  | 102 +++++++++++++++++++++++++++++++++
 webmails/snappymail/pubkey.asc |  11 ++++
 3 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 webmails/roundcube/pubkey.asc
 create mode 100644 webmails/snappymail/pubkey.asc

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 9a4f5c8e..b967af5a 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -5,6 +5,9 @@ FROM base
 ARG VERSION
 LABEL version=$VERSION
 
+COPY snappymail/pubkey.asc /tmp/snappymail.asc
+COPY roundcube/pubkey.asc /tmp/roundcube.asc
+
 RUN set -euxo pipefail \
   ; apk add --no-cache \
     nginx gpg gpg-agent \
@@ -16,6 +19,8 @@ RUN set -euxo pipefail \
   ; rm /etc/nginx/http.d/default.conf \
   ; rm /etc/php81/php-fpm.d/www.conf \
   ; ln -s /usr/bin/php81 /usr/bin/php \
+  ; gpg --import /tmp/snappymail.asc \
+  ; gpg --import /tmp/roundcube.asc \
   ; mkdir -p /run/nginx \
   ; mkdir -p /conf
 
@@ -25,7 +30,10 @@ ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.4
 
 RUN set -euxo pipefail \
   ; cd /var/www \
-  ; curl -sL ${ROUNDCUBE_URL} | tar xz \
+  ; curl -sLo /dev/shm/roundcube.tgz ${ROUNDCUBE_URL} \
+  ; curl -sLo /dev/shm/roundcube.tgz.asc ${ROUNDCUBE_URL}.asc \
+  ; gpg --status-fd 1 --verify /dev/shm/roundcube.tgz.asc \
+  ; tar xzf /dev/shm/roundcube.tgz \
   ; curl -sL ${CARDDAV_URL} | tar xz \
   ; mv roundcubemail-* roundcube \
   ; mkdir -p /var/www/roundcube/config \
@@ -48,7 +56,10 @@ ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2
 RUN set -euxo pipefail \
   ; mkdir  /var/www/snappymail \
   ; cd /var/www/snappymail \
-  ; curl -sL  ${SNAPPYMAIL_URL} | tar xz \
+  ; curl -sLo /dev/shm/snappymail.tgz  ${SNAPPYMAIL_URL} \
+  ; curl -sLo /dev/shm/snappymail.tgz.asc  ${SNAPPYMAIL_URL}.asc \
+  ; gpg --status-fd 1 --verify /dev/shm/snappymail.tgz.asc \
+  ; tar xzf /dev/shm/snappymail.tgz \
   ; chmod -R u+w,a+rX /var/www/snappymail \
   ; chown -R nginx:nginx /var/www/snappymail
 
diff --git a/webmails/roundcube/pubkey.asc b/webmails/roundcube/pubkey.asc
new file mode 100644
index 00000000..3d4449c9
--- /dev/null
+++ b/webmails/roundcube/pubkey.asc
@@ -0,0 +1,102 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+0dXJnhEe7eXkwBbfEzk=
+=lBKd
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/webmails/snappymail/pubkey.asc b/webmails/snappymail/pubkey.asc
new file mode 100644
index 00000000..9f295b79
--- /dev/null
+++ b/webmails/snappymail/pubkey.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: Hostname: 
+Version: Hockeypuck 2.1.0-184-g50f1108
+
+xjMEYg0atBYJKwYBBAHaRw8BAQdA2S2tvGavChACjtBastsKRThD3rsBW1LUZLmN
+Zbs4uaHNI1NuYXBweU1haWwgPHJlbGVhc2VzQHNuYXBweW1haWwuZXU+wpQEExYK
+ADwWIQQQFuRweRRVQvi6EzVIIIuhMpDz6wUCYg0atAIbAwULCQgHAgMiAgEGFQoJ
+CAsCBBYCAwECHgcCF4AACgkQSCCLoTKQ8+u9SAD/Q/IoAwjUkKDJBPq0RGwCFnl6
+FG/VHB97CvBSpGOxtIsBAMCwMhWlsaBHAEqbzxiN+cdlMYwV23+SWLUJ/XMFgukE
+=vC/h
+-----END PGP PUBLIC KEY BLOCK-----

From 224f2f45081313fd9c162969e33652dc4fc679e3 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 14:01:01 +0100
Subject: [PATCH 06/27] This isn't used anymore

The healthcheck is now done by fpm
---
 webmails/roundcube/login/mailu.php | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/webmails/roundcube/login/mailu.php b/webmails/roundcube/login/mailu.php
index 0596ca9d..25d95a10 100644
--- a/webmails/roundcube/login/mailu.php
+++ b/webmails/roundcube/login/mailu.php
@@ -18,13 +18,6 @@ class mailu extends rcube_plugin
       $args['action'] = 'login';
     }
 
-    $ua = $_SERVER['HTTP_USER_AGENT'];
-    $ra = $_SERVER['REMOTE_ADDR'];
-    if ($ua == 'health' and ($ra == '127.0.0.1' or $ra == '::1')) {
-      print('OK');
-      exit();
-    }
-
     return $args;
   }
 

From 7e722cd0c30325f603d228bba4903cedd4b46b1a Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 14:10:50 +0100
Subject: [PATCH 07/27] fix #2250: ensure rainloop uses _ADDRESS

---
 webmails/start.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/webmails/start.py b/webmails/start.py
index 464d50e8..c2bd87b7 100755
--- a/webmails/start.py
+++ b/webmails/start.py
@@ -18,8 +18,8 @@ context = {}
 context.update(env)
 
 context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))
-context["FRONT_ADDRESS"] = system.resolve_address(os.environ.get("HOST_FRONT", "front"))
-context["IMAP_ADDRESS"] = system.resolve_address(os.environ.get("HOST_IMAP", "imap"))
+context["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", "front")
+context["IMAP_ADDRESS"] = system.get_host_address_from_environment("IMAP", "imap")
 
 db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
 if db_flavor == "sqlite":

From 710dde1faf4846c5889fc77f4502c5d056b08678 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 14:27:32 +0100
Subject: [PATCH 08/27] Fix #948: ensure the admin panel is disabled

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 tests/compose/webmail/01_ensure_admin_unreachable.sh

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
new file mode 100644
index 00000000..c4afc76a
--- /dev/null
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/` -ne 200 ]] && echo "The default page of rainloop hasn't returned 200!" >>/dev/stderr && exit 1
+[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/?admin` -ne 403 ]] && echo "The admin of rainloop is not disabled!" >>/dev/stderr && exit 1

From 50f94a282f391ec0034085749fd8b8fe289cfc42 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 14:35:17 +0100
Subject: [PATCH 09/27] doh

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 tests/compose/webmail/01_ensure_admin_unreachable.sh

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
old mode 100644
new mode 100755

From 1379a583525351458d2675d3fc81840eec7f73fe Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 14:50:30 +0100
Subject: [PATCH 10/27] Basic hardening

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh |  6 +++---
 webmails/nginx-webmail.conf                          | 11 ++++++++++-
 webmails/php.ini                                     |  3 +++
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index c4afc76a..a3864b78 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
-[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/` -ne 200 ]] && echo "The default page of rainloop hasn't returned 200!" >>/dev/stderr && exit 1
-[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/?admin` -ne 403 ]] && echo "The admin of rainloop is not disabled!" >>/dev/stderr && exit 1
+[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/` -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
+[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/?admin` -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1
diff --git a/webmails/nginx-webmail.conf b/webmails/nginx-webmail.conf
index 5e5f8ec3..b1149c49 100644
--- a/webmails/nginx-webmail.conf
+++ b/webmails/nginx-webmail.conf
@@ -16,6 +16,11 @@ server {
 
     # set maximum body size to configured limit
     client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
+    fastcgi_hide_header X-Powered-By;
+    add_header X-Download-Options "noopen" always;
+    add_header X-Robots-Tag "none" always;
+    add_header X-Permitted-Cross-Domain-Policies "none" always;
+    add_header Referrer-Policy "no-referrer" always;
 
     location / {
         try_files $uri $uri/ /index.php$args;
@@ -42,10 +47,14 @@ server {
         {% endif %}
     }
 
-    location ~ /\. {
+    location ~ (^|/)\. {
         deny all;
     }
 
+    location ~* ^/(config|temp|logs) {
+       deny all;
+    }
+
     location ^~ /data {
        deny all;
     }
diff --git a/webmails/php.ini b/webmails/php.ini
index af9ce8c5..884dda72 100644
--- a/webmails/php.ini
+++ b/webmails/php.ini
@@ -6,3 +6,6 @@ session.auto_start=Off
 mbstring.func_overload=Off
 file_uploads=On
 error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
+display_errors=Off
+log_errors=On
+zlib.output_compression=Off

From 729838c8fe2a6ddf5515dac7c0cf7a8b35a14633 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:12:22 +0100
Subject: [PATCH 11/27] Grrr.

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index a3864b78..3351b85b 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -1,4 +1,6 @@
 #!/bin/bash
 
-[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/` -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
-[[ `curl -I -so /dev/null -w "%{http_code}" http://localhost/?admin` -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1
+IP="$(docker inspect webmail_webmail_1|jq '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
+
+[[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/) -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
+[[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1

From 6d8cc9083bbc44a84e8412c61cf539b6ce356f4e Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:21:04 +0100
Subject: [PATCH 12/27] test

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index 3351b85b..ff0e9f25 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -2,5 +2,8 @@
 
 IP="$(docker inspect webmail_webmail_1|jq '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
 
+echo "webmail is on $IP"
+wget -S http://$IP/ &>/dev/stderr
+
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/) -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1

From 4517ce23a6510e47b84ea3da33636fdd58ff9f81 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:28:01 +0100
Subject: [PATCH 13/27] Aliases be damned.

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index ff0e9f25..76e45179 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -1,9 +1,6 @@
 #!/bin/bash
 
-IP="$(docker inspect webmail_webmail_1|jq '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
-
-echo "webmail is on $IP"
-wget -S http://$IP/ &>/dev/stderr
+IP="$(docker inspect webmail_webmail_1|jq -r '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
 
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/) -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1

From ad17b10c8e208338c2001b86d7604b8c8a883b89 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:31:47 +0100
Subject: [PATCH 14/27] redirects should be HTTP/302

---
 webmails/roundcube/login/mailu.php | 8 ++++----
 webmails/snappymail/login/sso.php  | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/webmails/roundcube/login/mailu.php b/webmails/roundcube/login/mailu.php
index 25d95a10..86de6562 100644
--- a/webmails/roundcube/login/mailu.php
+++ b/webmails/roundcube/login/mailu.php
@@ -28,7 +28,7 @@ class mailu extends rcube_plugin
         header('HTTP/1.0 403 Forbidden');
         print('mailu sso failure');
       } else {
-        header('Location: sso.php');
+        header('Location: sso.php', 302);
       }
       exit();
     }
@@ -47,19 +47,19 @@ class mailu extends rcube_plugin
   {
     $this->load_config();
     $sso_logout_url = rcmail::get_instance()->config->get('sso_logout_url');
-    header('Location: ' . $sso_logout_url, true);
+    header('Location: ' . $sso_logout_url, true, 302);
     exit();
   }
 
   function login($args)
   {
-    header('Location: index.php');
+    header('Location: index.php', 302);
     exit();
   }
 
   function login_failed($args)
   {
-    header('Location: sso.php');
+    header('Location: sso.php', 302);
     exit();
   }
 
diff --git a/webmails/snappymail/login/sso.php b/webmails/snappymail/login/sso.php
index e3d04824..254bb151 100644
--- a/webmails/snappymail/login/sso.php
+++ b/webmails/snappymail/login/sso.php
@@ -9,9 +9,9 @@ if (isset($_SERVER['HTTP_X_REMOTE_USER']) && isset($_SERVER['HTTP_X_REMOTE_USER_
 	$ssoHash = \RainLoop\Api::CreateUserSsoHash($email, $password);
 
 	// redirect to webmail sso url
-	header('Location: index.php?sso&hash='.$ssoHash);
+	header('Location: index.php?sso&hash='.$ssoHash, 302);
 }
 else {
-	header('HTTP/1.0 403 Forbidden');
+	header('HTTP/1.0 403 Forbidden', 403);
 }
-?>
\ No newline at end of file
+?>

From 225322fe88673d4aeb3baddb66c360772b937483 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:34:43 +0100
Subject: [PATCH 15/27] More hardening

---
 webmails/Dockerfile         | 2 +-
 webmails/nginx-webmail.conf | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index b967af5a..8fd6f9f8 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -40,7 +40,7 @@ RUN set -euxo pipefail \
   ; mv carddav roundcube/plugins/ \
   ; cd roundcube \
   ; rm -rf CHANGELOG.md SECURITY.md INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \
-  ; ln -sf index.php /var/www/roundcube/sso.php \
+  ; ln -sf index.php /var/www/roundcube/public_html/sso.php \
   ; chmod -R u+w,a+rX /var/www/roundcube \
   ; chown -R nginx:nginx /var/www/roundcube \
   ; rm -rf plugins/{autologon,example_addressbook,http_authentication,krb_authentication,new_user_identity,password,redundant_attachments,squirrelmail_usercopy,userinfo,virtuser_file,virtuser_query}
diff --git a/webmails/nginx-webmail.conf b/webmails/nginx-webmail.conf
index b1149c49..37672ab1 100644
--- a/webmails/nginx-webmail.conf
+++ b/webmails/nginx-webmail.conf
@@ -2,7 +2,11 @@ server {
     listen 80 default_server;
     listen [::]:80 default_server;
 
+{% if WEBMAIL == 'roundcube' %}
+    root /var/www/{{ WEBMAIL }}/public_html;
+{% else %}
     root /var/www/{{ WEBMAIL }};
+{% endif %}
 
     include /etc/nginx/mime.types;
 

From b488e576024eaf84f709a050e00081b1b8cda0c8 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 15:39:11 +0100
Subject: [PATCH 16/27] debug

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index 76e45179..8f9667aa 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -2,5 +2,9 @@
 
 IP="$(docker inspect webmail_webmail_1|jq -r '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
 
+echo "webmail is on $IP" >/dev/stderr
+wget -S -O - "http://$IP/" &>/dev/stderr
+docker inspect webmail_webmail_1 &>/dev/stderr
+
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/) -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1

From f3a91d1a180413e2e472bc0a1041ce86a5ad0b68 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 16:00:55 +0100
Subject: [PATCH 17/27] enable APCu

---
 webmails/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 8fd6f9f8..fed0f464 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -11,7 +11,7 @@ COPY roundcube/pubkey.asc /tmp/roundcube.asc
 RUN set -euxo pipefail \
   ; apk add --no-cache \
     nginx gpg gpg-agent \
-    php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml \
+    php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml php81-pecl-apc \
     php81-dom php81-curl php81-exif gd php81-gd php81-iconv php81-intl php81-openssl \
     php81-pdo_sqlite php81-pdo_mysql php81-pdo_pgsql php81-pdo php81-sodium libsodium php81-tidy php81-pecl-uuid \
     php81-pspell php81-pecl-imagick php81-opcache php81-session php81-sockets php81-fileinfo \

From 7ebac75045e091a6bfac3cffefe16e6ce14f8965 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 16:07:08 +0100
Subject: [PATCH 18/27] fix tests

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 7 ++-----
 webmails/Dockerfile                                  | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index 8f9667aa..7a3df370 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -2,9 +2,6 @@
 
 IP="$(docker inspect webmail_webmail_1|jq -r '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
 
-echo "webmail is on $IP" >/dev/stderr
-wget -S -O - "http://$IP/" &>/dev/stderr
-docker inspect webmail_webmail_1 &>/dev/stderr
-
-[[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/) -ne 200 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
+MAIN_RETURN_CODE=$(curl -I -so /dev/null -w "%{http_code}" http://$IP/)
+[[ $MAIN_RETURN_CODE -ne 200 ]] && [[ $MAIN_RETURN_CODE -ne 302 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1
diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index fed0f464..90d56ad5 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -11,7 +11,7 @@ COPY roundcube/pubkey.asc /tmp/roundcube.asc
 RUN set -euxo pipefail \
   ; apk add --no-cache \
     nginx gpg gpg-agent \
-    php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml php81-pecl-apc \
+    php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml php81-pecl-apcu \
     php81-dom php81-curl php81-exif gd php81-gd php81-iconv php81-intl php81-openssl \
     php81-pdo_sqlite php81-pdo_mysql php81-pdo_pgsql php81-pdo php81-sodium libsodium php81-tidy php81-pecl-uuid \
     php81-pspell php81-pecl-imagick php81-opcache php81-session php81-sockets php81-fileinfo \

From d7b80e94a422145a1ae3238d748694c6db2b29b4 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sat, 12 Nov 2022 16:21:28 +0100
Subject: [PATCH 19/27] try again.

---
 tests/compose/webmail/01_ensure_admin_unreachable.sh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/compose/webmail/01_ensure_admin_unreachable.sh b/tests/compose/webmail/01_ensure_admin_unreachable.sh
index 7a3df370..4fd78a1b 100755
--- a/tests/compose/webmail/01_ensure_admin_unreachable.sh
+++ b/tests/compose/webmail/01_ensure_admin_unreachable.sh
@@ -3,5 +3,8 @@
 IP="$(docker inspect webmail_webmail_1|jq -r '.[0].NetworkSettings.Networks.webmail_default.IPAddress')"
 
 MAIN_RETURN_CODE=$(curl -I -so /dev/null -w "%{http_code}" http://$IP/)
-[[ $MAIN_RETURN_CODE -ne 200 ]] && [[ $MAIN_RETURN_CODE -ne 302 ]] && echo "The default page of snappymail hasn't returned 200!" >>/dev/stderr && exit 1
+[[ $MAIN_RETURN_CODE -ne 200 && $MAIN_RETURN_CODE -ne 302 ]] && echo "The default page of snappymail hasn't returned 200 but $MAIN_RETURN_CODE!" >>/dev/stderr && exit 1
 [[ $(curl -I -so /dev/null -w "%{http_code}" http://$IP/?admin) -ne 403 ]] && echo "The admin of snappymail is not disabled!" >>/dev/stderr && exit 1
+echo "Everything OK" >/dev/stderr
+
+exit 0

From 06c0c78956efd18f4cb68724a12b5ae841afb84a Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 13:44:35 +0100
Subject: [PATCH 20/27] Hardening: run the http and php as different users

---
 webmails/Dockerfile       | 9 +++++----
 webmails/php-webmail.conf | 4 ++--
 webmails/start.py         | 3 +--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 90d56ad5..34085f4f 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -41,8 +41,9 @@ RUN set -euxo pipefail \
   ; cd roundcube \
   ; rm -rf CHANGELOG.md SECURITY.md INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \
   ; ln -sf index.php /var/www/roundcube/public_html/sso.php \
-  ; chmod -R u+w,a+rX /var/www/roundcube \
-  ; chown -R nginx:nginx /var/www/roundcube \
+  ; chown -R root:root /var/www/roundcube/ \
+  ; chown -R mailu:mailu /var/www/roundcube/temp /var/www/roundcube/logs \
+  ; chmod -R a+rX /var/www/roundcube \
   ; rm -rf plugins/{autologon,example_addressbook,http_authentication,krb_authentication,new_user_identity,password,redundant_attachments,squirrelmail_usercopy,userinfo,virtuser_file,virtuser_query}
 
 COPY roundcube/config/config.inc.php /conf/
@@ -60,8 +61,8 @@ RUN set -euxo pipefail \
   ; curl -sLo /dev/shm/snappymail.tgz.asc  ${SNAPPYMAIL_URL}.asc \
   ; gpg --status-fd 1 --verify /dev/shm/snappymail.tgz.asc \
   ; tar xzf /dev/shm/snappymail.tgz \
-  ; chmod -R u+w,a+rX /var/www/snappymail \
-  ; chown -R nginx:nginx /var/www/snappymail
+  ; chmod -R a+rX /var/www/snappymail \
+  ; chown -R root:root /var/www/snappymail
 
 # SnappyMail login
 COPY snappymail/login/include.php /var/www/snappymail/
diff --git a/webmails/php-webmail.conf b/webmails/php-webmail.conf
index 47c1f6dd..18a1f66e 100644
--- a/webmails/php-webmail.conf
+++ b/webmails/php-webmail.conf
@@ -11,8 +11,8 @@ catch_workers_output = 1
 ; Unix user/group of processes
 ; Note: The user is mandatory. If the group is not set, the default user's group
 ;       will be used.
-user = nginx
-group = nginx
+user = mailu
+group = mailu
 
 ; The address on which to accept FastCGI requests.
 ; Valid syntaxes are:
diff --git a/webmails/start.py b/webmails/start.py
index c2bd87b7..06b90351 100755
--- a/webmails/start.py
+++ b/webmails/start.py
@@ -110,8 +110,7 @@ conf.jinja("/defaults/application.ini", context, "/data/_data_/_default_/configs
 conf.jinja("/defaults/php.ini", context, "/etc/php81/php.ini")
 
 # setup permissions
-os.system("chown -R nginx:nginx /data /var/www")
-os.system("chmod -R a+rX /var/www/")
+os.system("chown -R mailu:mailu /data")
 
 # Configure nginx
 conf.jinja("/conf/nginx-webmail.conf", context, "/etc/nginx/http.d/webmail.conf")

From f2f430af5dbfbd22986226be3a0ba9bcf0cb7492 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 14:07:40 +0100
Subject: [PATCH 21/27] Redirect the logs where they belong

---
 webmails/Dockerfile | 16 ++++++++++------
 webmails/php.ini    |  4 +++-
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 34085f4f..376399bf 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -41,9 +41,6 @@ RUN set -euxo pipefail \
   ; cd roundcube \
   ; rm -rf CHANGELOG.md SECURITY.md INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \
   ; ln -sf index.php /var/www/roundcube/public_html/sso.php \
-  ; chown -R root:root /var/www/roundcube/ \
-  ; chown -R mailu:mailu /var/www/roundcube/temp /var/www/roundcube/logs \
-  ; chmod -R a+rX /var/www/roundcube \
   ; rm -rf plugins/{autologon,example_addressbook,http_authentication,krb_authentication,new_user_identity,password,redundant_attachments,squirrelmail_usercopy,userinfo,virtuser_file,virtuser_query}
 
 COPY roundcube/config/config.inc.php /conf/
@@ -60,9 +57,7 @@ RUN set -euxo pipefail \
   ; curl -sLo /dev/shm/snappymail.tgz  ${SNAPPYMAIL_URL} \
   ; curl -sLo /dev/shm/snappymail.tgz.asc  ${SNAPPYMAIL_URL}.asc \
   ; gpg --status-fd 1 --verify /dev/shm/snappymail.tgz.asc \
-  ; tar xzf /dev/shm/snappymail.tgz \
-  ; chmod -R a+rX /var/www/snappymail \
-  ; chown -R root:root /var/www/snappymail
+  ; tar xzf /dev/shm/snappymail.tgz
 
 # SnappyMail login
 COPY snappymail/login/include.php /var/www/snappymail/
@@ -72,6 +67,15 @@ COPY snappymail/login/sso.php /var/www/snappymail/
 COPY snappymail/defaults/application.ini /defaults/
 COPY snappymail/defaults/default.json /defaults/
 
+# set perms
+RUN set -euxo pipefail \
+  ; chmod -R a+rX /var/www/snappymail \
+  ; chown -R root:root /var/www/snappymail \
+  ; chown -R mailu:mailu /var/www/snappymail/data \
+  ; chown -R root:root /var/www/roundcube/ \
+  ; chown -R mailu:mailu /var/www/roundcube/temp /var/www/roundcube/logs \
+  ; chmod -R a+rX /var/www/roundcube
+
 # common
 COPY start.py /
 COPY php.ini /defaults/
diff --git a/webmails/php.ini b/webmails/php.ini
index 884dda72..d9ba892c 100644
--- a/webmails/php.ini
+++ b/webmails/php.ini
@@ -5,7 +5,9 @@ post_max_size = {{ MAX_FILESIZE }}M
 session.auto_start=Off
 mbstring.func_overload=Off
 file_uploads=On
-error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
+error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE
 display_errors=Off
 log_errors=On
 zlib.output_compression=Off
+access.log = /dev/fd/2
+error_log = /dev/fd/2

From a508eeaafba574aa8b3b53c8c1b49557b11917fa Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 14:16:44 +0100
Subject: [PATCH 22/27] Use /dev/shm for tmp

---
 webmails/roundcube/config/config.inc.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/webmails/roundcube/config/config.inc.php b/webmails/roundcube/config/config.inc.php
index d5213b32..6e5ea0bd 100644
--- a/webmails/roundcube/config/config.inc.php
+++ b/webmails/roundcube/config/config.inc.php
@@ -4,7 +4,7 @@ $config = array();
 
 // Generals
 $config['db_dsnw'] = '{{ DB_DSNW }}';
-$config['temp_dir'] = '/tmp/';
+$config['temp_dir'] = '/dev/shm/';
 $config['des_key'] = '{{ SECRET_KEY }}';
 $config['cipher_method'] = 'AES-256-CBC';
 $config['identities_level'] = 0;

From 6b2cb95a7d75f905e282ae490bf41a5b350db885 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 14:17:37 +0100
Subject: [PATCH 23/27] This is not required anymore

---
 .../snappymail/config/nginx-snappymail.conf   | 63 -------------------
 1 file changed, 63 deletions(-)
 delete mode 100644 webmails/snappymail/config/nginx-snappymail.conf

diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf
deleted file mode 100644
index 80268340..00000000
--- a/webmails/snappymail/config/nginx-snappymail.conf
+++ /dev/null
@@ -1,63 +0,0 @@
-server {
-    listen 80 default_server;
-    listen [::]:80 default_server;
-
-    root /var/www/webmail;
-
-    include /etc/nginx/mime.types;
-
-    # /dev/stdout (Default), <path>, off
-    access_log off;
-
-    # /dev/stderr (Default), <path>, debug, info, notice, warn, error, crit, alert, emerg
-    error_log /dev/stderr notice;
-
-    index index.php;
-
-    # set maximum body size to configured limit
-    client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
-
-    location / {
-        try_files $uri $uri/ /index.php$args;
-    }
-
-    location ~ \.php$ {
-        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
-        if (!-f $document_root$fastcgi_script_name) {
-            return 404;
-        }
-        include /etc/nginx/fastcgi_params;
-
-        fastcgi_intercept_errors on;
-        fastcgi_index  index.php;
-
-        fastcgi_keep_conn on;
-
-        fastcgi_pass unix:/var/run/php8-fpm.sock;
-        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-        {% if WEB_WEBMAIL == '/' %}
-        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
-        {% else %}
-        fastcgi_param SCRIPT_NAME {{WEB_WEBMAIL}}/$fastcgi_script_name;
-        {% endif %}
-    }
-
-    location ~ /\. {
-        deny all;
-    }
-
-    location ^~ /data {
-       deny all;
-    }
-
-    location = /ping {
-        allow 127.0.0.1;
-        allow ::1;
-        deny all;
-
-        include /etc/nginx/fastcgi_params;
-        fastcgi_index index.php;
-        fastcgi_pass unix:/var/run/php8-fpm.sock;
-        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-    }
-}

From 071ad15a97df5135b8edddec05d26a69ac6dc90b Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 14:34:25 +0100
Subject: [PATCH 24/27] Better snappymail defaults

---
 webmails/nginx-webmail.conf                  |  6 +-----
 webmails/snappymail/defaults/application.ini | 11 +++++++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/webmails/nginx-webmail.conf b/webmails/nginx-webmail.conf
index 37672ab1..1794a635 100644
--- a/webmails/nginx-webmail.conf
+++ b/webmails/nginx-webmail.conf
@@ -55,11 +55,7 @@ server {
         deny all;
     }
 
-    location ~* ^/(config|temp|logs) {
-       deny all;
-    }
-
-    location ^~ /data {
+    location ~* /(config|temp|logs|data) {
        deny all;
     }
 
diff --git a/webmails/snappymail/defaults/application.ini b/webmails/snappymail/defaults/application.ini
index 71a19f35..85c8c7c6 100644
--- a/webmails/snappymail/defaults/application.ini
+++ b/webmails/snappymail/defaults/application.ini
@@ -5,6 +5,7 @@ attachment_size_limit = {{ MAX_FILESIZE }}
 
 [security]
 allow_admin_panel = Off
+openpgp = On
 
 [labs]
 allow_gravatar = Off
@@ -21,3 +22,13 @@ allow_sync = On
 
 [defaults]
 contacts_autosave = On
+
+[cache]
+fast_cache_driver = "APCU"
+
+[imap]
+use_move = On
+
+[labs]
+image_exif_auto_rotate = On
+try_to_detect_hidden_images = On

From 56a106ad608948f3c4b0faee73c0f35845eeeda9 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Sun, 13 Nov 2022 15:25:46 +0100
Subject: [PATCH 25/27] Only one labs section in the conf file

---
 webmails/snappymail/defaults/application.ini | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/webmails/snappymail/defaults/application.ini b/webmails/snappymail/defaults/application.ini
index 85c8c7c6..bcf544c5 100644
--- a/webmails/snappymail/defaults/application.ini
+++ b/webmails/snappymail/defaults/application.ini
@@ -9,12 +9,10 @@ openpgp = On
 
 [labs]
 allow_gravatar = Off
-{% if WEB_WEBMAIL == '/' %}
-custom_login_link='sso.php'
-{% else %}
-custom_login_link='{{ WEB_WEBMAIL }}/sso.php'
-{% endif %}
-custom_logout_link='/sso/logout'
+image_exif_auto_rotate = On
+try_to_detect_hidden_images = On
+{% if WEB_WEBMAIL == '/' %}custom_login_link = "sso.php"{% else %}custom_login_link = "{{ WEB_WEBMAIL }}/sso.php"{% endif %}
+custom_logout_link = "/sso/logout"
 
 [contacts]
 enable = On
@@ -24,11 +22,8 @@ allow_sync = On
 contacts_autosave = On
 
 [cache]
+enable = On
 fast_cache_driver = "APCU"
 
 [imap]
 use_move = On
-
-[labs]
-image_exif_auto_rotate = On
-try_to_detect_hidden_images = On

From 28d720bbc978fbcbd7b8654c0d2b13f04480f173 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Mon, 21 Nov 2022 14:54:36 +0100
Subject: [PATCH 26/27] As requested

---
 webmails/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 376399bf..72c2ee18 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -79,7 +79,7 @@ RUN set -euxo pipefail \
 # common
 COPY start.py /
 COPY php.ini /defaults/
-COPY php-webmail.conf /etc/php81/php-fpm.d/php-webmail.conf
+COPY php-webmail.conf /etc/php81/php-fpm.d/
 COPY nginx-webmail.conf /conf/
 
 EXPOSE 80/tcp

From ab852772f91cdcf0ec1617cea8ea2659fdecb8a4 Mon Sep 17 00:00:00 2001
From: Florent Daigniere <nextgens@freenetproject.org>
Date: Mon, 21 Nov 2022 16:04:00 +0100
Subject: [PATCH 27/27] Bump snappymail to 2.21.3

---
 webmails/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/webmails/Dockerfile b/webmails/Dockerfile
index 72c2ee18..5d0bc23b 100644
--- a/webmails/Dockerfile
+++ b/webmails/Dockerfile
@@ -49,7 +49,7 @@ COPY roundcube/config/config.inc.carddav.php /var/www/roundcube/plugins/carddav/
 
 # snappymail
 
-ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.21.0/snappymail-2.21.0.tar.gz
+ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.21.3/snappymail-2.21.3.tar.gz
 
 RUN set -euxo pipefail \
   ; mkdir  /var/www/snappymail \