diff --git a/modules/yubikey-first-login.nix b/modules/yubikey-first-login.nix index fe96358..d168e3a 100644 --- a/modules/yubikey-first-login.nix +++ b/modules/yubikey-first-login.nix @@ -1,91 +1,178 @@ { pkgs, ... }: let - yubikeyFirstLogin = pkgs.writeShellScript "yubikey-first-login" '' - #!/usr/bin/env bash + # ------------------------------------------------------------ + # Assistant interactif de changement du PIN + # ------------------------------------------------------------ + yubikeyPinChange = pkgs.writeShellScript "yubikey-pin-change" '' set -u - # Ce mécanisme concerne uniquement Alice. - current_user="$(${pkgs.coreutils}/bin/id -un)" - - if [ "$current_user" != "alice" ]; then - exit 0 - fi - - # Marqueur indiquant que le changement initial du PIN - # a déjà été effectué avec succès. state_dir="$HOME/.local/state/nixos-workstations" marker="$state_dir/yubikey-pin-initialized" - # Si Alice a déjà effectué l'initialisation, - # il n'y a plus rien à faire. + # Si l'initialisation a déjà été effectuée, rien à faire. if [ -e "$marker" ]; then exit 0 fi + clear + echo - echo "======================================================" - echo " INITIALISATION DE VOTRE YUBIKEY" - echo "======================================================" + echo "============================================================" + echo " INITIALISATION DE VOTRE YUBIKEY" + echo "============================================================" echo echo "Vous devez modifier le PIN temporaire de votre YubiKey." echo - echo "Munissez-vous du PIN temporaire qui vous a été communiqué." + echo "Cette opération est obligatoire." + echo echo echo "Vous allez devoir saisir :" echo - echo " 1. le PIN actuel temporaire ;" + echo " 1. votre PIN temporaire actuel ;" echo " 2. votre nouveau PIN personnel ;" - echo " 3. une confirmation de votre nouveau PIN." + echo " 3. une seconde fois votre nouveau PIN." echo - echo "Le nouveau PIN ne sera pas enregistré sur le poste." + echo "IMPORTANT :" + echo "Ne fermez pas cette fenêtre avant la fin de la procédure." + echo + echo "Si cette fenêtre est fermée ou si l'opération échoue," + echo "votre session sera automatiquement fermée." + echo + echo "============================================================" echo if ${pkgs.yubikey-manager}/bin/ykman fido access change-pin; then + # Le marqueur est créé IMMÉDIATEMENT après que ykman + # confirme le changement effectif du PIN. ${pkgs.coreutils}/bin/mkdir -p "$state_dir" ${pkgs.coreutils}/bin/touch "$marker" echo - echo "======================================================" - echo "Le PIN de votre YubiKey a été modifié avec succès." - echo "======================================================" + echo "============================================================" + echo " LE PIN A ÉTÉ MODIFIÉ AVEC SUCCÈS" + echo "============================================================" echo - echo "Cette procédure ne sera plus affichée." + echo "Vous pouvez maintenant utiliser votre nouveau PIN" + echo "pour vos prochaines connexions." + echo + echo "Cette fenêtre va se fermer automatiquement." echo - sleep 5 + ${pkgs.coreutils}/bin/sleep 5 exit 0 else echo - echo "======================================================" - echo "Le changement du PIN n'a pas été effectué." - echo "======================================================" + echo "============================================================" + echo " ÉCHEC DU CHANGEMENT DU PIN" + echo "============================================================" echo - echo "Cette procédure sera reproposée lors de votre" - echo "prochaine ouverture de session." + echo "Votre session va être fermée." + echo + echo "La procédure sera automatiquement reproposée" + echo "à votre prochaine connexion." echo - echo "Appuyez sur Entrée pour fermer cette fenêtre." - read -r + ${pkgs.coreutils}/bin/sleep 3 exit 1 fi ''; + # ------------------------------------------------------------ + # Superviseur + # ------------------------------------------------------------ + # + # Il reste actif indépendamment de Konsole. + # + # Si Konsole disparaît alors que le marqueur n'a pas été créé, + # la session graphique d'Alice est immédiatement terminée. + # + + yubikeyFirstLoginSupervisor = + pkgs.writeShellScript "yubikey-first-login-supervisor" '' + set -u + + current_user="$(${pkgs.coreutils}/bin/id -un)" + + # Ce mécanisme ne concerne pour l'instant qu'Alice. + if [ "$current_user" != "alice" ]; then + exit 0 + fi + + state_dir="$HOME/.local/state/nixos-workstations" + marker="$state_dir/yubikey-pin-initialized" + + # Initialisation déjà terminée. + if [ -e "$marker" ]; then + exit 0 + fi + + # Laisse Plasma terminer son démarrage. + ${pkgs.coreutils}/bin/sleep 3 + + # Lance une instance indépendante de Konsole. + # + # --separate garantit que ce processus Konsole reste attaché + # au superviseur jusqu'à la fermeture de la fenêtre. + # + # Le plein écran rend également impossible une fermeture + # accidentelle via le bouton de décoration de fenêtre. + ${pkgs.kdePackages.konsole}/bin/konsole \ + --separate \ + --fullscreen \ + --hide-menubar \ + --hide-tabbar \ + -e ${yubikeyPinChange} + + # ---------------------------------------------------------- + # Konsole vient de se terminer. + # ---------------------------------------------------------- + + # Le changement du PIN a réussi : + # Alice peut continuer sa session normalement. + if [ -e "$marker" ]; then + exit 0 + fi + + # Sinon : + # - fenêtre fermée volontairement ; + # - Ctrl+C ; + # - ykman en erreur ; + # - changement de PIN abandonné. + # + # Dans tous ces cas, on ferme la session. + + session_id="''${XDG_SESSION_ID:-}" + + if [ -n "$session_id" ]; then + ${pkgs.systemd}/bin/loginctl terminate-session "$session_id" + else + # Secours si XDG_SESSION_ID n'est exceptionnellement + # pas disponible. + ${pkgs.systemd}/bin/loginctl terminate-user "$current_user" + fi + + exit 1 + ''; + in { - # Lancement automatique après ouverture de la session graphique. + # ------------------------------------------------------------ + # Lancement automatique à l'ouverture de la session KDE + # ------------------------------------------------------------ + environment.etc."xdg/autostart/yubikey-first-login.desktop".text = '' [Desktop Entry] Type=Application Name=Initialisation YubiKey - Comment=Initialisation du PIN personnel de la YubiKey - Exec=${pkgs.kdePackages.konsole}/bin/konsole -e ${yubikeyFirstLogin} + Comment=Initialisation obligatoire du PIN personnel de la YubiKey + Exec=${yubikeyFirstLoginSupervisor} OnlyShowIn=KDE; NoDisplay=true StartupNotify=false