#!/bin/bash
set -euo pipefail

# Convertisseur de configuration strongSwan pour ARV / Sphynx.
#
# ARV génère historiquement une configuration au format ipsec.conf,
# ipsec.secrets et /etc/ipsec.d/*. Ce format était chargé par
# strongswan-starter via les commandes :
#
#   ipsec rereadall
#   ipsec update
#
# En strongSwan 6 avec charon-systemd, strongswan-starter et la commande
# ipsec ne sont plus utilisés. Le service strongswan charge désormais sa
# configuration via swanctl.
#
# Ce script sert donc de couche de compatibilité temporaire :
#
#   1. conserver la génération ARV existante au format ipsec.conf ;
#   2. recopier les certificats/clefs vers l’arborescence attendue par swanctl ;
#   3. aplatir les include de /etc/ipsec.conf, car ipsec2swanctl ne les traite
#      pas correctement dans le cas ARV ;
#   4. convertir la configuration legacy avec ipsec2swanctl.py ;
#   5. corriger la valeur version=ike générée par le convertisseur ;
#   6. charger la configuration finale avec swanctl --load-all --noprompt.
#
# L’objectif est d’éviter une réécriture complète immédiate du générateur ARV,
# tout en permettant à Sphynx 2.11 d’utiliser le modèle strongSwan 6/swanctl.

EXPANDED_CONF="/run/eole-ipsec-expanded.conf"
SWANCTL_CONF="/etc/swanctl/conf.d/eole-arv.conf"
CONVERTER="/usr/lib/python3/dist-packages/arv/lib/ipsec2swanctl.py"

mkdir -p /etc/swanctl/conf.d \
         /etc/swanctl/x509 \
         /etc/swanctl/x509ca \
         /etc/swanctl/private \
         /etc/swanctl/x509crl

# Copie les magasins historiques strongSwan vers les répertoires utilisés
# par swanctl.
#
# /etc/ipsec.d/certs    -> certificats machine
# /etc/ipsec.d/cacerts  -> certificats d'autorités
# /etc/ipsec.d/private  -> clefs privées
# /etc/ipsec.d/crls     -> listes de révocation
#
# Les copies sont tolérantes : tous les dossiers ne sont pas forcément
# présents selon l’état de la configuration ARV.
cp -af /etc/ipsec.d/certs/.    /etc/swanctl/x509/    2>/dev/null || true
cp -af /etc/ipsec.d/cacerts/.  /etc/swanctl/x509ca/  2>/dev/null || true
cp -af /etc/ipsec.d/private/.  /etc/swanctl/private/ 2>/dev/null || true
cp -af /etc/ipsec.d/crls/.     /etc/swanctl/x509crl/ 2>/dev/null || true

# Génère les fichiers include par défaut utilisés par ipsec2swanctl.
#
# Le convertisseur crée notamment :
#   /etc/swanctl/conf.d/ike_sa_default.conf
#   /etc/swanctl/conf.d/child_sa_default.conf
#
# Ces fichiers sont ensuite inclus dans les connexions converties.
python3 "$CONVERTER" \
  --sysconfdir /etc \
  -o /tmp/eole-empty-swanctl.conf \
  -w >/dev/null

# Correction du convertisseur.
#
# ARV utilise keyexchange=ike dans ipsec.conf. ipsec2swanctl le convertit en :
#
#   version=ike
#
# Or swanctl attend une valeur numérique :
#
#   0 = IKEv1/IKEv2
#   1 = IKEv1
#   2 = IKEv2
#
# La valeur équivalente à keyexchange=ike est donc version=0.
sed -i 's/^version=ike$/version=0/' /etc/swanctl/conf.d/ike_sa_default.conf

# Aplatit les include de /etc/ipsec.conf.
#
# ARV génère un fichier principal qui contient généralement :
#
#   include /etc/ipsec.d/conf/*
#
# Le convertisseur ne développe pas correctement ces include dans notre cas.
# On produit donc un fichier temporaire complet dans /run avant conversion.
python3 - <<'PY'
from pathlib import Path
import glob

src = Path("/etc/ipsec.conf")
dst = Path("/run/eole-ipsec-expanded.conf")

out = []
for line in src.read_text().splitlines():
    stripped = line.strip()
    if stripped.startswith("include "):
        pattern = stripped.split(None, 1)[1]
        for fname in sorted(glob.glob(pattern)):
            out.append(f"\n# BEGIN include {fname}")
            out.append(Path(fname).read_text())
            out.append(f"# END include {fname}\n")
    else:
        out.append(line)

dst.write_text("\n".join(out) + "\n")
PY

# Convertit la configuration réellement utilisée par ARV vers swanctl.conf.
python3 "$CONVERTER" \
  --ipsecconf "$EXPANDED_CONF" \
  -o "$SWANCTL_CONF" \
  -w

# Charge la configuration swanctl, les certificats, les clefs et les secrets.
#
# --noprompt évite toute question interactive lors d’un reconfigure,
# d’un posttemplate ou d’un appel ARV automatisé.
swanctl --load-all --noprompt