Browse Source

Merge pull request #6758 from mailcow/feat/sogo-url-encryption

[SOGo][Web] SOGo URL Encryption support
FreddleSpl0it 1 month ago
parent
commit
78168ee80a

+ 6 - 5
_modules/scripts/new_options.sh

@@ -43,6 +43,7 @@ adapt_new_options() {
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "ALLOW_ADMIN_EMAIL_LOGIN"
   "SKIP_HTTP_VERIFICATION"
   "SKIP_HTTP_VERIFICATION"
   "SOGO_EXPIRE_SESSION"
   "SOGO_EXPIRE_SESSION"
+  "SOGO_URL_ENCRYPTION_KEY"
   "REDIS_PORT"
   "REDIS_PORT"
   "REDISPASS"
   "REDISPASS"
   "DOVECOT_MASTER_USER"
   "DOVECOT_MASTER_USER"
@@ -94,7 +95,6 @@ adapt_new_options() {
             echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
             echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
             echo "LOG_LINES=9999" >> mailcow.conf
             echo "LOG_LINES=9999" >> mailcow.conf
             ;;
             ;;
-        
         IPV4_NETWORK)
         IPV4_NETWORK)
             echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf
             echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf
             echo "IPV4_NETWORK=172.22.1" >> mailcow.conf
             echo "IPV4_NETWORK=172.22.1" >> mailcow.conf
@@ -276,21 +276,22 @@ adapt_new_options() {
             echo '# A COMPLETE DOCKER STACK REBUILD (compose down && compose up -d) IS NEEDED TO APPLY THIS.' >> mailcow.conf
             echo '# A COMPLETE DOCKER STACK REBUILD (compose down && compose up -d) IS NEEDED TO APPLY THIS.' >> mailcow.conf
             echo ENABLE_IPV6=${IPV6_BOOL} >> mailcow.conf
             echo ENABLE_IPV6=${IPV6_BOOL} >> mailcow.conf
             ;;
             ;;
-    
         SKIP_CLAMD)
         SKIP_CLAMD)
             echo '# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n' >> mailcow.conf
             echo '# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n' >> mailcow.conf
             echo 'SKIP_CLAMD=n' >> mailcow.conf
             echo 'SKIP_CLAMD=n' >> mailcow.conf
             ;;
             ;;
-
         SKIP_OLEFY)
         SKIP_OLEFY)
             echo '# Skip Olefy (olefy-mailcow) anti-virus for Office documents (Rspamd will auto-detect a missing Olefy container) - y/n' >> mailcow.conf
             echo '# Skip Olefy (olefy-mailcow) anti-virus for Office documents (Rspamd will auto-detect a missing Olefy container) - y/n' >> mailcow.conf
             echo 'SKIP_OLEFY=n' >> mailcow.conf
             echo 'SKIP_OLEFY=n' >> mailcow.conf
             ;;
             ;;
-        
         REDISPASS)
         REDISPASS)
             echo "REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 28)" >> mailcow.conf
             echo "REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 28)" >> mailcow.conf
             ;;
             ;;
-                  
+        SOGO_URL_ENCRYPTION_KEY)
+            echo '# SOGo URL encryption key (exactly 16 characters, limited to A–Z, a–z, 0–9)' >> mailcow.conf
+            echo '# This key is used to encrypt email addresses within SOGo URLs' >> mailcow.conf
+            echo "SOGO_URL_ENCRYPTION_KEY=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 16)" >> mailcow.conf
+            ;;
         *)
         *)
             echo "${option}=" >> mailcow.conf
             echo "${option}=" >> mailcow.conf
             ;;
             ;;

+ 4 - 0
data/Dockerfiles/sogo/bootstrap-sogo.sh

@@ -50,6 +50,10 @@ cat <<EOF > /var/lib/sogo/GNUstep/Defaults/sogod.plist
     <string>YES</string>
     <string>YES</string>
     <key>SOGoEncryptionKey</key>
     <key>SOGoEncryptionKey</key>
     <string>${RAND_PASS}</string>
     <string>${RAND_PASS}</string>
+    <key>SOGoURLEncryptionEnabled</key>
+    <string>YES</string>
+    <key>SOGoURLEncryptionPassphrase</key>
+    <string>${SOGO_URL_ENCRYPTION_KEY}</string>
     <key>OCSAdminURL</key>
     <key>OCSAdminURL</key>
     <string>mysql://${DBUSER}:${DBPASS}@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/${DBNAME}/sogo_admin</string>
     <string>mysql://${DBUSER}:${DBPASS}@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/${DBNAME}/sogo_admin</string>
     <key>OCSCacheFolderURL</key>
     <key>OCSCacheFolderURL</key>

