Actualiser modules/yubikey-first-login.nix

This commit is contained in:
2026-08-18 14:12:47 +02:00
parent 0a762d7d22
commit be3d312dca
+174 -123
View File
@@ -11,8 +11,33 @@ let
state_dir="$HOME/.local/state/nixos-workstations" state_dir="$HOME/.local/state/nixos-workstations"
marker="$state_dir/yubikey-pin-initialized" marker="$state_dir/yubikey-pin-initialized"
runtime_dir="''${XDG_RUNTIME_DIR:-/tmp}"
active_file="$runtime_dir/nixos-workstations-yubikey-first-login.active"
# ---------------------------------------------------------- # ----------------------------------------------------------
# Couleurs ANSI # 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" RESET="\033[0m"
@@ -26,15 +51,14 @@ let
GREY="\033[38;5;245m" GREY="\033[38;5;245m"
WHITE="\033[38;5;255m" WHITE="\033[38;5;255m"
# ----------------------------------------------------------
# Fonctions d'affichage
# ----------------------------------------------------------
separator() { separator() {
printf "''${BLUE}''${RESET}\n" printf "''${BLUE}''${RESET}\n"
} }
header() { # ----------------------------------------------------------
# Nettoyage de l'écran
# ----------------------------------------------------------
printf "\033[2J\033[H" printf "\033[2J\033[H"
echo echo
@@ -44,103 +68,54 @@ let
echo echo
separator separator
echo echo
}
step() {
number="$1"
text="$2"
printf " ''${BOLD}''${CYAN}[%s]''${RESET} ''${WHITE}%s''${RESET}\n" \
"$number" "$text"
}
info() {
printf " ''${GREY}%s''${RESET}\n" "$1"
}
success() {
echo
separator
echo
printf " ''${BOLD}''${GREEN} INITIALISATION TERMINÉE''${RESET}\n"
echo
separator
echo
}
failure() {
echo
separator
echo
printf " ''${BOLD}''${RED} INITIALISATION NON TERMINÉE''${RESET}\n"
echo
separator
echo
}
# ----------------------------------------------------------
# Déjà initialisé
# ----------------------------------------------------------
if [ -e "$marker" ]; then
exit 0
fi
# ----------------------------------------------------------
# Annulation / interruption
# ----------------------------------------------------------
trap '
printf "\n\n"
printf "''${RED}Initialisation interrompue.''${RESET}\n"
exit 130
' INT TERM
# ----------------------------------------------------------
# Écran d'accueil
# ----------------------------------------------------------
header
printf " ''${WHITE}Bienvenue.''${RESET}\n" printf " ''${WHITE}Bienvenue.''${RESET}\n"
echo echo
printf " Pour sécuriser votre accès au poste, vous devez personnaliser\n"
printf " le ''${BOLD}PIN de votre YubiKey''${RESET}.\n" printf " Pour sécuriser votre accès au poste, vous devez maintenant\n"
printf " personnaliser le ''${BOLD}PIN de votre YubiKey''${RESET}.\n"
echo echo
printf " ''${YELLOW} Cette opération est obligatoire.''${RESET}\n" printf " ''${YELLOW} Cette opération est obligatoire.''${RESET}\n"
echo echo
step "1/3" "Munissez-vous du PIN temporaire fourni par le service informatique." # ----------------------------------------------------------
# É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 echo
step "2/3" "Choisissez un nouveau PIN personnel." printf " ''${BOLD}''${CYAN}[2/3]''${RESET} ''${WHITE}Choisissez votre nouveau PIN personnel.''${RESET}\n"
info "Ne réutilisez pas le PIN temporaire." printf " ''${GREY}Ne réutilisez pas le PIN temporaire.''${RESET}\n"
echo echo
step "3/3" "Confirmez votre nouveau PIN." printf " ''${BOLD}''${CYAN}[3/3]''${RESET} ''${WHITE}Confirmez votre nouveau PIN.''${RESET}\n"
echo echo
separator separator
echo echo
printf " ''${GREY}Le PIN est enregistré directement dans votre YubiKey.''${RESET}\n" printf " ''${GREY}Votre nouveau PIN est enregistré directement dans la YubiKey.''${RESET}\n"
printf " ''${GREY}Il n'est ni enregistré sur le poste, ni envoyé au service informatique.''${RESET}\n" printf " ''${GREY}Il n'est pas enregistré dans la configuration du poste.''${RESET}\n"
echo echo
separator separator
echo echo
printf " ''${BOLD}''${WHITE}Insérez votre YubiKey et suivez les instructions.''${RESET}\n" printf " ''${BOLD}''${YELLOW}IMPORTANT''${RESET}\n"
echo echo
printf " ''${YELLOW}Ne fermez pas cette fenêtre.''${RESET}\n" 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 echo
separator separator
echo echo
# Petite pause pour que l'utilisateur lise l'écran printf " ''${BOLD}''${WHITE}Suivez maintenant les instructions ci-dessous.''${RESET}\n"
${pkgs.coreutils}/bin/sleep 2 echo
# ---------------------------------------------------------- # ----------------------------------------------------------
# Changement du PIN # Changement du PIN
@@ -148,25 +123,42 @@ let
if ${pkgs.yubikey-manager}/bin/ykman fido access change-pin; then if ${pkgs.yubikey-manager}/bin/ykman fido access change-pin; then
# --------------------------------------------------------
# Succès
#
# IMPORTANT : # IMPORTANT :
# le marqueur n'est créé qu'après retour positif de ykman. # le marqueur est créé immédiatement après le succès
# confirmé par ykman.
# --------------------------------------------------------
${pkgs.coreutils}/bin/mkdir -p "$state_dir" ${pkgs.coreutils}/bin/mkdir -p "$state_dir"
${pkgs.coreutils}/bin/touch "$marker" ${pkgs.coreutils}/bin/touch "$marker"
success echo
separator
echo
printf " ''${BOLD}''${GREEN} INITIALISATION TERMINÉE''${RESET}\n"
echo
separator
echo
printf " ''${GREEN}Votre nouveau PIN est maintenant actif.''${RESET}\n" printf " ''${GREEN}Votre nouveau PIN est maintenant actif.''${RESET}\n"
echo echo
printf " Utilisez désormais ce PIN pour vous connecter\n"
printf " avec votre YubiKey.\n" printf " Utilisez désormais ce nouveau PIN pour vous\n"
printf " connecter avec votre YubiKey.\n"
echo echo
printf " ''${GREY}Cette procédure ne sera plus affichée.''${RESET}\n" printf " ''${GREY}Cette procédure ne sera plus affichée.''${RESET}\n"
echo
echo
separator separator
echo echo
printf " Fermeture automatique" printf " Fermeture automatique"
for i in 1 2 3 4 5; do for i in 1 2 3 4 5; do
printf "." printf "."
${pkgs.coreutils}/bin/sleep 1 ${pkgs.coreutils}/bin/sleep 1
@@ -177,33 +169,45 @@ let
else else
failure # --------------------------------------------------------
# Échec / annulation
#
# Aucun marqueur n'est créé.
# Le superviseur relancera automatiquement l'assistant.
# --------------------------------------------------------
printf " ''${RED}Le PIN de la YubiKey n'a pas été modifié.''${RESET}\n"
echo echo
printf " Votre session va être fermée afin de protéger\n"
printf " l'accès au poste.\n"
echo
printf " ''${YELLOW}La procédure sera automatiquement reproposée''${RESET}\n"
printf " ''${YELLOW}à votre prochaine connexion.''${RESET}\n"
echo
separator separator
echo echo
printf " Fermeture de la session" printf " ''${BOLD}''${RED} INITIALISATION NON TERMINÉE''${RESET}\n"
for i in 1 2 3; do
printf "."
${pkgs.coreutils}/bin/sleep 1
done
echo 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 exit 1
fi fi
''; '';
# ============================================================ # ============================================================
# Superviseur # Superviseur de première connexion
# ============================================================ # ============================================================
yubikeyFirstLoginSupervisor = yubikeyFirstLoginSupervisor =
@@ -212,7 +216,10 @@ let
current_user="$(${pkgs.coreutils}/bin/id -un)" current_user="$(${pkgs.coreutils}/bin/id -un)"
# --------------------------------------------------------
# Pour le moment, uniquement Alice. # Pour le moment, uniquement Alice.
# --------------------------------------------------------
if [ "$current_user" != "alice" ]; then if [ "$current_user" != "alice" ]; then
exit 0 exit 0
fi fi
@@ -220,52 +227,96 @@ let
state_dir="$HOME/.local/state/nixos-workstations" state_dir="$HOME/.local/state/nixos-workstations"
marker="$state_dir/yubikey-pin-initialized" marker="$state_dir/yubikey-pin-initialized"
# Initialisation déjà effectuée. 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 if [ -e "$marker" ]; then
exit 0 exit 0
fi fi
# Laisse KDE terminer son démarrage. # Laisse Plasma terminer son démarrage.
${pkgs.coreutils}/bin/sleep 3 ${pkgs.coreutils}/bin/sleep 4
# -------------------------------------------------------- # --------------------------------------------------------
# Assistant plein écran # 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 \ ${pkgs.kdePackages.konsole}/bin/konsole \
--separate \ --separate \
--fullscreen \ --fullscreen \
--hide-menubar \ --hide-menubar \
--hide-tabbar \ --hide-tabbar \
-e ${yubikeyPinChange} -e ${yubikeyPinChange} \
>/dev/null 2>&1 &
# -------------------------------------------------------- # Laisse le temps à Konsole et au script de démarrer.
# L'assistant vient de se terminer. ${pkgs.coreutils}/bin/sleep 2
# --------------------------------------------------------
if [ -e "$marker" ]; then
# PIN correctement changé.
exit 0
fi
# Pas de marqueur :
#
# - utilisateur ayant fermé la fenêtre ;
# - Ctrl+C ;
# - erreur ykman ;
# - changement du PIN abandonné.
#
# Dans tous ces cas, on ferme la session d'Alice.
session_id="''${XDG_SESSION_ID:-}"
if [ -n "$session_id" ]; then
${pkgs.systemd}/bin/loginctl terminate-session "$session_id"
else else
${pkgs.systemd}/bin/loginctl terminate-user "$current_user"
${pkgs.coreutils}/bin/sleep 2
fi fi
exit 1 done
# --------------------------------------------------------
# Le marqueur existe :
# l'initialisation est terminée.
#
# On ne touche PAS à la session KDE.
# --------------------------------------------------------
exit 0
''; '';
in in