Control Web Panel
WebPanel => Updates => Topic started by: cyberspace on June 19, 2025, 10:39:18 AM
-
A new security vulnerability was found in Roundcube:
https://nvd.nist.gov/vuln/detail/CVE-2025-49113
The effected versions:
all versions before 1.5.10
all 1.6.x versions before 1.6.11
The most recent versions of Roundcube include the patch:
https://roundcube.net/news/2025/06/01/security-updates-1.6.11-and-1.5.10
CWP uses Roundcube 1.4.x therefore it is highly recommended to update Roundcube
Instructions how to update Roundcube to 1.5.11:
cd /usr/local/cwpsrv/var/services
cp -R roundcube roundcube_backup
wget https://github.com/roundcube/roundcubemail/releases/download/1.5.11/roundcubemail-1.5.11-complete.tar.gz
tar -xvzf roundcubemail-1.5.11-complete.tar.gz
cd roundcubemail-1.5.11
bin/installto.sh /usr/local/cwpsrv/var/services/roundcube
cd ..
chown -R cwpsvc:cwpsvc roundcube
rm -rf roundcubemail-1.5.11*
Please note you do it on your own risk.
-
Yes, saw that a couple of weeks ago. Other updating directions are here, just update the version number from 1.5.8 to 1.5.11 (LTS version):
https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/#comment-35 (https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/#comment-35)
-
Yes, saw that a couple of weeks ago. Other updating directions are here, just update the version number from 1.5.8 to 1.5.11 (LTS version):
https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/#comment-35 (https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/#comment-35)
Worked perfectly on AL 8.10 installation
Used the "Centos 8 stream/EL8" instructions
-
A new security vulnerability was found in Roundcube:
https://nvd.nist.gov/vuln/detail/CVE-2025-49113
The effected versions:
all versions before 1.5.10
all 1.6.x versions before 1.6.11
The most recent versions of Roundcube include the patch:
https://roundcube.net/news/2025/06/01/security-updates-1.6.11-and-1.5.10
CWP uses Roundcube 1.4.x therefore it is highly recommended to update Roundcube
Instructions how to update Roundcube to 1.5.11:
cd /usr/local/cwpsrv/var/services
cp -R roundcube roundcube_backup
wget https://github.com/roundcube/roundcubemail/releases/download/1.5.11/roundcubemail-1.5.11-complete.tar.gz
tar -xvzf roundcubemail-1.5.11-complete.tar.gz
cd roundcubemail-1.5.11
bin/installto.sh /usr/local/cwpsrv/var/services/roundcube
cd ..
chown -R cwpsvc:cwpsvc roundcube
rm -rf roundcubemail-1.5.11*
Please note you do it on your own risk.
Got server error in roundcube after following the instructions. Maybe some step is missing.
-
What error did you get ?
-
There are several steps missing @anandmys
I'll create a new KB article, the one we have online is for 1.5.9
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-mail-version-1-5-9-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-mail-version-1-5-9-in-cwp-on-almalinux-8-9/)
-
Here is the updated guide to update Roundcube to version 1.5.11:
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/)
-
Hi,
For CentOS Stream 8 what is the correct way to update?
Thanks,
Geo
-
Follow the steps for EL8 distributions here:
https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/ (https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/)
-
There are several steps missing @anandmys
I'll create a new KB article, the one we have online is for 1.5.9
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-mail-version-1-5-9-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-mail-version-1-5-9-in-cwp-on-almalinux-8-9/)
I still get Server error! (Internal Server Error)
-
Here is the updated guide to update Roundcube to version 1.5.11:
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/)
Works like a charm buddy :D alm 9
-
Here is the updated guide to update Roundcube to version 1.5.11:
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/)
Worked with Rocky 8
-
Hi,
For CentOS Stream 8 what is the correct way to update?
Thanks,
Geo
Alpha OS'es aren't recommended for Production use.
You should switch over to AlmaLinux 8.
-
Do you have to upgrade your cwp php version?
-
You shouldn't have to.
-
Just to affirm Starburst's previous guide to update Roundcube in light of the current vulnerability:
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-11-in-cwp-on-almalinux-8-9/
or follow Sandeep's guide here:
https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/
Simply update the Roundcube version number to 1.5.13 in the directions and download links and you will obtain a CWP-compatible LTS version of Roundcube, safe from the latest CVE.
-
Have an updated guide for 1.5.13:
https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-13-in-cwp-on-almalinux-8-9/ (https://starburst.help/control-web-panel-cwp/control-web-panel-cwp-admin-tutorials/update-roundcube-webmail-to-version-1-5-13-in-cwp-on-almalinux-8-9/)
-
Hi guys,
I've developed a script to update Roundcube for CWP to the latest LTS version.
What does the script do ?
1. I parses the page:
https://roundcube.net/download/
to identify the latest LTS version of Roundcub and URL to .tag.gz file.
2. Compares the versions (installed and available at the website)
3. If the installed version is older than available then:
3a. Makes backup of the currently installed Roundcube
3b. Downloads the .tar.gz file from the website
3c. Checks the checksum to make sure the downloaded file isn't corrupted
3d. Updates Roundcube
3e. Sends a notification to the user (address is specified in the script)
If the versions are the same or installed version is never then just sends an simple notification like "no update needed".
#!/usr/bin/env bash
####################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2026 BeinHost.com #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
####################################################################################
########################################
# CONFIG
########################################
BASE_DIR="/usr/local/cwpsrv/var/services"
INSTALL_DIR="$BASE_DIR/roundcube"
PAGE_URL="https://roundcube.net/download/"
OWNER="cwpsvc:cwpsvc"
EMAIL="support@beinhost.com"
SUBJECT_PREFIX="[Roundcube Updater]"
cd "$BASE_DIR"
########################################
# Send notofication
########################################
send_email() {
local subject="$1"
local body="$2"
# use mail command
echo -e "$body" | mail -s "$SUBJECT_PREFIX $subject" "$EMAIL"
}
########################################
# Detect installed version
########################################
INI_FILE="$INSTALL_DIR/program/include/iniset.php"
if [[ ! -f "$INI_FILE" ]]; then
echo "Cannot detect installed version (iniset.php missing)."
exit 2
fi
installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/")
installed_version=$(echo "$installed_version" | tr -d '\r\n[:space:]')
echo "Installed version: $installed_version"
########################################
# Detect latest LTS version + checksum
########################################
lts_block=$(curl -fsSL "$PAGE_URL" \
| awk '/<h2 id="lts">/,/<\/table>/')
download_url=$(echo "$lts_block" \
| grep -oE 'https://[^"]+-complete\.tar\.gz' \
| head -n1)
latest_version=$(echo "$download_url" \
| sed -E 's/.*roundcubemail-([0-9]+\.[0-9]+\.[0-9]+)-complete\.tar\.gz/\1/')
latest_version=$(echo "$latest_version" | tr -d '\r\n[:space:]')
sha256_expected=$(echo "$lts_block" \
| grep -oE '[a-f0-9]{64}' \
| head -n1)
if [[ -z "$download_url" || -z "$latest_version" || -z "$sha256_expected" ]]; then
echo "Failed to detect latest LTS release."
send_email "Update failed" "Server: `hostname`\nFailed to detect latest LTS release.\nTime: $(date)"
exit 3
fi
########################################
# Compare versions
########################################
version_gt() {
[ "$1" = "$2" ] && return 1
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do ver2[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
if ((10#${ver1[i]} > 10#${ver2[i]})); then return 0; fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then return 1; fi
done
return 1
}
#echo "Installed: [$installed_version]"
#echo "Latest: [$latest_version]"
if version_gt "$latest_version" "$installed_version"; then
echo "Update available."
send_email "Update successful" "Server: `hostname`\nStatus: Roundcube updated successfully!\nPrevious version: $installed_version\nNew version: $latest_version\nBackup directory: $backup_dir\nTime: $(date)"
elif version_gt "$installed_version" "$latest_version"; then
echo "Installed version is newer than LTS."
send_email "Installed version newer than LTS" "Server: `hostname`\nStatus: Installed Roundcube version ($installed_version) is newer than latest LTS ($latest_version).\nNo update performed.\nTime: $(date)"
else
echo "Latest LTS version:" "$latest_version"
echo "Already up to date."
send_email "No update needed" "Server: `hostname`\nStatus: Roundcube is already up to date.\nInstalled version: $installed_version\nLatest LTS: $latest_version\nTime: $(date)"
exit 0
fi
########################################
# Backup current installation
########################################
backup_dir="roundcube_backup_v${installed_version}_$(date +%F_%H%M%S)"
echo "Creating backup: $backup_dir"
cp -a roundcube "$backup_dir"
########################################
# Download release
########################################
filename=$(basename "$download_url")
echo "Downloading $filename"
curl -fL -o "$filename" "$download_url"
########################################
# Verify SHA256
########################################
echo "Verifying checksum..."
sha256_actual=$(sha256sum "$filename" | awk '{print $1}')
if [[ "$sha256_actual" != "$sha256_expected" ]]; then
echo "Checksum verification FAILED!"
rm -f "$filename"
send_email "Server: `hostname`\nUpdate FAILED" "Status: Roundcube update failed!\nInstalled version: $installed_version\nLatest version: $latest_version\nBackup: $backup_dir\nReason: SHA256 mismatch or extraction failure\nTime: $(date)"
exit 4
fi
echo "Checksum OK."
########################################
# Extract + Install
########################################
echo "Extracting..."
tar -xzf "$filename"
src_dir="roundcubemail-$latest_version"
if [[ ! -d "$src_dir" ]]; then
echo "Extraction failed. Directory $src_dir not found."
exit 5
fi
echo "Running install script..."
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
########################################
# Fix permissions
########################################
chown -R "$OWNER" roundcube
########################################
# Cleanup
########################################
rm -rf "$src_dir" "$filename"
echo "Update completed successfully!"
echo "Now running version: $latest_version"
send_email "Update successful.\nStatus: Roundcube updated: $installed_version -> $latest_version\nBackup: $backup_dir"
I tested the script some time and it worked fine for me. However, please note, you use the script on your own risk (MIT License) )
-
Thanks for that! I've added it into my daily cron routines.
One thing I do is add an authentication hook at the beginning of privileged scripts, in case it is run interactively:
# Authentication
sudo -p "Please authenticate (admin password): " printf "" || {
echo "Abort: could not authenticate" >&2
exit 1
}And then close out the script with
sudo -kto remove cached credentials.
-
I just set the permissions on the script like:
chown admin:admin /script/update_roundcube.sh # replace "admin:admin" with your admin username and group.
chmod 700 /script/update_roundcube.sh
so no one except "admin" would be allowed to run the script.
I should probably have written these instructions in my previous message.
-
Update to the script listed here:
http://forum.centos-webpanel.com/updates/roundcube-vulnerability/msg53064/#msg53064
Changelog:
Added the option to enable/disable email notifications
ENABLE_NOTIFICATIONS=true # true/false to enable/disable notificationsThanks @overseer for the idea
#!/usr/bin/env bash
####################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2026 BeinHost.com #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
####################################################################################
########################################
# CONFIG
########################################
BASE_DIR="/usr/local/cwpsrv/var/services"
INSTALL_DIR="$BASE_DIR/roundcube"
PAGE_URL="https://roundcube.net/download/"
OWNER="cwpsvc:cwpsvc"
EMAIL="address@domain.com" # set your email address here
ENABLE_NOTIFICATIONS=true # true/false to enable/disable notifications
SUBJECT_PREFIX="[Roundcube Updater]"
cd "$BASE_DIR"
########################################
# Send notofication
########################################
send_email() {
if [ "$ENABLE_NOTIFICATIONS" = true ]; then
local subject="$1"
local body="$2"
# use mail command
echo -e "$body" | mail -s "$SUBJECT_PREFIX $subject" "$EMAIL"
fi
}
########################################
# Detect installed version
########################################
INI_FILE="$INSTALL_DIR/program/include/iniset.php"
if [[ ! -f "$INI_FILE" ]]; then
echo "Cannot detect installed version (iniset.php missing)."
exit 2
fi
installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/")
installed_version=$(echo "$installed_version" | tr -d '\r\n[:space:]')
echo "Installed version: $installed_version"
########################################
# Detect latest LTS version + checksum
########################################
lts_block=$(curl -fsSL "$PAGE_URL" \
| awk '/<h2 id="lts">/,/<\/table>/')
download_url=$(echo "$lts_block" \
| grep -oE 'https://[^"]+-complete\.tar\.gz' \
| head -n1)
latest_version=$(echo "$download_url" \
| sed -E 's/.*roundcubemail-([0-9]+\.[0-9]+\.[0-9]+)-complete\.tar\.gz/\1/')
latest_version=$(echo "$latest_version" | tr -d '\r\n[:space:]')
sha256_expected=$(echo "$lts_block" \
| grep -oE '[a-f0-9]{64}' \
| head -n1)
if [[ -z "$download_url" || -z "$latest_version" || -z "$sha256_expected" ]]; then
echo "Failed to detect latest LTS release."
send_email "Update failed" "Server: `hostname`\nFailed to detect latest LTS release.\nTime: $(date)"
exit 3
fi
########################################
# Compare versions
########################################
version_gt() {
[ "$1" = "$2" ] && return 1
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do ver2[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
if ((10#${ver1[i]} > 10#${ver2[i]})); then return 0; fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then return 1; fi
done
return 1
}
#echo "Installed: [$installed_version]"
#echo "Latest: [$latest_version]"
if version_gt "$latest_version" "$installed_version"; then
echo "Update available."
send_email "Update successful" "Server: `hostname`\nStatus: Roundcube updated successfully!\nPrevious version: $installed_version\nNew version: $latest_version\nBackup directory: $backup_dir\nTime: $(date)"
elif version_gt "$installed_version" "$latest_version"; then
echo "Installed version is newer than LTS."
send_email "Installed version newer than LTS" "Server: `hostname`\nStatus: Installed Roundcube version ($installed_version) is newer than latest LTS ($latest_version).\nNo update performed.\nTime: $(date)"
else
echo "Latest LTS version:" "$latest_version"
echo "Already up to date."
send_email "No update needed" "Server: `hostname`\nStatus: Roundcube is already up to date.\nInstalled version: $installed_version\nLatest LTS: $latest_version\nTime: $(date)"
exit 0
fi
########################################
# Backup current installation
########################################
backup_dir="roundcube_backup_v${installed_version}_$(date +%F_%H%M%S)"
echo "Creating backup: $backup_dir"
cp -a roundcube "$backup_dir"
########################################
# Download release
########################################
filename=$(basename "$download_url")
echo "Downloading $filename"
curl -fL -o "$filename" "$download_url"
########################################
# Verify SHA256
########################################
echo "Verifying checksum..."
sha256_actual=$(sha256sum "$filename" | awk '{print $1}')
if [[ "$sha256_actual" != "$sha256_expected" ]]; then
echo "Checksum verification FAILED!"
rm -f "$filename"
send_email "Server: `hostname`\nUpdate FAILED" "Status: Roundcube update failed!\nInstalled version: $installed_version\nLatest version: $latest_version\nBackup: $backup_dir\nReason: SHA256 mismatch or extraction failure\nTime: $(date)"
exit 4
fi
echo "Checksum OK."
########################################
# Extract + Install
########################################
echo "Extracting..."
tar -xzf "$filename"
src_dir="roundcubemail-$latest_version"
if [[ ! -d "$src_dir" ]]; then
echo "Extraction failed. Directory $src_dir not found."
exit 5
fi
echo "Running install script..."
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
########################################
# Fix permissions
########################################
chown -R "$OWNER" roundcube
########################################
# Cleanup
########################################
rm -rf "$src_dir" "$filename"
echo "Update completed successfully!"
echo "Now running version: $latest_version"
send_email "Update successful.\nStatus: Roundcube updated: $installed_version -> $latest_version\nBackup: $backup_dir"
-
Thanks a lot for sharing the script. Very useful. However I've tried to enhance it. You can use this one, a more robust version attached here:
#!/usr/bin/env bash
####################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2026 BeinHost.com #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
####################################################################################
set -euo pipefail
IFS=$'\n\t'
########################################
# CONFIG
########################################
BASE_DIR="/usr/local/cwpsrv/var/services"
INSTALL_DIR="$BASE_DIR/roundcube"
PAGE_URL="https://roundcube.net/download/"
OWNER="cwpsvc:cwpsvc"
EMAIL="mail@domain.com" # set your email address here
ENABLE_NOTIFICATIONS=true # true/false to enable/disable notifications
SUBJECT_PREFIX="[Roundcube Updater]"
RC_VERSION="lts" # select between "lts" or "stable"
CONNECT_TIMEOUT=10
MAX_TIMEOUT=30
cd "$BASE_DIR" || exit 1
########################################
# INITIAL CHECKS
########################################
required_cmds=(
curl
sha256sum
tar
mail
yes
awk
grep
sed
)
for cmd in "${required_cmds[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Required command not found: $cmd"
exit 10
fi
done
exec 9>/var/lock/roundcube_updater.lock
flock -n 9 || { echo "Another update process is running."; exit 20; }
trap 'send_email "Update FAILED (unexpected)" "Server: $(hostname)\nAn unexpected error occurred.\nTime: $(date)"' ERR
########################################
# Send notification
########################################
send_email() {
if [ "$ENABLE_NOTIFICATIONS" = true ]; then
local subject="$1"
local body="$2"
# use mail command
echo -e "$body" | mail -s "$SUBJECT_PREFIX $subject" "$EMAIL"
fi
}
########################################
# Detect installed version
########################################
INI_FILE="$INSTALL_DIR/program/include/iniset.php"
if [[ ! -f "$INI_FILE" ]]; then
echo "Cannot detect installed version (iniset.php missing)."
exit 2
fi
installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/")
installed_version=$(echo "$installed_version" | tr -d '\r\n[:space:]')
echo "Installed version: $installed_version"
########################################
# Detect latest version + checksum
########################################
echo "Fetching releases information..."
if ! page_content=$(curl -fsSL --connect-timeout $CONNECT_TIMEOUT --max-time $MAX_TIMEOUT "$PAGE_URL"); then
echo "Failed to fetch download page."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Failed to retrieve Roundcube download page.\nURL: $PAGE_URL\nTime: $(date)"
exit 30
fi
block_id="$RC_VERSION"
version_block=$(echo "$page_content" | awk "/<h2 id=\"$block_id\">/,/<\/table>/")
if [[ -z "$version_block" ]]; then
echo "Failed to parse the releases block."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Could not parse the release section from download page.\nURL: $PAGE_URL\nTime: $(date)"
exit 31
fi
download_url=$(echo "$version_block" \
| grep -oE 'https://[^"]+-complete\.tar\.gz' \
| head -n1)
latest_version=$(echo "$download_url" \
| sed -E 's/.*roundcubemail-([0-9]+\.[0-9]+\.[0-9]+)-complete\.tar\.gz/\1/')
latest_version=$(echo "$latest_version" | tr -d '\r\n[:space:]')
sha256_expected=$(echo "$version_block" \
| grep -oE '[a-f0-9]{64}' \
| head -n1)
if [[ -z "$download_url" || -z "$latest_version" || -z "$sha256_expected" ]]; then
echo "Failed to detect the latest release."
send_email "Update failed" "Server: $(hostname)\nFailed to detect the latest release.\nTime: $(date)"
exit 3
fi
########################################
# Compare versions
########################################
version_gt() {
[ "$1" = "$2" ] && return 1
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do ver2[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
if ((10#${ver1[i]} > 10#${ver2[i]})); then return 0; fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then return 1; fi
done
return 1
}
#echo "Installed: [$installed_version]"
#echo "Latest: [$latest_version]"
if version_gt "$latest_version" "$installed_version"; then
echo "Update available."
elif version_gt "$installed_version" "$latest_version"; then
echo "Installed version is newer than latest available."
send_email "Installed version newer than available" "Server: $(hostname)\nStatus: Installed Roundcube version ($installed_version) is newer than latest LTS ($latest_version).\nNo update performed.\nTime: $(date)"
exit 0
else
echo "Latest version:" "$latest_version"
echo "Already up to date."
send_email "No update needed" "Server: $(hostname)\nStatus: Roundcube is already up to date.\nInstalled version: $installed_version\nLatest available: $latest_version\nTime: $(date)"
exit 0
fi
########################################
# Confirmation only if not in CRON mode
########################################
if [ -t 0 ]; then
read -rp "Do you want to download and install the new Roundcube release $latest_version? [y/N]: " yn
case "$yn" in
[Yy]*) ;;
*) echo "Update cancelled by user."; exit 0 ;;
esac
fi
########################################
# Backup current installation
########################################
backup_dir="roundcube_backup_v${installed_version}_$(date +%F_%H%M%S)"
echo "Creating backup: $backup_dir"
cp -a "$INSTALL_DIR" "$backup_dir"
########################################
# Download release
########################################
filename=$(basename "$download_url")
echo "Downloading $filename"
if ! curl -fL --connect-timeout $CONNECT_TIMEOUT --max-time $MAX_TIMEOUT -o "$filename" "$download_url"; then
echo "Failed to download latest release."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Failed to download the latest release package.\nURL: $PAGE_URL\nTime: $(date)"
exit 30
fi
########################################
# Verify SHA256
########################################
echo "Verifying checksum..."
sha256_actual=$(sha256sum "$filename" | awk '{print $1}')
if [[ "$sha256_actual" != "$sha256_expected" ]]; then
echo "Checksum verification FAILED!"
rm -f "$filename"
send_email "Update FAILED" "Server: $(hostname)\nStatus: Roundcube update failed!\nInstalled version: $installed_version\nLatest version: $latest_version\nBackup: $backup_dir\nReason: SHA256 mismatch or extraction failure\nTime: $(date)"
exit 4
fi
echo "Checksum OK."
########################################
# Extract + Install
########################################
echo "Extracting..."
if ! tar -xzf "$filename"; then
echo "Extraction failed."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Extraction failed.\nVersion: $latest_version\nBackup: $backup_dir\nTime: $(date)"
exit 14
fi
src_dir="roundcubemail-$latest_version"
if [[ ! -d "$src_dir" ]]; then
echo "Extraction failed. Directory $src_dir not found."
exit 5
fi
echo "Running install script..."
if ! yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"; then
echo "Install failed"
send_email "Update FAILED" "Server: $(hostname)\nStatus: Installation script failed.\nRollback performed.\nTime: $(date)"
[[ -d "${INSTALL_DIR}_failed" ]] && mv "${INSTALL_DIR}_failed" "${INSTALL_DIR}_failed_$(date +%s)"
if ! mv "$INSTALL_DIR" "${INSTALL_DIR}_failed"; then
echo "Rollback failed (step 1)"
exit 7
fi
if ! mv "$backup_dir" "$INSTALL_DIR"; then
echo "Rollback failed (step 2)"
exit 8
fi
exit 6
fi
########################################
# Post-install verification
########################################
echo "Verifying installed version..."
if ! new_installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/"); then
echo "Failed to detect installed version after update."
exit 13
fi
new_installed_version=$(echo "$new_installed_version" | tr -d '\r\n[:space:]')
if [[ "$new_installed_version" != "$latest_version" ]]; then
echo "Post-install verification FAILED!"
echo "Expected: $latest_version"
echo "Detected: $new_installed_version"
[[ -d "${INSTALL_DIR}_failed" ]] && mv "${INSTALL_DIR}_failed" "${INSTALL_DIR}_failed_$(date +%s)"
if ! mv "$INSTALL_DIR" "${INSTALL_DIR}_failed"; then
echo "Rollback failed (post-check step 1)"
exit 11
fi
if ! mv "$backup_dir" "$INSTALL_DIR"; then
echo "Rollback failed (post-check step 2)"
exit 12
fi
send_email "Update FAILED" "Server: $(hostname)
Status: Roundcube update failed during post-install verification.
Expected version: $latest_version
Detected version: $new_installed_version
Rollback performed.
Time: $(date)"
exit 9
fi
echo "Post-install verification OK."
########################################
# Fix permissions
########################################
chown -R "$OWNER" "$INSTALL_DIR"
########################################
# Cleanup
########################################
rm -rf "$src_dir" "$filename"
echo "Update completed successfully!"
echo "Now running version: $latest_version"
send_email "Update successful" "Server: $(hostname)\nStatus: Roundcube updated successfully!\nPrevious version: $installed_version\nNew version: $latest_version\nBackup directory: $backup_dir\nTime: $(date)"
I hope it helps. Cheers! :)
-
Hi again. I've fixed and tweaked some issues. Now it works fine. However, due to CWP limited to PHP 7.4 (!!!!) Roundcube can't be updated beyond 1.6.11 so be careful if you select "stable" and not "lts" into the script settings:
#!/usr/bin/env bash
####################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2026 BeinHost.com #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
####################################################################################
set -euo pipefail
IFS=$'\n\t'
########################################
# CONFIG
########################################
BASE_DIR="/usr/local/cwpsrv/var/services"
INSTALL_DIR="$BASE_DIR/roundcube"
PAGE_URL="https://roundcube.net/download/"
OWNER="cwpsvc:cwpsvc"
EMAIL="mail@domain.com" # set your email address here
ENABLE_NOTIFICATIONS=true # true/false to enable/disable notifications
SUBJECT_PREFIX="[Roundcube Updater]"
RC_VERSION="lts" # select between "lts" or "stable" or "beta"
CONNECT_TIMEOUT=10
MAX_TIMEOUT=30
cd "$BASE_DIR" || exit 1
########################################
# INITIAL CHECKS
########################################
required_cmds=(
curl
sha256sum
tar
mail
yes
awk
grep
sed
)
for cmd in "${required_cmds[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Required command not found: $cmd"
exit 10
fi
done
exec 9>/var/lock/roundcube_updater.lock
flock -n 9 || { echo "Another update process is running."; exit 20; }
trap 'send_email "Update FAILED (unexpected)" "Server: $(hostname)\nAn unexpected error occurred.\nTime: $(date)"' ERR
########################################
# Send notification
########################################
send_email() {
if [ "$ENABLE_NOTIFICATIONS" = true ]; then
local subject="$1"
local body="$2"
# use mail command
echo -e "$body" | mail -s "$SUBJECT_PREFIX $subject" "$EMAIL"
fi
}
########################################
# Detect installed version
########################################
INI_FILE="$INSTALL_DIR/program/include/iniset.php"
if [[ ! -f "$INI_FILE" ]]; then
echo "Cannot detect installed version (iniset.php missing)."
exit 2
fi
installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/")
installed_version=$(echo "$installed_version" | tr -d '\r\n[:space:]')
echo "Installed version: $installed_version"
########################################
# Detect latest version + checksum
########################################
echo "Fetching releases information..."
if ! page_content=$(curl -fsSL --connect-timeout $CONNECT_TIMEOUT --max-time $MAX_TIMEOUT "$PAGE_URL"); then
echo "Failed to fetch download page."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Failed to retrieve Roundcube download page.\nURL: $PAGE_URL\nTime: $(date)"
exit 30
fi
block_id="$RC_VERSION"
version_block=$(echo "$page_content" | awk "/<h2 id=\"$block_id\">/,/<\/table>/")
if [[ -z "$version_block" ]]; then
echo "Failed to parse the releases block."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Could not parse the release section from download page.\nURL: $PAGE_URL\nTime: $(date)"
exit 31
fi
row_complete=$(echo "$version_block" | awk '
BEGIN {RS="</tr>"; FS="\n"}
/roundcubemail-[0-9]+\.[0-9]+\.[0-9]+-complete\.tar\.gz/ {print $0 "</tr>"}' || true)
if [[ -z "$row_complete" ]]; then
echo "Failed to find the complete release row."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Could not find the complete release row for $RC_VERSION.\nTime: $(date)"
exit 32
fi
download_url=$(echo "$row_complete" | grep -oE 'https://[^"]+-complete\.tar\.gz' | head -n1 || true)
latest_version=$(echo "$download_url" | sed -E 's/.*roundcubemail-([0-9]+\.[0-9]+\.[0-9]+)-complete\.tar\.gz/\1/' | tr -d '\r\n[:space:]' || true)
sha256_expected=$(echo "$row_complete" | grep -oP '<span class="copy-target[^"]*">\K[a-f0-9]{64}' || true)
if [[ -z "$download_url" || -z "$latest_version" || -z "$sha256_expected" ]]; then
echo "Failed to detect the latest release or its checksum."
send_email "Update failed" "Server: $(hostname)\nFailed to detect the latest release or checksum.\nTime: $(date)"
exit 3
fi
########################################
# Compare versions
########################################
version_gt() {
[ "$1" = "$2" ] && return 1
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do ver2[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
if ((10#${ver1[i]} > 10#${ver2[i]})); then return 0; fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then return 1; fi
done
return 1
}
#echo "Installed: [$installed_version]"
#echo "Latest: [$latest_version]"
if version_gt "$latest_version" "$installed_version"; then
echo "Update available."
elif version_gt "$installed_version" "$latest_version"; then
echo "Installed version is newer than latest available ($latest_version)."
send_email "Installed version newer than available" "Server: $(hostname)\nStatus: Installed Roundcube version ($installed_version) is newer than latest LTS ($latest_version).\nNo update performed.\nTime: $(date)"
exit 0
else
echo "Latest version:" "$latest_version"
echo "Already up to date."
send_email "No update needed" "Server: $(hostname)\nStatus: Roundcube is already up to date.\nInstalled version: $installed_version\nLatest available: $latest_version\nTime: $(date)"
exit 0
fi
########################################
# Confirmation only if not in CRON mode
########################################
if [ -t 0 ]; then
read -rp "Do you want to download and install the new Roundcube release $latest_version? [y/N]: " yn
case "$yn" in
[Yy]*) ;;
*) echo "Update cancelled by user."; exit 0 ;;
esac
fi
########################################
# Backup current installation
########################################
backup_dir="roundcube_backup_v${installed_version}_$(date +%F_%H%M%S)"
echo "Creating backup: $backup_dir"
cp -a "$INSTALL_DIR" "$backup_dir"
########################################
# Download release
########################################
filename=$(basename "$download_url")
echo "Downloading $filename"
if ! curl -fL --connect-timeout $CONNECT_TIMEOUT --max-time $MAX_TIMEOUT -o "$filename" "$download_url"; then
echo "Failed to download latest release."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Failed to download the latest release package.\nURL: $PAGE_URL\nTime: $(date)"
exit 30
fi
########################################
# Verify SHA256
########################################
echo "Verifying checksum..."
sha256_actual=$(sha256sum "$filename" | awk '{print $1}')
if [[ "$sha256_actual" != "$sha256_expected" ]]; then
echo "Checksum verification FAILED!"
rm -f "$filename"
send_email "Update FAILED" "Server: $(hostname)\nStatus: Roundcube update failed!\nInstalled version: $installed_version\nLatest version: $latest_version\nBackup: $backup_dir\nReason: SHA256 mismatch or extraction failure\nTime: $(date)"
exit 4
fi
echo "Checksum OK."
########################################
# Extract + Install
########################################
echo "Extracting..."
if ! tar -xzf "$filename"; then
echo "Extraction failed."
send_email "Update FAILED" "Server: $(hostname)\nStatus: Extraction failed.\nVersion: $latest_version\nBackup: $backup_dir\nTime: $(date)"
exit 14
fi
src_dir="roundcubemail-$latest_version"
if [[ ! -d "$src_dir" ]]; then
echo "Extraction failed. Directory $src_dir not found."
exit 5
fi
echo "Running install script..."
if [ -t 0 ]; then
"$src_dir/bin/installto.sh" "$INSTALL_DIR"
else
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
fi
if [[ $? -ne 0 ]]; then
echo "Install failed"
send_email "Update FAILED" "Server: $(hostname)\nStatus: Installation script failed.\nRollback performed.\nTime: $(date)"
[[ -d "${INSTALL_DIR}_failed" ]] && mv "${INSTALL_DIR}_failed" "${INSTALL_DIR}_failed_$(date +%s)"
if ! mv "$INSTALL_DIR" "${INSTALL_DIR}_failed"; then
echo "Rollback failed (step 1)"
exit 7
fi
if ! mv "$backup_dir" "$INSTALL_DIR"; then
echo "Rollback failed (step 2)"
exit 8
fi
exit 6
fi
########################################
# Post-install verification
########################################
echo "Verifying installed version..."
if ! new_installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/"); then
echo "Failed to detect installed version after update."
exit 13
fi
new_installed_version=$(echo "$new_installed_version" | tr -d '\r\n[:space:]')
if [[ "$new_installed_version" != "$latest_version" ]]; then
echo "Post-install verification FAILED!"
echo "Expected: $latest_version"
echo "Detected: $new_installed_version"
[[ -d "${INSTALL_DIR}_failed" ]] && mv "${INSTALL_DIR}_failed" "${INSTALL_DIR}_failed_$(date +%s)"
if ! mv "$INSTALL_DIR" "${INSTALL_DIR}_failed"; then
echo "Rollback failed (post-check step 1)"
exit 11
fi
if ! mv "$backup_dir" "$INSTALL_DIR"; then
echo "Rollback failed (post-check step 2)"
exit 12
fi
send_email "Update FAILED" "Server: $(hostname)\nStatus: Roundcube update failed during post-install verification.\nExpected version: $latest_version\nDetected version: $new_installed_version\nRollback performed.\nTime: $(date)"
exit 9
fi
echo "Post-install verification OK."
########################################
# Fix permissions
########################################
chown -R "$OWNER" "$INSTALL_DIR"
########################################
# Cleanup
########################################
rm -rf "$src_dir" "$filename"
echo "Update completed successfully!"
echo "Now running version: $latest_version"
send_email "Update successful" "Server: $(hostname)\nStatus: Roundcube updated successfully!\nPrevious version: $installed_version\nNew version: $latest_version\nBackup directory: $backup_dir\nTime: $(date)"
-
(...) due to CWP limited to PHP 7.4 (!!!!) Roundcube can't be updated beyond 1.6.11 (...)
"everything is fine, CWP have received updates X days ago"
Thank you for your script and alert.
-
You can update to the latest 1.5 LTS version, which is 1.5.13
That takes care of the issue.
-
You can update to the latest 1.5 LTS version, which is 1.5.13
That takes care of the issue.
That is the same as apply a bandage to a bullet hole. The core issue is still there and will bleed out eventually...
-
Excessive hyperbole. There's nothing wrong with LTS versions.
-
Excessive hyperbole. There's nothing wrong with LTS versions.
And i didnt say that there is...
LTS is great... to support old tech. So is a bandage, not a fix.
-
If you aren't satisfied with CWP then I don't understand why you are here.
Don't waste your time. I wish you luck finding another modern all-in-one control panel that meets your requirements.
-
If you aren't satisfied with CWP then I don't understand why you are here.
Don't waste your time. I wish you luck finding another modern all-in-one control panel that meets your requirements.
And i did, as many others. But that doesn't mean i don't follow the project...
-
And i did, as many others. But that doesn't mean i don't follow the project...
Following is one thing.
But all you seem to do is post misinformation and troll posts of actual users trying to get help with your hate of CWP...
Thank for finally admitting publicly your just a troll.
-
Yes... now, instead of reply with toxic, can you back to the original question?
Note that is YOU that are being offtopic with toxic answers, not me. Don't say BS in something that anyone can read, is a little dumb.
Otherwise, kindle provide any proof in how did i write any misinformation. If you cannot, YOU are being the toxic here, not me, so shut up.
Now, back to where all this started: a message from me thanking the users for the script. Thats it... everything after that was ignited from toxic replies... and ANYONE can read that so don't even answer please.
-
A new security vulnerability was found in Roundcube:
https://nvd.nist.gov/vuln/detail/CVE-2025-49113
The effected versions:
all versions before 1.5.10
all 1.6.x versions before 1.6.11
The most recent versions of Roundcube include the patch:
https://roundcube.net/news/2025/06/01/security-updates-1.6.11-and-1.5.10
CWP uses Roundcube 1.4.x therefore it is highly recommended to update Roundcube
Instructions how to update Roundcube to 1.5.11:
cd /usr/local/cwpsrv/var/services
cp -R roundcube roundcube_backup
wget https://github.com/roundcube/roundcubemail/releases/download/1.5.11/roundcubemail-1.5.11-complete.tar.gz
tar -xvzf roundcubemail-1.5.11-complete.tar.gz
cd roundcubemail-1.5.11
bin/installto.sh /usr/local/cwpsrv/var/services/roundcube
cd ..
chown -R cwpsvc:cwpsvc roundcube
rm -rf roundcubemail-1.5.11*
Please note you do it on your own risk.
I had a problem with it.
Seems CWP is running php-7.2.30 without php-intl extension.
Roundcube needs this extension to detect Spoofing.
The solution for this was to change
/usr/local/cwpsrv/conf.d/webmail.conf
/usr/local/cwpsrv/conf/cwp_services.conf
fastcgi_pass unix:/usr/local/cwp/php71/var/sockets/cwpsvc.sock;
to
fastcgi_pass unix:/opt/alt/php-fpm81/usr/var/sockets/cwpsvc.sock;
fastcgi_param PHP_ADMIN_VALUE "open_basedir = /usr/local/cwpsrv/var/services/roundcube/:/tmp/:/usr/local/cwp/php71/lib/";
to
fastcgi_param PHP_ADMIN_VALUE "open_basedir = /usr/local/cwpsrv/var/services/roundcube/:/tmp/:/usr/local/cwp/php71/lib/:/opt/alt/php-fpm82/usr/";
However this didn't catch it all. When you go to it through https://<your_server/webmail, you still ended up with php-7.2.30.
The version on port 2096 was OK, so I also changed the first lines of roundcube/index.php.
<?php
if (!preg_match("/:2096/",$_SERVER['HTTP_HOST'])) header('Location: https://<your_server>:2096/');
-
Be advised that CWP runs under its own dedicated PHP 7.2 version so changing its internal services to run on a more modern PHP version (8.2) risks breaking it or introducing unexpected behavior. Plus, if you take CWP too far out of spec and customize it, their support team will decline to help you if you have issues.
There are workarounds to the intl issue that don't risk breaking CWP. Follow these instructions, but update the version number to 1.5.14:
https://www.alphagnu.com/topic/33-update-cwp-roundcube-mail-version-158-%E2%80%93-control-web-panel/
-
Update to the script listed here:
http://forum.centos-webpanel.com/updates/roundcube-vulnerability/msg53064/#msg53064
Hi cyberspace,
Just used your script to update to 1.5.15 LTS -- on one server it worked fine, but on another server it errored out due to the system() function being disabled in that version of PHP, yet your script proceeded to report that the install had succeeded. I think you need to put some conditional logic around this code block to check for actual success before reporting success:
echo "Update completed successfully!"
echo "Now running version: $latest_version"
-
@overseer Searched the script for:
system and system( calls, and didn't see any.
Maybe @cyberspace could elaborate more.
-
Script wouldn't run unless system was an allowed function for that system version of PHP (8.3 in this case). It merrily proceeded to the ending echo lines and acted as if it had done something, but there was clearly an error during execution.
-
Just used your script to update to 1.5.15 LTS -- on one server it worked fine, but on another server it errored out due to the system() function being disabled in that version of PHP
Hi,
Sorry for the delayed reply. I’ve been away from home for a while and only have occasional access to my PC.
Anyway, the script doesn't use the function like system() or exec(). Do you run the script from PHP using system() ?
-
I had a problem with it.
Seems CWP is running php-7.2.30 without php-intl extension.
Roundcube needs this extension to detect Spoofing.
Seems "roundcube" running on my system doesn't require intl. Anyway, if your roundcube requires it you can compile the extension from sources:
As root:
cd /usr/local/src/
wget https://www.php.net/distributions/php-7.2.30.tar.gz
tar -xvzf php-7.2.30.tar.gz
cd php-7.2.30/ext/intl
/usr/local/cwp/php71/bin/phpize
./configure --with-php-config=/usr/local/cwp/php71/bin/php-config
make
cp modules/intl.so /usr/local/cwp/php71/lib/php/extensions/no-debug-non-zts-20170718/
open the file /usr/local/cwp/php71/php.ini for editing and add the line:
extension = intl.so
right before:
zend_extension = /usr/local/ioncube/ioncube_loader_lin_7.2.so
remove sources and extracted files
rm -rf /usr/local/src/php-*
-
Anyway, the script doesn't use the function like system() or exec(). Do you run the script from PHP using system() ?
I believe the error happens with the install line, using the default RC install script:
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"So it's a bit of an outlier, but maybe you need to test for installation success before reporting it with the echo lines that follow, and maybe worth testing the actual installed version and reporting that:
grep "Version " /usr/local/cwpsrv/var/services/roundcube/index.php | awk '{print $3}'
-
I believe the error happens with the install line, using the default RC install script:
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
Put:
set -euo pipefailright after:
#!/usr/bin/env bashand:
if [[ $? -ne 0 ]]; then
echo "Install script failed!"
send_email "Update FAILED" "Server: $(hostname)\nStatus: installto.sh failed\nBackup: $backup_dir\nTime: $(date)"
exit 6
fi
right after:
echo "Running install script..."
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
-
Hi guys,
I've developed a script to update Roundcube for CWP to the latest LTS version.
What does the script do ?
1. I parses the page:
https://roundcube.net/download/
to identify the latest LTS version of Roundcub and URL to .tag.gz file.
2. Compares the versions (installed and available at the website)
3. If the installed version is older than available then:
3a. Makes backup of the currently installed Roundcube
3b. Downloads the .tar.gz file from the website
3c. Checks the checksum to make sure the downloaded file isn't corrupted
3d. Updates Roundcube
3e. Sends a notification to the user (address is specified in the script)
If the versions are the same or installed version is never then just sends an simple notification like "no update needed".
#!/usr/bin/env bash
####################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2026 BeinHost.com #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
####################################################################################
########################################
# CONFIG
########################################
BASE_DIR="/usr/local/cwpsrv/var/services"
INSTALL_DIR="$BASE_DIR/roundcube"
PAGE_URL="https://roundcube.net/download/"
OWNER="cwpsvc:cwpsvc"
EMAIL="support@beinhost.com"
SUBJECT_PREFIX="[Roundcube Updater]"
cd "$BASE_DIR"
########################################
# Send notofication
########################################
send_email() {
local subject="$1"
local body="$2"
# use mail command
echo -e "$body" | mail -s "$SUBJECT_PREFIX $subject" "$EMAIL"
}
########################################
# Detect installed version
########################################
INI_FILE="$INSTALL_DIR/program/include/iniset.php"
if [[ ! -f "$INI_FILE" ]]; then
echo "Cannot detect installed version (iniset.php missing)."
exit 2
fi
installed_version=$(grep -oE "RCMAIL_VERSION',[[:space:]]*'[^']+'" \
"$INI_FILE" | sed -E "s/.*'([^']+)'.*/\1/")
installed_version=$(echo "$installed_version" | tr -d '\r\n[:space:]')
echo "Installed version: $installed_version"
########################################
# Detect latest LTS version + checksum
########################################
lts_block=$(curl -fsSL "$PAGE_URL" \
| awk '/<h2 id="lts">/,/<\/table>/')
download_url=$(echo "$lts_block" \
| grep -oE 'https://[^"]+-complete\.tar\.gz' \
| head -n1)
latest_version=$(echo "$download_url" \
| sed -E 's/.*roundcubemail-([0-9]+\.[0-9]+\.[0-9]+)-complete\.tar\.gz/\1/')
latest_version=$(echo "$latest_version" | tr -d '\r\n[:space:]')
sha256_expected=$(echo "$lts_block" \
| grep -oE '[a-f0-9]{64}' \
| head -n1)
if [[ -z "$download_url" || -z "$latest_version" || -z "$sha256_expected" ]]; then
echo "Failed to detect latest LTS release."
send_email "Update failed" "Server: `hostname`\nFailed to detect latest LTS release.\nTime: $(date)"
exit 3
fi
########################################
# Compare versions
########################################
version_gt() {
[ "$1" = "$2" ] && return 1
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do ver2[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
if ((10#${ver1[i]} > 10#${ver2[i]})); then return 0; fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then return 1; fi
done
return 1
}
#echo "Installed: [$installed_version]"
#echo "Latest: [$latest_version]"
if version_gt "$latest_version" "$installed_version"; then
echo "Update available."
send_email "Update successful" "Server: `hostname`\nStatus: Roundcube updated successfully!\nPrevious version: $installed_version\nNew version: $latest_version\nBackup directory: $backup_dir\nTime: $(date)"
elif version_gt "$installed_version" "$latest_version"; then
echo "Installed version is newer than LTS."
send_email "Installed version newer than LTS" "Server: `hostname`\nStatus: Installed Roundcube version ($installed_version) is newer than latest LTS ($latest_version).\nNo update performed.\nTime: $(date)"
else
echo "Latest LTS version:" "$latest_version"
echo "Already up to date."
send_email "No update needed" "Server: `hostname`\nStatus: Roundcube is already up to date.\nInstalled version: $installed_version\nLatest LTS: $latest_version\nTime: $(date)"
exit 0
fi
########################################
# Backup current installation
########################################
backup_dir="roundcube_backup_v${installed_version}_$(date +%F_%H%M%S)"
echo "Creating backup: $backup_dir"
cp -a roundcube "$backup_dir"
########################################
# Download release
########################################
filename=$(basename "$download_url")
echo "Downloading $filename"
curl -fL -o "$filename" "$download_url"
########################################
# Verify SHA256
########################################
echo "Verifying checksum..."
sha256_actual=$(sha256sum "$filename" | awk '{print $1}')
if [[ "$sha256_actual" != "$sha256_expected" ]]; then
echo "Checksum verification FAILED!"
rm -f "$filename"
send_email "Server: `hostname`\nUpdate FAILED" "Status: Roundcube update failed!\nInstalled version: $installed_version\nLatest version: $latest_version\nBackup: $backup_dir\nReason: SHA256 mismatch or extraction failure\nTime: $(date)"
exit 4
fi
echo "Checksum OK."
########################################
# Extract + Install
########################################
echo "Extracting..."
tar -xzf "$filename"
src_dir="roundcubemail-$latest_version"
if [[ ! -d "$src_dir" ]]; then
echo "Extraction failed. Directory $src_dir not found."
exit 5
fi
echo "Running install script..."
yes | "$src_dir/bin/installto.sh" "$INSTALL_DIR"
########################################
# Fix permissions
########################################
chown -R "$OWNER" roundcube
########################################
# Cleanup
########################################
rm -rf "$src_dir" "$filename"
echo "Update completed successfully!"
echo "Now running version: $latest_version"
send_email "Update successful.\nStatus: Roundcube updated: $installed_version -> $latest_version\nBackup: $backup_dir"
I tested the script some time and it worked fine for me. However, please note, you use the script on your own risk (MIT License) )
I triying to use this script but:
PHP Fatal error: Uncaught Error: Call to undefined function mb_internal_encoding() in /usr/local/cwpsrv/var/services/roundcubemail-1.6.16/program/lib/Roundcube/bootstrap.php:85
Stack trace:
#0 /usr/local/cwpsrv/var/services/roundcubemail-1.6.16/program/include/iniset.php(80): require_once()
#1 /usr/local/cwpsrv/var/services/roundcubemail-1.6.16/program/include/clisetup.php(25): require_once('...')
#2 /usr/local/cwpsrv/var/services/roundcubemail-1.6.16/bin/installto.sh(23): require_once('...')
#3 {main}
thrown in /usr/local/cwpsrv/var/services/roundcubemail-1.6.16/program/lib/Roundcube/bootstrap.php on line 85
Fatal error: Please check the Roundcube error log and/or server error logs for more information.
Update completed successfully!
Now running version: 1.6.16
żany idea?
-
You should be running the LTS 1.5.x branch for CWP compatibility. Can you verify that is your current (and only) version installed? 1.6.x won't work.