#!/bin/bash
# NetworkManager dispatcher: point chrony at the fleet NTP server, learned from
# DHCP at runtime (no FQDN baked into the image). Two modes, baked at build time:
#
#   nts  (secure_ntp=true, default): AUTHENTICATED time. Derive the server NAME
#        from the DHCP-provided domain as <PREFIX>.<domain> and write
#        `server NAME iburst nts`. chrony verifies the NTS-KE TLS cert against the
#        fleet CA (chrony.conf: ntstrustedcerts). Because the domain comes from
#        DHCP, a domain change needs only a new DHCP domain + reissued NTS cert —
#        no image rebuild. A DHCP/NTP/DNS spoofer can only DoS (no fleet-CA-signed
#        cert for the name it redirects to => NTS fails => no sync); it cannot
#        shift the clock. See docs/secure-ntp-design.md (F-03/P-18).
#
#   dhcp (secure_ntp=false): LEGACY, UNAUTHENTICATED. Write the DHCP option-42
#        server IPs as plain `server <ip> iburst`. Lab/interop only.
#
# We use NetworkManager's internal DHCP (the network-manager dracut port); NM
# exports the lease's domain as $DHCP4_DOMAIN_NAME (option 15) / $DHCP4_DOMAIN_SEARCH
# (option 119) and NTP servers as $DHCP4_NTP_SERVERS (option 42). chrony.conf
# carries `sourcedir /run/chrony-dhcp`, so writing <iface>.sources there and
# reloading makes chronyd use them. The baked public pool is stripped (provisioner).
#
# Installed 0755 root:root. Lenient on purpose: a hiccup here must never break
# networking. @NTP_MODE@/@NTP_PREFIX@ are substituted at build time.

MODE="@NTP_MODE@"      # nts | dhcp
PREFIX="@NTP_PREFIX@"  # nts: server name = <PREFIX>.<dhcp-domain>

interface="$1"
action="$2"

case "$action" in
    up|dhcp4-change|reapply) ;;
    *) exit 0 ;;
esac

dir=/run/chrony-dhcp
file="$dir/${interface}.sources"
mkdir -p "$dir"

if [ "$MODE" = nts ]; then
    # Prefer option 15 (domain-name); fall back to the first option-119 search domain.
    domain="${DHCP4_DOMAIN_NAME:-}"
    [ -z "$domain" ] && domain="${DHCP4_DOMAIN_SEARCH%% *}"
    if [ -n "$domain" ]; then
        printf 'server %s.%s iburst nts\n' "$PREFIX" "$domain" > "$file"
        # Pick up the new source without restarting chronyd.
        chronyc reload sources >/dev/null 2>&1 || true
    fi
else
    if [ -n "${DHCP4_NTP_SERVERS:-}" ]; then
        : > "$file"
        for s in $DHCP4_NTP_SERVERS; do
            printf 'server %s iburst\n' "$s" >> "$file"
        done
        chronyc reload sources >/dev/null 2>&1 || true
    fi
fi

exit 0
