#!/bin/sh
# Blackbox: build the cloud-init seed from the MEASURED command line instead of
# a host-written seed ISO. A seed ISO is a file the host can rewrite at any
# time, and it carries the SSH key that becomes root; the command line is part
# of the launch measurement, so a host that changes it changes the number the
# customer checks.
PREREQ=""
prereqs() { echo "$PREREQ"; }
case "$1" in prereqs) prereqs; exit 0 ;; esac
. /scripts/functions

D=/run/blackbox/seed
mkdir -p "$D"
chmod 700 /run/blackbox
KEY=""; IID="measured"; HOST="blackbox"; IP4=""; GW4=""; IP6=""; GW6=""; DNS=""
for x in $(cat /proc/cmdline); do
    case "$x" in
        bb.key=*)  KEY=$(printf '%s' "${x#bb.key=}" | base64 -d 2>/dev/null | head -1) ;;
        bb.iid=*)  IID="${x#bb.iid=}" ;;
        bb.host=*) HOST="${x#bb.host=}" ;;
        bb.ip4=*)  IP4="${x#bb.ip4=}" ;;
        bb.gw4=*)  GW4="${x#bb.gw4=}" ;;
        bb.ip6=*)  IP6="${x#bb.ip6=}" ;;
        bb.gw6=*)  GW6="${x#bb.gw6=}" ;;
        bb.dns=*)  DNS="${x#bb.dns=}" ;;
    esac
done
MAC=$(cat /sys/class/net/ens18/address 2>/dev/null || echo "")

printf 'instance-id: %s\nlocal-hostname: %s\n' "$IID" "$HOST" > "$D/meta-data"

{
    echo "#cloud-config"
    echo "hostname: $HOST"
    echo "manage_etc_hosts: true"
    echo "package_upgrade: false"
    echo "package_update: false"
    echo "disable_root: false"
    echo "ssh_pwauth: false"
    if [ -n "$KEY" ]; then
        echo "ssh_authorized_keys:"
        echo "  - \"$KEY\""
    fi
    echo "users:"
    echo "  - name: root"
    echo "    lock_passwd: true"
    if [ -n "$KEY" ]; then
        echo "    ssh_authorized_keys:"
        echo "      - \"$KEY\""
    fi
} > "$D/user-data"

{
    echo "version: 2"
    echo "ethernets:"
    echo "  nic0:"
    if [ -n "$MAC" ]; then
        echo "    match:"
        echo "      macaddress: $MAC"
    else
        echo "    match:"
        echo "      name: ens18"
    fi
    echo "    dhcp4: false"
    echo "    dhcp6: false"
    echo "    addresses:"
    [ -n "$IP4" ] && echo "      - $IP4"
    [ -n "$IP6" ] && echo "      - $IP6"
    echo "    routes:"
    if [ -n "$GW4" ]; then
        echo "      - to: 0.0.0.0/0"
        echo "        via: $GW4"
        echo "        on-link: true"
    fi
    if [ -n "$GW6" ]; then
        echo "      - to: \"::/0\""
        echo "        via: \"$GW6\""
        echo "        on-link: true"
    fi
    if [ -n "$DNS" ]; then
        echo "    nameservers:"
        echo "      addresses: [$(printf '%s' "$DNS" | sed 's/,/, /g')]"
    fi
} > "$D/network-config"
chmod 600 "$D"/*
cp /run/bb/attest.json /run/blackbox/attest.json 2>/dev/null || true
cp /run/bb/report.bin /run/blackbox/report.bin 2>/dev/null || true

# klibc's ipconfig leaves /run/net-ens18.conf behind, and cloud-init ranks
# that "initramfs network config" above the datasource's own network-config:
# the guest would end up with the IPv4 address only, no IPv6, no nameservers.
# /run moves into the real root, so remove them here.
rm -f /run/net-*.conf /run/net6-*.conf 2>/dev/null || true

# Hand the interface to the real system clean. The ip= configuration this
# initramfs applied would otherwise still be on ens18 when ifupdown or netplan
# tries to add the same address, and "file exists" aborts the interface before
# the IPv6 address and routes are ever added.
if command -v ip >/dev/null 2>&1; then
    ip -4 addr flush dev ens18 2>/dev/null || true
    ip -4 route flush dev ens18 2>/dev/null || true
    ip link set ens18 down 2>/dev/null || true
elif command -v ifconfig >/dev/null 2>&1; then
    ifconfig ens18 0.0.0.0 down 2>/dev/null || true
fi
