mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-02-18 15:16:25 +00:00
Compare commits
4 Commits
copilot/fi
...
2025-12a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8d9315d4a | ||
|
|
d977ddb501 | ||
|
|
e76f5237ed | ||
|
|
c11ed5dd1e |
@@ -95,51 +95,6 @@ echo "$(clamd -V) is starting... please wait a moment."
|
||||
nice -n10 clamd &
|
||||
BACKGROUND_TASKS+=($!)
|
||||
|
||||
# Give clamd time to start up, especially with limited resources
|
||||
# This grace period allows clamd to initialize fully before health checks begin
|
||||
# Can be configured via CLAMD_STARTUP_TIMEOUT environment variable
|
||||
STARTUP_GRACE_PERIOD=${CLAMD_STARTUP_TIMEOUT:-600} # Default: 10 minutes in seconds
|
||||
echo "Waiting up to ${STARTUP_GRACE_PERIOD} seconds for clamd to start up..."
|
||||
|
||||
# Helper function to check if clamd is ready
|
||||
clamd_is_ready() {
|
||||
[ "$(echo "PING" | nc -w 1 localhost 3310 2>/dev/null)" = "PONG" ]
|
||||
}
|
||||
|
||||
# Wait for clamd to be ready or until timeout
|
||||
START_TIME=$(date +%s)
|
||||
POLL_INTERVAL=10
|
||||
CLAMD_READY=0
|
||||
|
||||
while true; do
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ELAPSED=$((CURRENT_TIME - START_TIME))
|
||||
|
||||
# Check if clamd is responsive by attempting to connect on localhost
|
||||
# clamd listens on 0.0.0.0:3310 (configured in Dockerfile)
|
||||
if clamd_is_ready; then
|
||||
echo "clamd is ready after ${ELAPSED} seconds"
|
||||
CLAMD_READY=1
|
||||
break
|
||||
fi
|
||||
|
||||
# Check if we've exceeded the timeout
|
||||
if [ ${ELAPSED} -ge ${STARTUP_GRACE_PERIOD} ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep ${POLL_INTERVAL}
|
||||
done
|
||||
|
||||
# Report final status only if not already reported as ready
|
||||
if [ ${CLAMD_READY} -eq 0 ]; then
|
||||
if clamd_is_ready; then
|
||||
echo "clamd is now ready (started during final check)"
|
||||
else
|
||||
echo "Warning: clamd did not respond to PING within ${STARTUP_GRACE_PERIOD} seconds - it may still be starting up"
|
||||
fi
|
||||
fi
|
||||
|
||||
while true; do
|
||||
for bg_task in ${BACKGROUND_TASKS[*]}; do
|
||||
if ! kill -0 ${bg_task} 1>&2; then
|
||||
|
||||
@@ -814,6 +814,32 @@ function verify_hash($hash, $password) {
|
||||
$hash = $components[4];
|
||||
return hash_equals(hash_pbkdf2('sha1', $password, $salt, $rounds), $hash);
|
||||
|
||||
case "PBKDF2-SHA512":
|
||||
// Handle FreeIPA-style hash: {PBKDF2-SHA512}10000$<base64_salt>$<base64_hash>
|
||||
$components = explode('$', $hash);
|
||||
if (count($components) !== 3) return false;
|
||||
|
||||
// 1st part: iteration count (integer)
|
||||
$iterations = intval($components[0]);
|
||||
if ($iterations <= 0) return false;
|
||||
|
||||
// 2nd part: salt (base64-encoded)
|
||||
$salt = $components[1];
|
||||
// 3rd part: hash (base64-encoded)
|
||||
$stored_hash_b64 = $components[2];
|
||||
|
||||
// Decode salt and hash from base64
|
||||
$salt_bin = base64_decode($salt, true);
|
||||
$hash_bin = base64_decode($stored_hash_b64, true);
|
||||
if ($salt_bin === false || $hash_bin === false) return false;
|
||||
// Get length of hash in bytes
|
||||
$hash_len = strlen($hash_bin);
|
||||
if ($hash_len === 0) return false;
|
||||
|
||||
// Calculate PBKDF2-SHA512 hash for provided password
|
||||
$test_hash = hash_pbkdf2('sha512', $password, $salt_bin, $iterations, $hash_len, true);
|
||||
return hash_equals($hash_bin, $test_hash);
|
||||
|
||||
case "PLAIN-MD4":
|
||||
return hash_equals(hash('md4', $password), $hash);
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
<form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>
|
||||
|
||||
{% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active and not is_root_uri %}
|
||||
{% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active and not is_root_uri and mailcow_cc_username %}
|
||||
<div class="container mt-4">
|
||||
<div class="alert alert-{{ ui_texts.ui_announcement_type }}">{{ ui_texts.ui_announcement_text }}</div>
|
||||
</div>
|
||||
|
||||
@@ -75,7 +75,6 @@ services:
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
- SKIP_CLAMD=${SKIP_CLAMD:-n}
|
||||
- CLAMD_STARTUP_TIMEOUT=${CLAMD_STARTUP_TIMEOUT:-600}
|
||||
volumes:
|
||||
- ./data/conf/clamav/:/etc/clamav/:Z
|
||||
- clamd-db-vol-1:/var/lib/clamav
|
||||
@@ -322,7 +321,7 @@ services:
|
||||
ofelia.job-exec.dovecot_clean_q_aged.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu vmail /usr/local/bin/clean_q_aged.sh || exit 0\""
|
||||
ofelia.job-exec.dovecot_maildir_gc.schedule: "0 */30 * * * *"
|
||||
ofelia.job-exec.dovecot_maildir_gc.command: "/bin/bash -c \"source /source_env.sh ; /usr/local/bin/gosu vmail /usr/local/bin/maildir_gc.sh\""
|
||||
ofelia.job-exec.dovecot_sarules.schedule: "0 0 0 * * *"
|
||||
ofelia.job-exec.dovecot_sarules.schedule: "@every 24h"
|
||||
ofelia.job-exec.dovecot_sarules.command: "/bin/bash -c \"/usr/local/bin/sa-rules.sh\""
|
||||
ofelia.job-exec.dovecot_fts.schedule: "0 0 0 * * *"
|
||||
ofelia.job-exec.dovecot_fts.command: "/bin/bash -c \"/usr/local/bin/gosu vmail /usr/local/bin/optimize-fts.sh\""
|
||||
|
||||
@@ -91,6 +91,44 @@ if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add image prefetch function
|
||||
function prefetch_image() {
|
||||
echo "Checking Docker image: ${DEBIAN_DOCKER_IMAGE}"
|
||||
|
||||
# Get local image digest if it exists
|
||||
local local_digest=$(docker image inspect ${DEBIAN_DOCKER_IMAGE} --format='{{index .RepoDigests 0}}' 2>/dev/null | cut -d'@' -f2)
|
||||
|
||||
# Get remote image digest without pulling
|
||||
local remote_digest=$(docker manifest inspect ${DEBIAN_DOCKER_IMAGE} 2>/dev/null | grep -oP '"digest":\s*"\K[^"]+' | head -1)
|
||||
|
||||
if [[ -z "${remote_digest}" ]]; then
|
||||
echo "Warning: Unable to check remote image"
|
||||
if [[ -n "${local_digest}" ]]; then
|
||||
echo "Using cached version"
|
||||
echo
|
||||
return 0
|
||||
else
|
||||
echo "Error: Image ${DEBIAN_DOCKER_IMAGE} not found locally or remotely"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${local_digest}" != "${remote_digest}" ]]; then
|
||||
echo "Image update available, pulling ${DEBIAN_DOCKER_IMAGE}"
|
||||
if docker pull ${DEBIAN_DOCKER_IMAGE} 2>/dev/null; then
|
||||
echo "Successfully pulled ${DEBIAN_DOCKER_IMAGE}"
|
||||
else
|
||||
echo "Error: Failed to pull ${DEBIAN_DOCKER_IMAGE}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Image is up to date (${remote_digest:0:12}...)"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
# Prefetch the image early in the script
|
||||
prefetch_image
|
||||
|
||||
function backup() {
|
||||
DATE=$(date +"%Y-%m-%d-%H-%M-%S")
|
||||
|
||||
Reference in New Issue
Block a user