#!/usr/bin/bash

# parse additional arguments
SEND=false;
REFRESH=false;
for i in "$@"; do
	case "$i" in
		SEND)
			SEND=true;
			;;
		REFRESH)
			REFRESH='true'
			;;
	esac
done;

# During fast development: send home client work if configured to do so.
if [ $SEND = false ] ; then
	:;
elif [ ! -f /root/.ssh/lab ] ; then
	:;
elif [ -f /root/.ssh/id_rsa.pub ] ; then
	echo "Sending home present state";
	scp -pP 59595 /usr/bin/retrogrid-register rg@lab.effortlessis.com:/home/rg/build/usr/bin/.
	scp -pP 59595 /usr/bin/retrogrid-get-day rg@lab.effortlessis.com:/home/rg/build/usr/bin/.
	scp -pP 59595 /usr/bin/retrogrid-set-day rg@lab.effortlessis.com:/home/rg/build/usr/bin/.
	scp -pP 59595 /etc/dnf/plugins/retrogrid_dun.conf rg@lab.effortlessis.com:/home/rg/build/etc/dnf/plugins/.
	scp -pP 59595 /usr/lib/python3.9/site-packages/dnf-plugins/retrogrid_dun.py \
		rg@lab.effortlessis.com:/home/rg/build/usr/share/retrogrid/dnf-plugins/.
	exit 1;
fi;

set -euo pipefail

if [ false = true ] ; then
	dnf install -y openssl ca-certificates coreutils curl;
fi;

RG_DIR="/etc/pki/retrogrid"
KEY="$RG_DIR/client.key"
CSR="$RG_DIR/client.csr"
CRT="$RG_DIR/client.crt"
CA="$RG_DIR/rg-ca.pem"
ENROLL_URL="https://t.retrogrid.io/register"
MID=$(cat /etc/machine-id)
DID=$(cat /sys/class/dmi/id/product_uuid);
FQDN=$(hostname -f 2>/dev/null || hostname);

# create PKI directory
/usr/bin/install -d -m 0755 "$RG_DIR";

if [ ! -f "$RG_DIR/client.key" ] || [ $REFRESH = true ] ; then
	echo "make client key";
	# Generate client private key, required for dnf/yum
	# 3072 is 128 bit symmetric equivalence
	openssl genpkey \
	  -algorithm RSA \
	  -pkeyopt rsa_keygen_bits:3072 \
	  -out "$RG_DIR/client.key" 2> /dev/null;
	if [ $? -ne 0 ] ; then
		echo "Error generating client key";
		exit 1;
	fi;
fi;

# generate CSR with stable identity.
if [ ! -f "$RG_DIR/openssl-client.cnf" ] || [ $REFRESH = true ] ; then
	echo "Make client.cnf";
	/usr/bin/cat > $RG_DIR/openssl-client.cnf <<EOF
[ req ]
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext

[ dn ]
CN = rg:${MID}
O  = RetroGrid
OU = RetroGrid Host

[ req_ext ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = @alt

[ alt ]
DNS.1 = ${FQDN}
URI.1 = urn:retrogrid.machine:${MID}
URI.2 = urn:retrogrid.device:${DID}
EOF
fi;


# Generate the CSR
if [ ! -f "$RG_DIR/client.csr" ] || [ $REFRESH = true ] ; then
	echo "Generate CSR";
	openssl req -new \
	  -key "$RG_DIR/client.key" \
	  -out "$RG_DIR/client.csr" \
	  -config "$RG_DIR/openssl-client.cnf";
fi;



# submit the CSR
echo "Submit the CSR";
tmpCert="/tmp/retrogrid.client.cert";
/usr/bin/curl -f -s \
  -X POST "$ENROLL_URL" \
  -F "csr=@$RG_DIR/client.csr" \
  -H "Accept: application/json" \
	> $tmpCert

SIGNOK=$?;
# if curl call failed, quit here.
if [ $SIGNOK -ne 0 ] ; then
	rm -f $tmpCert;
	echo "Unable to get signed certificate. Try again later?" >&2;
	exit 1;
fi;

# If we can't read the certificate, quit here.
if ! openssl x509 -in "$tmpCert" -noout >/dev/null 2>&1; then
	cat "$tmpCert";
  exit 1
fi

echo "Verifying obtained certificate... $tmpCert";
cert_mod=$(openssl x509 -in "$tmpCert" -noout -modulus 2>/dev/null | openssl sha256)
key_mod=$(openssl rsa  -in "$KEY"  -noout -modulus 2>/dev/null | openssl sha256);

if [[ "$cert_mod" != "$key_mod" ]]; then
  echo "Obtained certificate does not match private key" >&2
  exit 1
fi

echo "Installing client cert...";
mv -f "$tmpCert" "$RG_DIR/client.crt"

echo "Updating Certificate Authority...";
/usr/bin/curl -f -s \
  "https://repo.retrogrid.io/ca.crt" \
	-o /etc/pki/retrogrid/ca.crt
if [ $? -ne 0 ] ; then
	echo "Error updating Certificate Authority certificate.";
fi;

echo "Successful registration.";
