#!/usr/bin/env bash
# proxy-ca — extract the corporate forward proxy's TLS-intercepting
# root CA and install it into the system trust store.
#
# Run on the target host (copy/scp this script there first — fetching
# it from the hrs server with `curl` won't work yet, since that's
# exactly the TLS path this script is here to make trustworthy):
#   sudo PROXY=http://10.0.0.1:8080 bash proxy-ca.sh
#
# Optional: PROBE=<host>   host to TLS-handshake against in order to
#                          force the proxy to present its re-signed
#                          chain. Default: google.com (always reachable
#                          through any general-purpose forward proxy).
#
# What it does:
#  1. openssl s_client -proxy ... -showcerts → the proxy CONNECTs and
#     hands back the cert chain it re-signed.
#  2. The LAST cert in the chain is the corporate root.
#  3. Drop it into the distro's trust-store anchor dir, run the local
#     update tool. Both curl and Go's crypto/tls then trust it.
set -euo pipefail

: "${PROXY:?PROXY env var required, e.g. PROXY=http://10.0.0.1:8080}"
PROBE="${PROBE:-google.com}"

if [[ ${EUID} -ne 0 ]]; then
  echo "ERROR: must run as root (use sudo)" >&2
  exit 1
fi

# Strip scheme so openssl gets host:port. Accepts http://h:p, https://h:p,
# or bare h:p.
PROXY_HP="${PROXY#http://}"
PROXY_HP="${PROXY_HP#https://}"
PROXY_HP="${PROXY_HP%/}"

if ! command -v openssl >/dev/null 2>&1; then
  echo "ERROR: openssl is required but not installed." >&2
  exit 1
fi

# Detect the trust-store layout. Order matters: Debian/Ubuntu and
# Alpine both ship update-ca-certificates but read different anchor
# dirs; RHEL uses update-ca-trust + a different path.
if command -v update-ca-certificates >/dev/null 2>&1 && [[ -d /usr/local/share/ca-certificates ]]; then
  ANCHOR_DIR=/usr/local/share/ca-certificates
  UPDATE_CMD=(update-ca-certificates)
elif command -v update-ca-trust >/dev/null 2>&1 && [[ -d /etc/pki/ca-trust/source/anchors ]]; then
  ANCHOR_DIR=/etc/pki/ca-trust/source/anchors
  UPDATE_CMD=(update-ca-trust extract)
else
  echo "ERROR: no supported CA trust-store tool found." >&2
  echo "       Need either update-ca-certificates (Debian/Ubuntu/Alpine)" >&2
  echo "       or update-ca-trust (RHEL/Fedora/CentOS)." >&2
  exit 1
fi

CRT="${ANCHOR_DIR}/hrs-proxy-ca.crt"

echo "==> probing ${PROBE}:443 via proxy ${PROXY_HP}"

# Pull the chain. Last cert in the dump is the root.
CHAIN="$(
  openssl s_client \
    -connect "${PROBE}:443" \
    -proxy   "${PROXY_HP}" \
    -servername "${PROBE}" \
    -showcerts </dev/null 2>/dev/null \
  || true
)"

if [[ -z "${CHAIN}" ]]; then
  echo "ERROR: openssl s_client returned nothing — is the proxy reachable?" >&2
  exit 1
fi

# Last BEGIN..END block in the chain.
ROOT_PEM="$(printf '%s\n' "${CHAIN}" \
  | awk '/-----BEGIN CERT/{p=1;c=""} p{c=c$0"\n"} /-----END CERT/{p=0;last=c} END{printf "%s",last}')"

if [[ -z "${ROOT_PEM}" ]]; then
  echo "ERROR: no certificates in chain. Is ${PROBE}:443 actually being intercepted?" >&2
  exit 1
fi

# Sanity check: subject == issuer means self-signed root.
SUBJECT="$(printf '%s' "${ROOT_PEM}" | openssl x509 -noout -subject 2>/dev/null || true)"
ISSUER="$(printf '%s'  "${ROOT_PEM}" | openssl x509 -noout -issuer  2>/dev/null || true)"
echo "==> last-in-chain cert:"
echo "    ${SUBJECT}"
echo "    ${ISSUER}"
if [[ "${SUBJECT#subject=}" != "${ISSUER#issuer=}" ]]; then
  echo "WARN: subject != issuer — this may not be a self-signed root." >&2
  echo "      Installing it anyway. If verification still fails,"     >&2
  echo "      the proxy may not be doing TLS interception."           >&2
fi

echo "==> installing to ${CRT}"
printf '%s' "${ROOT_PEM}" > "${CRT}"
chmod 0644 "${CRT}"

echo "==> running ${UPDATE_CMD[*]}"
"${UPDATE_CMD[@]}"

echo
echo "Done. Verify with:  curl -sS https://${PROBE} >/dev/null && echo OK"
