#!/bin/bash
# Set up Florian Roth's `signature-base` YARA ruleset on the Makenotwork
# production host. Idempotent: safe to re-run; pulls upstream changes if
# the repo's already cloned.
#
# After this script finishes, add the following to /opt/makenotwork/.env
# (and restart makenotwork):
#
#     YARA_RULES_DIR=/opt/makenotwork/yara-rules
#
# The `yara` layer compiles every `.yar` file in that directory at server
# startup. The Pipeline Health card flips from "down — No YARA rules loaded"
# to "ok" after the first upload completes.
#
# Periodic refresh: install the cron entry at the bottom of this script so
# upstream rule updates land automatically. Re-running the cron does NOT
# restart makenotwork — new rules take effect on next startup. Run a manual
# `systemctl restart makenotwork` after a significant ruleset change.
#
# References:
#   - https://github.com/Neo23x0/signature-base
#   - https://github.com/Neo23x0/signature-base/blob/master/LICENSE (CC-BY-NC 4.0)
#
# License note: signature-base is CC-BY-NC 4.0 (non-commercial). We use it
# server-side to protect creators on the platform; this is the same usage
# profile the upstream contributors document for SIEM/IR deployments.

set -euo pipefail

RULES_REPO="https://github.com/Neo23x0/signature-base.git"
WORK_DIR="/opt/makenotwork/yara-rules-src"
LINK_DIR="/opt/makenotwork/yara-rules"
CRON_FILE="/etc/cron.d/mnw-yara-rules"

require_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "[yara] error: must run as root" >&2
        exit 1
    fi
}

ensure_git() {
    if ! command -v git >/dev/null 2>&1; then
        DEBIAN_FRONTEND=noninteractive apt-get update -qq
        DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git
    fi
}

pull_or_clone() {
    if [ -d "$WORK_DIR/.git" ]; then
        echo "[yara] updating $WORK_DIR..."
        git -C "$WORK_DIR" fetch --depth=1 origin master
        git -C "$WORK_DIR" reset --hard origin/master
    else
        echo "[yara] cloning $RULES_REPO -> $WORK_DIR..."
        git clone --depth=1 "$RULES_REPO" "$WORK_DIR"
    fi
}

assemble_link_dir() {
    # The repo lays rules out under yara/, but also ships a few support
    # files we want to skip (LICENSE, .md, etc.). Assemble a flat dir of
    # .yar files so the yara-x compiler walks it cleanly.
    echo "[yara] assembling $LINK_DIR..."
    rm -rf "$LINK_DIR"
    mkdir -p "$LINK_DIR"
    # Copy every .yar / .yara, preserving filenames. find -print0 + cp is
    # the safe pattern (handles spaces, though signature-base avoids them).
    find "$WORK_DIR/yara" -type f \( -name '*.yar' -o -name '*.yara' \) -print0 \
        | xargs -0 -I {} cp {} "$LINK_DIR/"
    local count
    count=$(ls -1 "$LINK_DIR" | wc -l)
    echo "[yara] $count rule files staged"
}

write_ruleset_version() {
    # Stamp the commit SHA so we can correlate scan_layers details back to
    # a specific rule revision when a creator asks "why did this flag?"
    local sha
    sha=$(git -C "$WORK_DIR" rev-parse --short HEAD)
    local date
    date=$(git -C "$WORK_DIR" log -1 --format=%cI)
    cat > "$LINK_DIR/RULESET_VERSION" <<EOF
repo=$RULES_REPO
commit=$sha
date=$date
synced_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
EOF
    echo "[yara] ruleset commit $sha ($date)"
}

install_cron() {
    cat > "$CRON_FILE" <<EOF
# Pull upstream YARA ruleset updates weekly. Does not restart makenotwork —
# the compiled rules in memory keep working until the next service restart.
SHELL=/bin/bash
PATH=/usr/sbin:/usr/bin:/sbin:/bin
30 4 * * 1 root /opt/makenotwork/deploy/setup-yara-rules.sh >> /var/log/mnw-yara-update.log 2>&1
EOF
    chmod 644 "$CRON_FILE"
    echo "[yara] cron installed at $CRON_FILE (weekly, Mondays 04:30 UTC)"
}

main() {
    require_root
    ensure_git
    pull_or_clone
    assemble_link_dir
    write_ruleset_version

    # Only install the cron on the first setup run (re-running idempotently
    # rewrites it, which is also fine but noisy).
    if [ ! -f "$CRON_FILE" ]; then
        install_cron
    fi

    cat <<EOF

[yara] setup complete. Ruleset at $LINK_DIR.

Next step — set the env var so makenotwork uses these rules:

    echo 'YARA_RULES_DIR=$LINK_DIR' >> /opt/makenotwork/.env
    systemctl restart makenotwork

The Pipeline Health card for 'yara' will flip from down to ok after the
first upload passes through the scan worker. Subsequent ruleset bumps land
via the weekly cron; a manual 'systemctl restart makenotwork' picks up the
newly-compiled rules.

EOF
}

main "$@"
