diff --git a/mail-status.sh b/mail-status.sh index 1746f6f..757c17e 100644 --- a/mail-status.sh +++ b/mail-status.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Postfix Mail Summary Tool - PRODUCTION READY EDITION (v4.0.7) +# Postfix Mail Summary Tool - PRODUCTION READY EDITION (v4.0.8) set -euo pipefail IFS=$'\n\t' @@ -134,14 +134,20 @@ if [[ "$WATCH_MODE" -eq 1 && "$REGEX_MODE" -eq 1 ]]; then exit 1 fi +# SECURITY SAFEGUARD: Path Validation for --log-dir (Directory Traversal Protection) +if [[ "$LOG_DIR" != "/var/log" && "$LOG_DIR" != "/var/log/mail" ]]; then + echo "Error: Unsafe log directory specified ($LOG_DIR). Only /var/log or /var/log/mail are allowed." >&2 + exit 1 +fi + # ============================================================================== # 3. RESOURCE LIMITS & LOCKFILES (PRODUCTION SAFEGUARDS) # ============================================================================== if [[ "$WATCH_MODE" -eq 1 ]]; then - LOCKFILE="/tmp/postfix_watch.lock" + LOCKFILE="${TMPDIR:-/tmp}/postfix_watch_${UID}.lock" ulimit -v 500000 else - LOCKFILE="/tmp/postfix_summary.lock" + LOCKFILE="${TMPDIR:-/tmp}/postfix_summary_${UID}.lock" ulimit -t 15 ulimit -v 500000 ulimit -f 102400 @@ -153,7 +159,7 @@ if ! flock -n 9; then exit 1 fi -TMP_DATA=$(mktemp /tmp/postfix_log.XXXXXX) +TMP_DATA=$(mktemp "${TMPDIR:-/tmp}/postfix_log.XXXXXX") trap 'rm -f "$TMP_DATA" 2>/dev/null' EXIT # ============================================================================== @@ -181,7 +187,7 @@ get_log_stream() { done < <(find "$LOG_DIR" -maxdepth 1 \( -name 'maillog*' -o -name 'mail.log*' \) -type f -print0 2>/dev/null | sort -z -r) if [ ${#LOG_FILES[@]} -eq 0 ]; then - echo "Error: No Postfix logs found." >&2; exit 1 + echo "Error: No Postfix logs found in $LOG_DIR." >&2; exit 1 fi for log in "${LOG_FILES[@]}"; do