Compare commits

..

6 Commits

Author SHA1 Message Date
cschantz 5fb3640004 CRITICAL FIX: Add explicit function validation and error checking to show_scan_menu
FIXED:
- Added explicit validation that show_scan_menu() function exists before calling
- Added explicit validation that print_banner() exists before using it
- Added error output if print_banner() call fails
- Improved handling of empty available_scanners array (display '(None currently installed)')
- Added error checking to ensure functions are available before use

BEHAVIOR CHANGE:
- Menu now validates dependencies before displaying
- Better error messages if required functions are missing
- More robust handling of library sourcing failures

This should fix the issue where menu fails to display when libraries are not properly sourced.
2026-03-21 01:20:35 -04:00
cschantz 9942296714 CRITICAL: Apply all bug fixes to production branch
This commit applies the critical fixes found during beta testing:

1. FIX: Show installation guide instead of exiting when no scanners detected
   - Heredoc was exiting with code 1 instead of showing helpful installation instructions
   - Changed to display full installation guide and exit gracefully with code 0
   - Users now see 'here's how to install' instead of just error

2. FIX: Add missing color variable definitions to generator
   - Generator script was using CYAN, RED, YELLOW, GREEN, NC colors
   - But these variables were never defined in the generator itself
   - Added color variable definitions at script start
   - Menu now displays with proper colors

3. FIX: Add print_banner to required functions validation
   - show_scan_menu() calls print_banner but it wasn't validated
   - If common-functions.sh failed to source, menu would crash
   - Added print_banner to validate_required_functions()

All fixes ensure the malware scanner menu displays properly even with no
scanners installed, and provides helpful guidance for installation.
2026-03-21 01:11:04 -04:00
cschantz aa432a08bd CRITICAL FIX: Sync malware scanner menu fix to production branch
FIXED:
- detect_scanners() no longer blocks menu when scanners aren't installed
- Removed show_scanner_installation_guide() call from detection
- main() no longer exits early if no scanners detected
- Menu always displays with option 9 'Install all scanners'

This syncs the critical menu fix from dev branch (beta) to production (main)
ensuring both branches work correctly.
2026-03-21 00:48:20 -04:00
cschantz 3126944905 Reapply "CRITICAL FIXES: Apply essential improvements from beta branch to production"
This reverts commit e5979a501e.
2026-03-20 15:45:24 -04:00
cschantz e5979a501e Revert "CRITICAL FIXES: Apply essential improvements from beta branch to production"
This reverts commit eabddb553d.
2026-03-19 21:03:11 -04:00
cschantz eabddb553d CRITICAL FIXES: Apply essential improvements from beta branch to production
CRITICAL FIXES:
1. Add missing initialize_system_detection() call (launcher.sh)
   - System detection was never initialized before building reference database
   - This caused all SYS_* variables to be empty
   - Fixed blank system detection output issue reported on Alma 8

2. Fix all unsafe read statements (launcher.sh - 10+ occurrences)
   - Changed all 'read -r choice' to use /dev/tty with error handling
   - Prevents crashes when stdin is piped (curl | bash)
   - Prevents unexpected SSH session termination
   - Gracefully returns instead of exiting

3. Fix remaining read -p statements (launcher.sh)
   - Added </dev/tty and error suppression to startup and exit prompts
   - Prevents hangs when terminal not available

SECURITY FIXES:
4. Fix SQL injection in database queries (reference-db.sh)
   - Escape database names with backticks: WHERE table_schema=`$db`
   - Prevents malicious database names from breaking SQL

5. Fix password exposure in process listings (reference-db.sh)
   - Use MYSQL_PWD environment variable instead of command line
   - Credentials no longer visible in ps aux output
   - Added cleanup with unset MYSQL_PWD

6. Fix race condition in temp directory creation (common-functions.sh)
   - Changed from mkdir -p to mktemp -d
   - Secure permissions (0700) and unpredictable naming
   - Prevents TOCTOU attacks

