#!/bin/bash
# freeloader-helper.sh
# Restricted privileged helper for Freeloader
# Only allows specific operations on a hard-coded whitelist of directories.
# N5AD / hardened - July 2026

set -euo pipefail

# ============================================================
# HARD-CODED ALLOWED BASE DIRECTORIES
# Must match freeloader_allowed_dirs() in freeloader_common.php
# Excludes /usr/local/bin and /var/www/html/freeloader intentionally.
# ============================================================
ALLOWED_DIRS=(
    "/my_uploads"
    "/etc/asterisk"
    "/etc/asterisk/local"
    "/etc/allmon3"
    "/var/lib/asterisk"
    "/var/www/html/supermon"
    "/usr/share/allmon3"
)

is_allowed_path() {
    local target="$1"
    local resolved
    resolved=$(realpath -e "$target" 2>/dev/null) || return 1

    local dir
    for dir in "${ALLOWED_DIRS[@]}"; do
        local basedir
        basedir=$(realpath -e "$dir" 2>/dev/null) || continue
        if [[ "$resolved" == "$basedir" || "$resolved" == "$basedir"/* ]]; then
            return 0
        fi
    done
    return 1
}

die() {
    echo "ERROR: $*" >&2
    exit 1
}

cmd="${1:-}"

case "$cmd" in
    cat)
        [[ $# -eq 2 ]] || die "cat requires exactly one path"
        target="$2"
        is_allowed_path "$target" || die "Path not allowed: $target"
        [[ -f "$target" ]] || die "Not a regular file: $target"
        cat -- "$target"
        ;;

    cp)
        [[ $# -eq 3 ]] || die "cp requires src and dst"
        src="$2"
        dst="$3"
        [[ -f "$src" ]] || die "Source not found or not a file: $src"
        dstdir=$(dirname -- "$dst")
        is_allowed_path "$dstdir" || die "Destination directory not allowed: $dstdir"
        real_dst_dir=$(realpath -e "$dstdir")
        base_name=$(basename -- "$dst")
        [[ "$base_name" != *..* && "$base_name" != */* ]] || die "Invalid destination filename"
        # Block executable / webshell extensions at the helper boundary
        case "${base_name,,}" in
            *.php|*.phtml|*.php3|*.php4|*.php5|*.php7|*.php8|*.phar|*.exe|*.cgi|*.asp|*.aspx|*.jsp|.htaccess|htaccess|.htpasswd)
                die "Refusing to write dangerous filename: $base_name"
                ;;
        esac
        cp -- "$src" "$real_dst_dir/$base_name"
        chmod 644 "$real_dst_dir/$base_name" 2>/dev/null || true
        ;;

    rm)
        [[ $# -eq 2 ]] || die "rm requires exactly one path"
        target="$2"
        is_allowed_path "$target" || die "Path not allowed: $target"
        [[ -f "$target" ]] || die "Not a regular file (or does not exist): $target"
        rm -f -- "$target"
        ;;

    restart_asterisk)
        [[ $# -eq 1 ]] || die "restart_asterisk takes no arguments"
        systemctl restart asterisk
        ;;

    *)
        die "Unknown or missing command. Allowed: cat, cp, rm, restart_asterisk"
        ;;
esac

exit 0
