diff --git a/modules/yubikey-first-login.nix b/modules/yubikey-first-login.nix deleted file mode 100644 index a5061fd..0000000 --- a/modules/yubikey-first-login.nix +++ /dev/null @@ -1,567 +0,0 @@ -{ pkgs, ... }: - -let - # ============================================================ - # Assistant interactif de première connexion - # - # Étape 1 : changement du mot de passe local - # Étape 2 : changement du PIN YubiKey - # ============================================================ - - firstLoginSetup = pkgs.writeShellScript "first-login-setup" '' - set -u - - state_dir="$HOME/.local/state/nixos-workstations" - - password_marker="$state_dir/password-initialized" - yubikey_marker="$state_dir/yubikey-pin-initialized" - - runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" - active_file="$runtime_dir/nixos-workstations-first-login.active" - - # ---------------------------------------------------------- - # Permet au superviseur de savoir que l'assistant tourne. - # ---------------------------------------------------------- - - printf '%s\n' "$$" > "$active_file" - - cleanup() { - ${pkgs.coreutils}/bin/rm -f "$active_file" - } - - trap cleanup EXIT HUP INT TERM - - # ---------------------------------------------------------- - # 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" - } - - clear_screen() { - printf "\033[2J\033[H" - } - - header() { - clear_screen - - echo - separator - echo - - printf " ''${BOLD}''${CYAN}🔐 CONFIGURATION DE VOTRE COMPTE''${RESET}\n" - - echo - separator - echo - } - - # ========================================================== - # ÉTAPE 1 : MOT DE PASSE LOCAL - # ========================================================== - - if [ ! -e "$password_marker" ]; then - - header - - printf " ''${BOLD}''${CYAN}ÉTAPE 1 SUR 2''${RESET}\n" - echo - - printf " ''${BOLD}''${WHITE}Personnalisation du mot de passe de secours''${RESET}\n" - echo - - printf " Votre compte possède actuellement un mot de passe temporaire.\n" - printf " Vous devez maintenant le remplacer par votre mot de passe\n" - printf " personnel.\n" - - echo - separator - echo - - printf " ''${CYAN}①''${RESET} Saisissez votre mot de passe temporaire actuel.\n" - echo - - printf " ''${CYAN}②''${RESET} Choisissez votre nouveau mot de passe personnel.\n" - echo - - printf " ''${CYAN}③''${RESET} Confirmez votre nouveau mot de passe.\n" - - echo - separator - echo - - printf " ''${GREY}Ce mot de passe reste local au poste.''${RESET}\n" - printf " ''${GREY}Il pourra être utilisé comme solution de secours si votre''${RESET}\n" - printf " ''${GREY}YubiKey est indisponible.''${RESET}\n" - - echo - separator - echo - - printf " ''${BOLD}''${YELLOW}Veuillez maintenant suivre les instructions ci-dessous.''${RESET}\n" - echo - - # -------------------------------------------------------- - # IMPORTANT NixOS - # - # On utilise volontairement le wrapper SUID NixOS. - # - # NE PAS remplacer par : - # ${pkgs.shadow}/bin/passwd - # -------------------------------------------------------- - - if /run/wrappers/bin/passwd; then - - # Le marqueur est créé immédiatement après le succès - # confirmé par passwd. - ${pkgs.coreutils}/bin/mkdir -p "$state_dir" - ${pkgs.coreutils}/bin/touch "$password_marker" - - echo - separator - echo - - printf " ''${BOLD}''${GREEN}✓ MOT DE PASSE MODIFIÉ AVEC SUCCÈS''${RESET}\n" - - echo - printf " Votre nouveau mot de passe personnel est maintenant actif.\n" - - echo - separator - echo - - ${pkgs.coreutils}/bin/sleep 3 - - else - - echo - separator - echo - - printf " ''${BOLD}''${RED}✗ LE MOT DE PASSE N'A PAS ÉTÉ MODIFIÉ''${RESET}\n" - - echo - printf " L'opération a été annulée ou a échoué.\n" - printf " Cette étape sera automatiquement reproposée.\n" - - echo - separator - echo - - ${pkgs.coreutils}/bin/sleep 3 - - exit 1 - fi - - fi - - # ========================================================== - # ÉTAPE 2 : PIN YUBIKEY - # ========================================================== - - if [ ! -e "$yubikey_marker" ]; then - - header - - printf " ''${BOLD}''${CYAN}ÉTAPE 2 SUR 2''${RESET}\n" - echo - - printf " ''${BOLD}''${WHITE}Personnalisation du PIN de votre YubiKey''${RESET}\n" - echo - - printf " Votre YubiKey possède actuellement le PIN temporaire\n" - printf " fourni lors de la préparation du poste.\n" - - echo - separator - echo - - printf " ''${CYAN}①''${RESET} Saisissez votre PIN temporaire actuel.\n" - echo - - printf " ''${CYAN}②''${RESET} Choisissez votre nouveau PIN personnel.\n" - echo - - printf " ''${CYAN}③''${RESET} Confirmez votre nouveau PIN.\n" - - echo - separator - echo - - printf " ''${GREY}Votre PIN est enregistré directement dans la YubiKey.''${RESET}\n" - printf " ''${GREY}Il n'est ni enregistré sur ce poste, ni dans Git.''${RESET}\n" - printf " ''${GREY}Le service informatique ne connaît pas votre nouveau PIN.''${RESET}\n" - - echo - separator - echo - - printf " ''${BOLD}''${YELLOW}⚠ ATTENTION AU PAVÉ NUMÉRIQUE''${RESET}\n" - echo - - printf " Vérifiez que ''${BOLD}Verr Num''${RESET} est activé avant de saisir votre PIN.\n" - printf " En cas de doute, utilisez les chiffres situés au-dessus\n" - printf " des lettres du clavier.\n" - - echo - separator - echo - - printf " ''${BOLD}''${YELLOW}Veuillez maintenant suivre les instructions ci-dessous.''${RESET}\n" - echo - - if ${pkgs.yubikey-manager}/bin/ykman fido access change-pin; then - - # Le marqueur est créé immédiatement après que ykman - # confirme réellement le changement du PIN. - ${pkgs.coreutils}/bin/mkdir -p "$state_dir" - ${pkgs.coreutils}/bin/touch "$yubikey_marker" - - echo - separator - echo - - printf " ''${BOLD}''${GREEN}✓ PIN YUBIKEY MODIFIÉ AVEC SUCCÈS''${RESET}\n" - - echo - printf " Votre nouveau PIN personnel est maintenant actif.\n" - - echo - separator - echo - - ${pkgs.coreutils}/bin/sleep 3 - - else - - echo - separator - echo - - printf " ''${BOLD}''${RED}✗ LE PIN N'A PAS ÉTÉ MODIFIÉ''${RESET}\n" - - echo - printf " L'opération a été annulée ou a échoué.\n" - echo - - if [ -e "$password_marker" ]; then - printf " ''${GREEN}✓ Votre nouveau mot de passe est déjà enregistré.''${RESET}\n" - printf " Il ne vous sera pas demandé de le modifier à nouveau.\n" - echo - fi - - printf " Seule la configuration du PIN sera reproposée.\n" - - echo - separator - echo - - ${pkgs.coreutils}/bin/sleep 3 - - exit 1 - fi - - fi - - # ========================================================== - # CONFIGURATION TERMINÉE - # ========================================================== - - header - - printf " ''${BOLD}''${GREEN}✓ VOTRE POSTE EST PRÊT''${RESET}\n" - - echo - separator - echo - - printf " La configuration initiale de votre compte est terminée.\n" - - echo - printf " ''${GREEN}✓''${RESET} Mot de passe personnel configuré\n" - printf " ''${GREEN}✓''${RESET} PIN personnel YubiKey configuré\n" - - echo - separator - echo - - printf " ''${BOLD}Pour vos prochaines connexions :''${RESET}\n" - - echo - printf " ''${BOLD}YubiKey + PIN personnel''${RESET}\n" - - echo - printf " Votre mot de passe local reste disponible comme solution\n" - printf " de secours si votre YubiKey est indisponible.\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 - ''; - - # ============================================================ - # Superviseur - # - # Son rôle : - # - lancer l'assistant ; - # - le relancer s'il est fermé avant la fin ; - # - NE JAMAIS tuer KDE ou la session. - # ============================================================ - - firstLoginSupervisor = - pkgs.writeShellScript "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" - - password_marker="$state_dir/password-initialized" - yubikey_marker="$state_dir/yubikey-pin-initialized" - - runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}" - - active_file="$runtime_dir/nixos-workstations-first-login.active" - supervisor_lock="$runtime_dir/nixos-workstations-first-login.lock" - - KDIALOG="${pkgs.kdePackages.kdialog}/bin/kdialog" - KONSOLE="${pkgs.kdePackages.konsole}/bin/konsole" - - # -------------------------------------------------------- - # Empêche deux superviseurs de fonctionner simultanément. - # -------------------------------------------------------- - - exec 9>"$supervisor_lock" - - if ! ${pkgs.util-linux}/bin/flock -n 9; then - exit 0 - fi - - # -------------------------------------------------------- - # Tout est déjà configuré. - # -------------------------------------------------------- - - if [ -e "$password_marker" ] && [ -e "$yubikey_marker" ]; then - exit 0 - fi - - # Laisse Plasma finir son démarrage. - ${pkgs.coreutils}/bin/sleep 4 - - # ======================================================== - # Boucle de provisioning - # ======================================================== - - while \ - [ ! -e "$password_marker" ] || \ - [ ! -e "$yubikey_marker" ] - do - - # ------------------------------------------------------ - # Présentation KDE - # ------------------------------------------------------ - - "$KDIALOG" \ - --title "Finalisation de votre poste" \ - --warningcontinuecancel \ - "Bienvenue Alice. - -Votre poste est presque prêt. - -Pour terminer sa configuration, vous devez personnaliser vos deux moyens d'authentification : - - 🔑 Votre mot de passe local de secours - - 🔐 Le PIN de votre YubiKey - -Les nouveaux secrets que vous choisirez sont personnels. - -Ils ne sont ni enregistrés dans Git, ni communiqués au service informatique. - -Cette opération ne doit être effectuée qu'une seule fois." - - dialog_result=$? - - # ------------------------------------------------------ - # Alice ferme la fenêtre d'accueil. - # - # On ne touche PAS à KDE. - # L'assistant sera simplement reproposé. - # ------------------------------------------------------ - - if [ "$dialog_result" -ne 0 ]; then - - "$KDIALOG" \ - --title "Configuration requise" \ - --sorry \ - "La configuration initiale de votre compte n'est pas terminée. - -Cette étape est obligatoire. - -L'assistant va être reproposé." - - ${pkgs.coreutils}/bin/sleep 1 - - continue - fi - - # ------------------------------------------------------ - # Supprime un éventuel fichier actif devenu obsolète. - # ------------------------------------------------------ - - if [ -s "$active_file" ]; then - - assistant_pid="$( - ${pkgs.coreutils}/bin/cat "$active_file" 2>/dev/null || true - )" - - if [ -n "$assistant_pid" ]; then - - if ! ${pkgs.coreutils}/bin/kill -0 "$assistant_pid" 2>/dev/null; then - ${pkgs.coreutils}/bin/rm -f "$active_file" - fi - - else - ${pkgs.coreutils}/bin/rm -f "$active_file" - fi - - fi - - # ------------------------------------------------------ - # Lance l'assistant. - # ------------------------------------------------------ - - "$KONSOLE" \ - --separate \ - --fullscreen \ - --hide-menubar \ - --hide-tabbar \ - -e ${firstLoginSetup} \ - >/dev/null 2>&1 & - - # Laisse au script le temps d'écrire active_file. - ${pkgs.coreutils}/bin/sleep 2 - - # ====================================================== - # Attend la fin réelle de l'assistant - # ====================================================== - - while true; do - - # Les deux opérations sont terminées. - if [ -e "$password_marker" ] && [ -e "$yubikey_marker" ]; then - break - fi - - # Le script n'est plus déclaré actif. - if [ ! -s "$active_file" ]; then - break - fi - - assistant_pid="$( - ${pkgs.coreutils}/bin/cat "$active_file" 2>/dev/null || true - )" - - if [ -z "$assistant_pid" ]; then - break - fi - - # Le script a disparu. - if ! ${pkgs.coreutils}/bin/kill -0 "$assistant_pid" 2>/dev/null; then - - ${pkgs.coreutils}/bin/rm -f "$active_file" - - break - fi - - ${pkgs.coreutils}/bin/sleep 1 - - done - - # ====================================================== - # Tout est terminé - # ====================================================== - - if [ -e "$password_marker" ] && [ -e "$yubikey_marker" ]; then - - "$KDIALOG" \ - --title "Poste configuré" \ - --msgbox \ - "✓ Votre poste est prêt. - -Votre mot de passe personnel et le PIN de votre YubiKey ont été configurés. - -Pour vos prochaines connexions, utilisez : - - YubiKey + votre PIN personnel - -Votre mot de passe local reste disponible comme solution de secours." - - exit 0 - fi - - # ====================================================== - # Configuration partielle / fenêtre fermée / erreur - # ====================================================== - - "$KDIALOG" \ - --title "Configuration incomplète" \ - --sorry \ - "La configuration initiale n'est pas entièrement terminée. - -Les étapes déjà réalisées sont conservées. - -L'assistant va reprendre uniquement les étapes restantes." - - ${pkgs.coreutils}/bin/sleep 1 - - done - - exit 0 - ''; - -in -{ - # ============================================================ - # Lancement automatique lors de l'ouverture de session KDE - # ============================================================ - - environment.etc."xdg/autostart/yubikey-first-login.desktop".text = '' - [Desktop Entry] - Type=Application - Name=Finalisation du poste - Comment=Configuration initiale du compte utilisateur - Exec=${firstLoginSupervisor} - OnlyShowIn=KDE; - NoDisplay=true - StartupNotify=false - ''; -} \ No newline at end of file