Actualiser modules/yubikey-first-login.nix

This commit is contained in:
2026-08-18 14:33:45 +02:00
parent be3d312dca
commit adf44ca2fe
+262 -194
View File
@@ -1,24 +1,16 @@
{ pkgs, ... }:
let
# ============================================================
# Assistant interactif de changement du PIN YubiKey
# ============================================================
yubikeyPinChange = pkgs.writeShellScript "yubikey-pin-change" ''
firstLoginSetup = pkgs.writeShellScript "first-login-setup" ''
set -u
state_dir="$HOME/.local/state/nixos-workstations"
marker="$state_dir/yubikey-pin-initialized"
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-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.
# ----------------------------------------------------------
active_file="$runtime_dir/nixos-workstations-first-login.active"
printf '%s\n' "$$" > "$active_file"
@@ -28,22 +20,13 @@ let
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"
@@ -51,110 +34,180 @@ let
GREY="\033[38;5;245m"
WHITE="\033[38;5;255m"
separator() {
printf "''${BLUE}''${RESET}\n"
line() {
printf "''${GREY}''${RESET}\n"
}
# ----------------------------------------------------------
# Nettoyage de l'écran
# ----------------------------------------------------------
printf "\033[2J\033[H"
clear
echo
separator
echo
printf " ''${BOLD}''${CYAN}🔐 INITIALISATION DE VOTRE YUBIKEY''${RESET}\n"
printf " ''${BOLD}''${CYAN}CONFIGURATION DE VOTRE COMPTE''${RESET}\n"
echo
separator
line
echo
printf " ''${WHITE}Bienvenue.''${RESET}\n"
printf " Bienvenue ''${BOLD}Alice''${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"
printf " Cette procédure termine la préparation de votre poste.\n"
printf " Elle ne sera effectuée qu'une seule fois.\n"
echo
separator
line
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"
# ==========================================================
# ÉTAPE 1 : MOT DE PASSE LOCAL
# ==========================================================
if [ ! -e "$password_marker" ]; then
printf " ''${BOLD}''${CYAN}ÉTAPE 1 / 2''${RESET}\n"
echo
separator
printf " ''${BOLD}Choisissez votre mot de passe de secours''${RESET}\n"
echo
printf " ''${BOLD}''${WHITE}Suivez maintenant les instructions ci-dessous.''${RESET}\n"
printf " Ce mot de passe permet notamment d'accéder au poste\n"
printf " si votre YubiKey est indisponible.\n"
echo
printf " ''${YELLOW}Vous allez saisir :''${RESET}\n"
echo
printf " votre mot de passe temporaire actuel\n"
printf " votre nouveau mot de passe personnel\n"
printf " une confirmation du nouveau mot de passe\n"
echo
line
echo
# ----------------------------------------------------------
# Changement du PIN
# ----------------------------------------------------------
if ${pkgs.shadow}/bin/passwd; then
${pkgs.coreutils}/bin/mkdir -p "$state_dir"
${pkgs.coreutils}/bin/touch "$password_marker"
echo
printf " ''${GREEN} Mot de passe modifié avec succès.''${RESET}\n"
echo
${pkgs.coreutils}/bin/sleep 2
else
echo
printf " ''${RED} Le changement du mot de passe a échoué.''${RESET}\n"
echo
printf " La procédure sera automatiquement reproposée.\n"
${pkgs.coreutils}/bin/sleep 3
exit 1
fi
fi
# ==========================================================
# ÉTAPE 2 : PIN YUBIKEY
# ==========================================================
clear
echo
echo
printf " ''${BOLD}''${CYAN}CONFIGURATION DE VOTRE COMPTE''${RESET}\n"
echo
line
echo
printf " ''${BOLD}''${CYAN}ÉTAPE 2 / 2''${RESET}\n"
echo
printf " ''${BOLD}Personnalisez le PIN de votre YubiKey''${RESET}\n"
echo
printf " Votre clé utilise actuellement le PIN temporaire fourni\n"
printf " lors de la préparation du poste.\n"
echo
printf " ''${YELLOW}Vous allez saisir :''${RESET}\n"
echo
printf " votre PIN temporaire actuel\n"
printf " votre nouveau PIN personnel\n"
printf " une confirmation du nouveau PIN\n"
echo
printf " ''${GREY}Le nouveau PIN reste enregistré uniquement dans la YubiKey.''${RESET}\n"
echo
printf " ''${YELLOW} Vérifiez Verr Num si vous utilisez le pavé numérique.''${RESET}\n"
printf " En cas de doute, utilisez les chiffres situés au-dessus du clavier.\n"
echo
line
echo
if [ ! -e "$yubikey_marker" ]; then
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"
${pkgs.coreutils}/bin/touch "$yubikey_marker"
echo
separator
echo
printf " ''${GREEN} PIN YubiKey modifié avec succès.''${RESET}\n"
printf " ''${BOLD}''${GREEN} INITIALISATION TERMINÉE''${RESET}\n"
${pkgs.coreutils}/bin/sleep 2
else
echo
separator
printf " ''${RED} Le changement du PIN n'a pas été terminé.''${RESET}\n"
echo
printf " Votre mot de passe déjà modifié sera conservé.\n"
printf " Seule cette étape sera reproposée.\n"
printf " ''${GREEN}Votre nouveau PIN est maintenant actif.''${RESET}\n"
echo
${pkgs.coreutils}/bin/sleep 3
printf " Utilisez désormais ce nouveau PIN pour vous\n"
printf " connecter avec votre YubiKey.\n"
exit 1
fi
fi
# ==========================================================
# TERMINÉ
# ==========================================================
clear
echo
printf " ''${GREY}Cette procédure ne sera plus affichée.''${RESET}\n"
echo
line
echo
printf " ''${BOLD}''${GREEN} CONFIGURATION TERMINÉE''${RESET}\n"
echo
separator
line
echo
printf " Votre compte est maintenant prêt.\n"
echo
printf " ''${GREEN}''${RESET} Mot de passe personnel configuré\n"
printf " ''${GREEN}''${RESET} PIN personnel YubiKey configuré\n"
echo
echo
printf " Pour vos prochaines connexions :\n"
echo
printf " ''${BOLD}YubiKey + votre PIN personnel''${RESET}\n"
echo
printf " Votre mot de passe local reste disponible comme solution\n"
printf " de secours.\n"
echo
line
echo
printf " Fermeture automatique"
@@ -166,171 +219,186 @@ let
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" ''
firstLoginSupervisor =
pkgs.writeShellScript "first-login-supervisor" ''
set -u
current_user="$(${pkgs.coreutils}/bin/id -un)"
# --------------------------------------------------------
# Pour le moment, uniquement Alice.
# --------------------------------------------------------
# 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"
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-yubikey-first-login.active"
supervisor_lock="$runtime_dir/nixos-workstations-yubikey-first-login.lock"
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"
# --------------------------------------------------------
# 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
# Les deux opérations sont déjà terminées.
if [ -e "$password_marker" ] && [ -e "$yubikey_marker" ]; then
exit 0
fi
# Laisse Plasma terminer son démarrage.
${pkgs.coreutils}/bin/sleep 4
${pkgs.coreutils}/bin/sleep 3
# --------------------------------------------------------
# Boucle de supervision
# --------------------------------------------------------
# ========================================================
# Présentation
# ========================================================
while [ ! -e "$marker" ]; do
while \
[ ! -e "$password_marker" ] || \
[ ! -e "$yubikey_marker" ]
do
assistant_running=0
"$KDIALOG" \
--title "Finalisation de votre poste" \
--warningcontinuecancel \
"Bienvenue Alice.
# ------------------------------------------------------
# Vérifie si l'assistant précédemment lancé tourne
# réellement toujours.
# ------------------------------------------------------
Votre poste est presque prêt.
if [ -s "$active_file" ]; then
Pour terminer sa configuration, vous devez personnaliser deux éléments de sécurité :
assistant_pid="$(${pkgs.coreutils}/bin/cat "$active_file" 2>/dev/null || true)"
🔑 Votre mot de passe local de secours
if [ -n "$assistant_pid" ] \
&& ${pkgs.coreutils}/bin/kill -0 "$assistant_pid" 2>/dev/null; then
🔐 Le PIN de votre YubiKey
assistant_running=1
Ces informations deviennent personnelles.
else
Elles ne sont pas enregistrées dans Git et ne sont pas transmises au service informatique.
# Fichier devenu obsolète.
rm -f "$active_file"
La procédure prend seulement quelques instants."
fi
result=$?
if [ "$result" -ne 0 ]; then
"$KDIALOG" \
--title "Configuration requise" \
--sorry \
"La configuration initiale de votre compte n'est pas terminée.
L'assistant va être reproposé."
${pkgs.coreutils}/bin/sleep 1
continue
fi
# ------------------------------------------------------
# Aucun assistant actif :
# on en ouvre un.
# Lance l'assistant interactif
# ------------------------------------------------------
if [ "$assistant_running" -eq 0 ]; then
${pkgs.kdePackages.konsole}/bin/konsole \
"$KONSOLE" \
--separate \
--fullscreen \
--hide-menubar \
--hide-tabbar \
-e ${yubikeyPinChange} \
-e ${firstLoginSetup} \
>/dev/null 2>&1 &
# Laisse le temps à Konsole et au script de démarrer.
${pkgs.coreutils}/bin/sleep 2
${pkgs.coreutils}/bin/sleep 1
else
# ------------------------------------------------------
# Attend la fin réelle du script.
# ------------------------------------------------------
${pkgs.coreutils}/bin/sleep 2
while true; do
if [ \
-e "$password_marker" \
] && [ \
-e "$yubikey_marker" \
]; then
break
fi
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
if ! ${pkgs.coreutils}/bin/kill -0 "$assistant_pid" 2>/dev/null; then
rm -f "$active_file"
break
fi
${pkgs.coreutils}/bin/sleep 1
done
# --------------------------------------------------------
# Le marqueur existe :
# l'initialisation est terminée.
#
# On ne touche PAS à la session KDE.
# --------------------------------------------------------
# ------------------------------------------------------
# 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 votre YubiKey et votre nouveau PIN.
Votre mot de passe local reste disponible comme solution de secours."
exit 0
fi
"$KDIALOG" \
--title "Configuration incomplète" \
--sorry \
"La configuration n'a pas été 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 à 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}
Name=Finalisation du poste
Comment=Configuration initiale du compte utilisateur
Exec=${firstLoginSupervisor}
OnlyShowIn=KDE;
NoDisplay=true
StartupNotify=false