{ pkgs, ... }: let # ============================================================ # Assistant interactif de changement du PIN YubiKey # ============================================================ yubikeyPinChange = pkgs.writeShellScript "yubikey-pin-change" '' set -u state_dir="$HOME/.local/state/nixos-workstations" marker="$state_dir/yubikey-pin-initialized" runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" active_file="$runtime_dir/nixos-workstations-yubikey-first-login.active" # ---------------------------------------------------------- # Déclare l'assistant comme actif. # On stocke son PID pour permettre au superviseur # de savoir s'il tourne réellement. # ---------------------------------------------------------- printf '%s\n' "$$" > "$active_file" cleanup() { rm -f "$active_file" } trap cleanup EXIT HUP INT TERM # ---------------------------------------------------------- # Si l'initialisation a déjà été effectuée, rien à faire. # ---------------------------------------------------------- if [ -e "$marker" ]; then exit 0 fi # ---------------------------------------------------------- # Couleurs # ---------------------------------------------------------- RESET="\033[0m" BOLD="\033[1m" BLUE="\033[38;5;39m" CYAN="\033[38;5;45m" GREEN="\033[38;5;82m" YELLOW="\033[38;5;220m" RED="\033[38;5;196m" GREY="\033[38;5;245m" WHITE="\033[38;5;255m" separator() { printf "''${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━''${RESET}\n" } # ---------------------------------------------------------- # Nettoyage de l'écran # ---------------------------------------------------------- printf "\033[2J\033[H" echo separator echo printf " ''${BOLD}''${CYAN}🔐 INITIALISATION DE VOTRE YUBIKEY''${RESET}\n" echo separator echo printf " ''${WHITE}Bienvenue.''${RESET}\n" echo printf " Pour sécuriser votre accès au poste, vous devez maintenant\n" printf " personnaliser le ''${BOLD}PIN de votre YubiKey''${RESET}.\n" echo printf " ''${YELLOW}⚠ Cette opération est obligatoire.''${RESET}\n" echo # ---------------------------------------------------------- # Étapes # ---------------------------------------------------------- printf " ''${BOLD}''${CYAN}[1/3]''${RESET} ''${WHITE}Saisissez votre PIN temporaire.''${RESET}\n" printf " ''${GREY}Il vous a été communiqué avec votre poste.''${RESET}\n" echo printf " ''${BOLD}''${CYAN}[2/3]''${RESET} ''${WHITE}Choisissez votre nouveau PIN personnel.''${RESET}\n" printf " ''${GREY}Ne réutilisez pas le PIN temporaire.''${RESET}\n" echo printf " ''${BOLD}''${CYAN}[3/3]''${RESET} ''${WHITE}Confirmez votre nouveau PIN.''${RESET}\n" echo separator echo printf " ''${GREY}Votre nouveau PIN est enregistré directement dans la YubiKey.''${RESET}\n" printf " ''${GREY}Il n'est pas enregistré dans la configuration du poste.''${RESET}\n" echo separator echo printf " ''${BOLD}''${YELLOW}IMPORTANT''${RESET}\n" echo printf " • Ne fermez pas cette fenêtre pendant l'opération.\n" printf " • Vérifiez l'état de ''${BOLD}Verr Num''${RESET} si vous utilisez le pavé numérique.\n" printf " • En cas de doute, utilisez les chiffres situés au-dessus du clavier.\n" echo separator echo printf " ''${BOLD}''${WHITE}Suivez maintenant les instructions ci-dessous.''${RESET}\n" echo # ---------------------------------------------------------- # Changement du PIN # ---------------------------------------------------------- if ${pkgs.yubikey-manager}/bin/ykman fido access change-pin; then # -------------------------------------------------------- # Succès # # IMPORTANT : # le marqueur est créé immédiatement après le succès # confirmé par ykman. # -------------------------------------------------------- ${pkgs.coreutils}/bin/mkdir -p "$state_dir" ${pkgs.coreutils}/bin/touch "$marker" echo separator echo printf " ''${BOLD}''${GREEN}✔ INITIALISATION TERMINÉE''${RESET}\n" echo separator echo printf " ''${GREEN}Votre nouveau PIN est maintenant actif.''${RESET}\n" echo printf " Utilisez désormais ce nouveau PIN pour vous\n" printf " connecter avec votre YubiKey.\n" echo printf " ''${GREY}Cette procédure ne sera plus affichée.''${RESET}\n" echo separator echo printf " Fermeture automatique" for i in 1 2 3 4 5; do printf "." ${pkgs.coreutils}/bin/sleep 1 done echo exit 0 else # -------------------------------------------------------- # Échec / annulation # # Aucun marqueur n'est créé. # Le superviseur relancera automatiquement l'assistant. # -------------------------------------------------------- echo separator echo printf " ''${BOLD}''${RED}✖ INITIALISATION NON TERMINÉE''${RESET}\n" echo separator echo printf " ''${RED}Le PIN n'a pas été modifié.''${RESET}\n" echo printf " La fenêtre va être fermée puis l'assistant\n" printf " sera automatiquement relancé.\n" echo printf " ''${YELLOW}Vous devez terminer cette procédure''${RESET}\n" printf " ''${YELLOW}pour finaliser l'initialisation de votre YubiKey.''${RESET}\n" echo separator echo ${pkgs.coreutils}/bin/sleep 4 exit 1 fi ''; # ============================================================ # Superviseur de première connexion # ============================================================ yubikeyFirstLoginSupervisor = pkgs.writeShellScript "yubikey-first-login-supervisor" '' set -u current_user="$(${pkgs.coreutils}/bin/id -un)" # -------------------------------------------------------- # Pour le moment, uniquement Alice. # -------------------------------------------------------- if [ "$current_user" != "alice" ]; then exit 0 fi state_dir="$HOME/.local/state/nixos-workstations" marker="$state_dir/yubikey-pin-initialized" runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" active_file="$runtime_dir/nixos-workstations-yubikey-first-login.active" supervisor_lock="$runtime_dir/nixos-workstations-yubikey-first-login.lock" # -------------------------------------------------------- # Une seule instance du superviseur. # -------------------------------------------------------- exec 9>"$supervisor_lock" if ! ${pkgs.util-linux}/bin/flock -n 9; then exit 0 fi # -------------------------------------------------------- # Initialisation déjà terminée. # -------------------------------------------------------- if [ -e "$marker" ]; then exit 0 fi # Laisse Plasma terminer son démarrage. ${pkgs.coreutils}/bin/sleep 4 # -------------------------------------------------------- # Boucle de supervision # -------------------------------------------------------- while [ ! -e "$marker" ]; do assistant_running=0 # ------------------------------------------------------ # Vérifie si l'assistant précédemment lancé tourne # réellement toujours. # ------------------------------------------------------ if [ -s "$active_file" ]; then assistant_pid="$(${pkgs.coreutils}/bin/cat "$active_file" 2>/dev/null || true)" if [ -n "$assistant_pid" ] \ && ${pkgs.coreutils}/bin/kill -0 "$assistant_pid" 2>/dev/null; then assistant_running=1 else # Fichier devenu obsolète. rm -f "$active_file" fi fi # ------------------------------------------------------ # Aucun assistant actif : # on en ouvre un. # ------------------------------------------------------ if [ "$assistant_running" -eq 0 ]; then ${pkgs.kdePackages.konsole}/bin/konsole \ --separate \ --fullscreen \ --hide-menubar \ --hide-tabbar \ -e ${yubikeyPinChange} \ >/dev/null 2>&1 & # Laisse le temps à Konsole et au script de démarrer. ${pkgs.coreutils}/bin/sleep 2 else ${pkgs.coreutils}/bin/sleep 2 fi done # -------------------------------------------------------- # Le marqueur existe : # l'initialisation est terminée. # # On ne touche PAS à la session KDE. # -------------------------------------------------------- exit 0 ''; in { # ============================================================ # Lancement automatique à l'ouverture de KDE # ============================================================ environment.etc."xdg/autostart/yubikey-first-login.desktop".text = '' [Desktop Entry] Type=Application Name=Initialisation de la YubiKey Comment=Configuration obligatoire de votre PIN personnel Exec=${yubikeyFirstLoginSupervisor} OnlyShowIn=KDE; NoDisplay=true StartupNotify=false ''; }