#!/bin/bash
################################################################################
# Script Name: version/2.1.30/UPDATE.sh
# Description: Get the web application firewall running again.
# Company: hitechcloud.org
# Copyright (c) hitechcloud.org
################################################################################
#
# Nothing to migrate. What this does is start a service that has not been
# running on any server that installed it.
#
# The firewall's own preflight created its master key, as root, and the service
# runs as hitechwaf - so every start since failed with "permission denied" and
# systemd gave up ten seconds later. The binary in this release no longer
# writes during a check, and `native-waf` repairs the ownership on any
# invocation, but neither helps a server where nobody happens to run a firewall
# command. So it is repaired here, once, and the result is reported either way.
#
# The unit file also changes in this release - StartLimitIntervalSec moves to
# the section systemd actually reads it in - which needs a daemon-reload before
# the restart, or systemd keeps enforcing the limit that stopped it last time.
################################################################################

set -uo pipefail

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
ok()   { echo -e "[2.1.30] ${GREEN}✓${NC} $*"; }
warn() { echo -e "[2.1.30] ${YELLOW}!${NC} $*" >&2; }

[[ $EUID -eq 0 ]] || { echo "[2.1.30] This update must run as root." >&2; exit 1; }

WAF_ROOT="/etc/hitechcloud/native/waf"
WAF_USER="hitechwaf"

# Asked without a pipe, on purpose. `systemctl list-unit-files | grep -q ...`
# looks obvious and is wrong under `set -o pipefail`: grep -q exits the moment
# it matches, systemctl is killed by SIGPIPE, the pipeline reports 141, and
# pipefail turns a match into a failure. This script's first version said "the
# firewall is not installed" on a server where it was installed and running.
installed=$(systemctl list-unit-files --no-legend --no-pager hitechcloud-waf.service 2>/dev/null)
if [[ -z "$installed" ]]; then
    ok "The web application firewall is not installed on this server"
    ok "2.1.30 update complete"
    exit 0
fi

# The new unit file has to be read before the restart, or systemd applies the
# start limit from the old one - which is the limit that stopped the service.
systemctl daemon-reload >/dev/null 2>&1

if id -u "$WAF_USER" >/dev/null 2>&1 && [[ -d "$WAF_ROOT" ]]; then
    # Ownership across the whole directory, not just the key: the key is what
    # was found, but anything in here written by a root-run command has the
    # same problem waiting.
    chown -R "${WAF_USER}:${WAF_USER}" "$WAF_ROOT" 2>/dev/null || true
    [[ -f "${WAF_ROOT}/secret.key" ]] && chmod 640 "${WAF_ROOT}/secret.key" 2>/dev/null
    ok "Firewall state directory belongs to ${WAF_USER}"
fi

# The logs it appends to, which systemd opens as root.
if [[ -d /var/log/hitechcloud/native/waf ]] && id -u "$WAF_USER" >/dev/null 2>&1; then
    chown -R "${WAF_USER}:${WAF_USER}" /var/log/hitechcloud/native/waf 2>/dev/null || true
fi

restarts_before=$(systemctl show hitechcloud-waf -p NRestarts --value 2>/dev/null)
systemctl reset-failed hitechcloud-waf >/dev/null 2>&1
systemctl restart hitechcloud-waf >/dev/null 2>&1

# Give it a moment to fail the way it used to before calling it healthy.
sleep 3

if [[ "$(systemctl is-active hitechcloud-waf 2>/dev/null)" == active ]]; then
    if [[ -n "${restarts_before:-}" && "${restarts_before:-0}" -gt 10 ]]; then
        ok "Firewall is running. It had restarted ${restarts_before} times before this - it has not been protecting anything since it was installed."
    else
        ok "Firewall is running"
    fi
else
    warn "The firewall did not start. Check: journalctl -u hitechcloud-waf, and /var/log/hitechcloud/native/waf/service.log"
fi

ok "2.1.30 update complete"
exit 0
