Files
nixos-workstations/modules/yubikey-first-login.nix
T

180 lines
5.3 KiB
Nix

{ pkgs, ... }:
let
# ------------------------------------------------------------
# Assistant interactif de changement du PIN
# ------------------------------------------------------------
yubikeyPinChange = pkgs.writeShellScript "yubikey-pin-change" ''
set -u
state_dir="$HOME/.local/state/nixos-workstations"
marker="$state_dir/yubikey-pin-initialized"
# 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 "Vous devez modifier le PIN temporaire de votre YubiKey."
echo
echo "Cette opération est obligatoire."
echo
echo
echo "Vous allez devoir saisir :"
echo
echo " 1. votre PIN temporaire actuel ;"
echo " 2. votre nouveau PIN personnel ;"
echo " 3. une seconde fois votre nouveau PIN."
echo
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 A ÉTÉ MODIFIÉ AVEC SUCCÈS"
echo "============================================================"
echo
echo "Vous pouvez maintenant utiliser votre nouveau PIN"
echo "pour vos prochaines connexions."
echo
echo "Cette fenêtre va se fermer automatiquement."
echo
${pkgs.coreutils}/bin/sleep 5
exit 0
else
echo
echo "============================================================"
echo " ÉCHEC DU CHANGEMENT DU PIN"
echo "============================================================"
echo
echo "Votre session va être fermée."
echo
echo "La procédure sera automatiquement reproposée"
echo "à votre prochaine connexion."
echo
${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 à l'ouverture de la session KDE
# ------------------------------------------------------------
environment.etc."xdg/autostart/yubikey-first-login.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Initialisation YubiKey
Comment=Initialisation obligatoire du PIN personnel de la YubiKey
Exec=${yubikeyFirstLoginSupervisor}
OnlyShowIn=KDE;
NoDisplay=true
StartupNotify=false
'';
}