+ 2 - 2
data/web/inc/triggers.user.inc.php

@@ -80,7 +80,7 @@ if (isset($_POST["verify_tfa_login"])) {
             intval($user_details['attributes']['force_pw_update']) != 1 &&
             intval($user_details['attributes']['force_pw_update']) != 1 &&
             getenv('SKIP_SOGO') != "y" &&
             getenv('SKIP_SOGO') != "y" &&
             !$is_dual) {
             !$is_dual) {
-          header("Location: /SOGo/so/{$_SESSION['mailcow_cc_username']}");
+          header("Location: /SOGo/so/");
           die();
           die();
         } else {
         } else {
           header("Location: /user");
           header("Location: /user");
@@ -146,7 +146,7 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
         intval($user_details['attributes']['force_pw_update']) != 1 &&
         intval($user_details['attributes']['force_pw_update']) != 1 &&
         getenv('SKIP_SOGO') != "y" &&
         getenv('SKIP_SOGO') != "y" &&
         !$is_dual) {
         !$is_dual) {
-      header("Location: /SOGo/so/{$login_user}");
+      header("Location: /SOGo/so/");
       die();
       die();
     } else {
     } else {
       header("Location: /user");
       header("Location: /user");

+ 1 - 4
data/web/sogo-auth.php

@@ -64,7 +64,7 @@ elseif (isset($_GET['login'])) {
           ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'])
           ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'])
         ));
         ));
         // redirect to sogo (sogo will get the correct credentials via nginx auth_request
         // redirect to sogo (sogo will get the correct credentials via nginx auth_request
-        header("Location: /SOGo/so/{$login}");
+        header("Location: /SOGo/so/");
         exit;
         exit;
       }
       }
     }
     }
@@ -81,10 +81,7 @@ elseif (isset($_SERVER['HTTP_X_ORIGINAL_URI']) && strcasecmp(substr($_SERVER['HT
   }
   }
   require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/sessions.inc.php';
   require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/sessions.inc.php';
 
 
-  // extract email address from "/SOGo/so/user@domain/xy"
-  $url_parts = explode("/", $_SERVER['HTTP_X_ORIGINAL_URI']);
   $email_list = array(
   $email_list = array(
-      $url_parts[3],                                // Requested mailbox
       ($_SESSION['mailcow_cc_username'] ?? ''),     // Current user
       ($_SESSION['mailcow_cc_username'] ?? ''),     // Current user
       ($_SESSION["dual-login"]["username"] ?? ''),  // Dual login user
       ($_SESSION["dual-login"]["username"] ?? ''),  // Dual login user
   );
   );

+ 2 - 1
docker-compose.yml

@@ -200,7 +200,7 @@ services:
             - phpfpm
             - phpfpm
 
 
     sogo-mailcow:
     sogo-mailcow:
-      image: ghcr.io/mailcow/sogo:1.135
+      image: ghcr.io/mailcow/sogo:1.136
       environment:
       environment:
         - DBNAME=${DBNAME}
         - DBNAME=${DBNAME}
         - DBUSER=${DBUSER}
         - DBUSER=${DBUSER}
@@ -213,6 +213,7 @@ services:
         - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
         - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
         - SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
         - SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
+        - SOGO_URL_ENCRYPTION_KEY=${SOGO_URL_ENCRYPTION_KEY:-SOGoSuperSecret0}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - SKIP_SOGO=${SKIP_SOGO:-n}
         - MASTER=${MASTER:-y}
         - MASTER=${MASTER:-y}
         - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
         - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}

+ 4 - 0
generate_config.sh

@@ -436,6 +436,10 @@ MAILDIR_SUB=Maildir
 # SOGo session timeout in minutes
 # SOGo session timeout in minutes
 SOGO_EXPIRE_SESSION=480
 SOGO_EXPIRE_SESSION=480
 
 
+# SOGo URL encryption key (exactly 16 characters, limited to A–Z, a–z, 0–9)
+# This key is used to encrypt email addresses within SOGo URLs
+SOGO_URL_ENCRYPTION_KEY=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 16)
+
 # DOVECOT_MASTER_USER and DOVECOT_MASTER_PASS must both be provided. No special chars.
 # DOVECOT_MASTER_USER and DOVECOT_MASTER_PASS must both be provided. No special chars.
 # Empty by default to auto-generate master user and password on start.
 # Empty by default to auto-generate master user and password on start.
 # User expands to DOVECOT_MASTER_USER@mailcow.local
 # User expands to DOVECOT_MASTER_USER@mailcow.local