All changes validated with bash -n syntax checks
Production launcher now matches/exceeds beta stability
2026-03-19 20:50:28 -04:00
4 changed files with 133 additions and 35 deletions
+44 -14
View File
@@ -53,7 +53,7 @@ run_module() {
echo "" echo ""
echo -e "${RED}✗ Module not found: $category/$module${NC}" echo -e "${RED}✗ Module not found: $category/$module${NC}"
echo "" echo ""
read -p "Press Enter to continue..." read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true
return 1 return 1
fi fi
@@ -74,7 +74,7 @@ run_module() {
echo -e "${RED}✗ Exited with code: $exit_code${NC}" echo -e "${RED}✗ Exited with code: $exit_code${NC}"
fi fi
echo "" echo ""
read -p "Press Enter to continue..." read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true
} }
############################################################################# #############################################################################
@@ -135,7 +135,9 @@ show_threat_analysis_menu() {
handle_threat_analysis_menu() { handle_threat_analysis_menu() {
while true; do while true; do
show_threat_analysis_menu show_threat_analysis_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "security" "bot-analyzer.sh" ;; 1) run_module "security" "bot-analyzer.sh" ;;
@@ -169,7 +171,9 @@ show_live_monitoring_menu() {
handle_live_monitoring_menu() { handle_live_monitoring_menu() {
while true; do while true; do
show_live_monitoring_menu show_live_monitoring_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "security" "live-attack-monitor.sh" ;; 1) run_module "security" "live-attack-monitor.sh" ;;
@@ -201,7 +205,9 @@ show_log_viewers_menu() {
handle_log_viewers_menu() { handle_log_viewers_menu() {
while true; do while true; do
show_log_viewers_menu show_log_viewers_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "security" "tail-apache-access.sh" ;; 1) run_module "security" "tail-apache-access.sh" ;;
@@ -232,7 +238,9 @@ show_security_actions_menu() {
handle_security_actions_menu() { handle_security_actions_menu() {
while true; do while true; do
show_security_actions_menu show_security_actions_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "security" "enable-cphulk.sh" ;; 1) run_module "security" "enable-cphulk.sh" ;;
@@ -266,7 +274,9 @@ show_security_menu() {
handle_security_menu() { handle_security_menu() {
while true; do while true; do
show_security_menu show_security_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) handle_threat_analysis_menu ;; 1) handle_threat_analysis_menu ;;
@@ -314,7 +324,9 @@ show_website_menu() {
handle_website_menu() { handle_website_menu() {
while true; do while true; do
show_website_menu show_website_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "website" "website-error-analyzer.sh" ;; 1) run_module "website" "website-error-analyzer.sh" ;;
@@ -367,7 +379,9 @@ show_performance_menu() {
handle_performance_menu() { handle_performance_menu() {
while true; do while true; do
show_performance_menu show_performance_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "performance" "mysql-query-analyzer.sh" ;; 1) run_module "performance" "mysql-query-analyzer.sh" ;;
@@ -473,7 +487,9 @@ show_acronis_menu() {
handle_backup_menu() { handle_backup_menu() {
while true; do while true; do
show_backup_menu show_backup_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) handle_acronis_menu ;; 1) handle_acronis_menu ;;
@@ -488,7 +504,9 @@ handle_backup_menu() {
handle_acronis_menu() { handle_acronis_menu() {
while true; do while true; do
show_acronis_menu show_acronis_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "backup" "acronis-install.sh" ;; 1) run_module "backup" "acronis-install.sh" ;;
@@ -542,7 +560,9 @@ show_email_menu() {
handle_email_menu() { handle_email_menu() {
while true; do while true; do
show_email_menu show_email_menu
read -r choice if ! read -r choice 2>/dev/null </dev/tty; then
return 0
fi
case $choice in case $choice in
1) run_module "email" "email-diagnostics.sh" ;; 1) run_module "email" "email-diagnostics.sh" ;;
@@ -573,6 +593,11 @@ init_directories() {
} }
startup_detection() { startup_detection() {
# Initialize system detection first (required for proper reference database)
if [ -z "${SYS_DETECTION_COMPLETE:-}" ]; then
initialize_system_detection
fi
if ! db_is_fresh; then if ! db_is_fresh; then
clear clear
print_banner "Server Management Toolkit - Initializing" print_banner "Server Management Toolkit - Initializing"
@@ -608,7 +633,7 @@ startup_detection() {
print_success "Detection complete! Cached for 1 hour." print_success "Detection complete! Cached for 1 hour."
echo "" echo ""
read -p "Press Enter to continue..." read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true
fi fi
} }
@@ -622,7 +647,12 @@ main() {
while true; do while true; do
show_main_menu show_main_menu
read -r choice
# Read from terminal (use /dev/tty directly for interaction)
if ! read -r choice 2>/dev/null </dev/tty; then
# No terminal available, return from function gracefully
return 0
fi
case $choice in case $choice in
1) run_module "diagnostics" "system-health-check.sh" ;; 1) run_module "diagnostics" "system-health-check.sh" ;;
+1 -2
View File
@@ -169,8 +169,7 @@ show_terminal_info() {
# Create temporary session directory # Create temporary session directory
create_temp_session() { create_temp_session() {
export SESSION_ID=$$ export SESSION_ID=$$
export TEMP_SESSION_DIR="/tmp/server-toolkit-${SESSION_ID}" export TEMP_SESSION_DIR=$(mktemp -d -t server-toolkit.XXXXXX)
mkdir -p "$TEMP_SESSION_DIR"
# Cleanup on exit # Cleanup on exit
trap '[ -n "$TEMP_SESSION_DIR" ] && rm -rf "$TEMP_SESSION_DIR" 2>/dev/null' EXIT INT TERM trap '[ -n "$TEMP_SESSION_DIR" ] && rm -rf "$TEMP_SESSION_DIR" 2>/dev/null' EXIT INT TERM
+6 -3
View File
@@ -162,8 +162,8 @@ build_databases_section() {
# Build MySQL command with credentials if needed # Build MySQL command with credentials if needed
local mysql_cmd="mysql" local mysql_cmd="mysql"
if [ "$SYS_CONTROL_PANEL" = "plesk" ] && [ -f /etc/psa/.psa.shadow ]; then if [ "$SYS_CONTROL_PANEL" = "plesk" ] && [ -f /etc/psa/.psa.shadow ]; then
local plesk_mysql_pass=$(cat /etc/psa/.psa.shadow) export MYSQL_PWD=$(cat /etc/psa/.psa.shadow)
mysql_cmd="mysql -uadmin -p${plesk_mysql_pass}" mysql_cmd="mysql -uadmin"
fi fi
local total_dbs=$($mysql_cmd -Ns -e "SHOW DATABASES" 2>/dev/null | grep -v "^information_schema$\|^mysql$\|^performance_schema$\|^sys$" | wc -l) local total_dbs=$($mysql_cmd -Ns -e "SHOW DATABASES" 2>/dev/null | grep -v "^information_schema$\|^mysql$\|^performance_schema$\|^sys$" | wc -l)
@@ -180,7 +180,7 @@ build_databases_section() {
local size_mb=$($mysql_cmd -Ns -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) local size_mb=$($mysql_cmd -Ns -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2)
FROM information_schema.TABLES FROM information_schema.TABLES
WHERE table_schema='$db'" 2>/dev/null) WHERE table_schema=\`$db\`" 2>/dev/null)
[ -z "$size_mb" ] && size_mb=0 [ -z "$size_mb" ] && size_mb=0
local table_count=$($mysql_cmd -Ns "$db" -e "SHOW TABLES" 2>/dev/null | wc -l) local table_count=$($mysql_cmd -Ns "$db" -e "SHOW TABLES" 2>/dev/null | wc -l)
@@ -190,6 +190,9 @@ build_databases_section() {
finish_progress finish_progress
echo "" >> "$SYSREF_DB" echo "" >> "$SYSREF_DB"
# Clean up password environment variable
unset MYSQL_PWD
} }
# Check domain HTTP/HTTPS status codes # Check domain HTTP/HTTPS status codes
+82 -16
View File
@@ -8,6 +8,14 @@
# Scan scope: Single domain, user account, or entire server # Scan scope: Single domain, user account, or entire server
################################################################################ ################################################################################
# Color definitions (matching launcher.sh)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# Source required libraries (warn if missing, but allow graceful degradation) # Source required libraries (warn if missing, but allow graceful degradation)
@@ -32,6 +40,7 @@ validate_required_functions() {
local required_functions=( local required_functions=(
"confirm" "confirm"
"print_header" "print_header"
"print_banner"
"select_user_interactive" "select_user_interactive"
"get_user_domains" "get_user_domains"
) )
@@ -91,13 +100,9 @@ detect_scanners() {
available_scanners+=("rkhunter") available_scanners+=("rkhunter")
fi fi
if [ ${#available_scanners[@]} -eq 0 ]; then # Note: If no scanners are found, available_scanners array will be empty
echo -e "${RED}No malware scanners detected!${NC}" # Menu option 9 allows installation, so we don't exit here
echo "" # Just return success to allow menu to display
show_scanner_installation_guide
return 1
fi
return 0 return 0
} }
@@ -823,10 +828,51 @@ else
fi fi
fi fi
# If no scanners found, show installation guide and exit gracefully
if [ ${#AVAILABLE_SCANNERS[@]} -eq 0 ]; then if [ ${#AVAILABLE_SCANNERS[@]} -eq 0 ]; then
log_message "ERROR: No scanners found!" log_message "WARNING: No scanners found on this system"
echo ""
echo -e "${RED}No malware scanners detected!${NC}" echo -e "${RED}No malware scanners detected!${NC}"
exit 1 echo ""
echo -e "${YELLOW}Available Malware Scanners:${NC}"
echo ""
echo -e "${CYAN}ImunifyAV${NC} - FREE real-time malware scanner"
echo " Status: Not installed"
echo " Installation (cPanel):"
echo " yum install imunify-antivirus imunify-antivirus-cpanel"
echo " /opt/alt/python35/share/imunify360/scripts/av-userside-plugin.sh"
echo " Installation (manual):"
echo " wget https://repo.imunify360.cloudlinux.com/defence360/imav-deploy.sh"
echo " bash imav-deploy.sh"
echo " Docs: https://docs.imunify360.com/imunifyav/"
echo ""
echo -e "${CYAN}ClamAV${NC} - Open source antivirus engine"
echo " Status: Not installed"
echo " Installation:"
echo " yum install clamav clamav-update # RHEL/CentOS"
echo " apt-get install clamav clamav-daemon # Debian/Ubuntu"
echo ""
echo -e "${CYAN}Maldet (LMD)${NC} - Linux Malware Detect"
echo " Status: Not installed"
echo " Installation:"
echo " cd /tmp && wget http://www.rfxn.com/downloads/maldetect-current.tar.gz"
echo " tar -xzf maldetect-current.tar.gz && cd maldetect-*"
echo " ./install.sh"
echo ""
echo -e "${CYAN}Rootkit Hunter${NC} - Rootkit/backdoor/exploit scanner"
echo " Status: Not installed"
echo " Installation:"
echo " yum install epel-release rkhunter # RHEL/CentOS"
echo " apt-get install rkhunter # Debian/Ubuntu"
echo ""
echo -e "${YELLOW}Recommendation:${NC} Install at least ClamAV + RKHunter (both free)"
echo ""
exit 0
fi fi
log_message "Found ${#AVAILABLE_SCANNERS[@]} scanner(s): ${AVAILABLE_SCANNERS[*]}" log_message "Found ${#AVAILABLE_SCANNERS[@]} scanner(s): ${AVAILABLE_SCANNERS[*]}"
@@ -2181,20 +2227,33 @@ delete_standalone_sessions() {
# Main scan menu # Main scan menu
show_scan_menu() { show_scan_menu() {
# Ensure print_banner is available before calling it
if ! declare -f "print_banner" &>/dev/null; then
echo "ERROR: print_banner function not found" >&2
return 1
fi
# Build reference database once for the entire menu session # Build reference database once for the entire menu session
if command -v build_reference_database &>/dev/null; then if command -v build_reference_database &>/dev/null; then
echo "Building system reference database..."
build_reference_database 2>/dev/null || true build_reference_database 2>/dev/null || true
clear clear
fi fi
while true; do while true; do
print_banner "Malware Scanner" # Call print_banner - MUST succeed
print_banner "Malware Scanner" || {
echo "ERROR: print_banner failed" >&2
return 1
}
echo "Available Scanners:" echo "Available Scanners:"
for scanner in "${available_scanners[@]}"; do if [ ${#available_scanners[@]} -eq 0 ]; then
echo "${scanner^}" echo " (None currently installed)"
done else
for scanner in "${available_scanners[@]}"; do
echo "${scanner^}"
done
fi
echo "" echo ""
echo -e "${CYAN}Create New Scan:${NC}" echo -e "${CYAN}Create New Scan:${NC}"
@@ -2540,10 +2599,17 @@ generate_client_report() {
# Main execution # Main execution
main() { main() {
if ! detect_scanners; then # Detect scanners (populate available_scanners array)
exit 1 # Don't exit if none found - menu option 9 allows installation
detect_scanners || true
# Verify show_scan_menu exists and is callable
if ! declare -f "show_scan_menu" &>/dev/null; then
echo "ERROR: show_scan_menu function not found" >&2
return 1
fi fi
# Call the menu function
show_scan_menu show_scan_menu
} }