Téléverser les fichiers vers "modules"

This commit is contained in:
2026-08-18 17:33:49 +02:00
parent 45cd0f1e57
commit 6faa2d3476
2 changed files with 305 additions and 8 deletions
+13 -7
View File
@@ -1,11 +1,12 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
# Les mots de passe peuvent être modifiés localement. # Les mots de passe restent mutables : après la création du compte,
# Un nixos-rebuild ne réécrase pas le mot de passe choisi par l'utilisateur. # le mot de passe choisi localement par l'utilisateur est conservé.
users.mutableUsers = true; users.mutableUsers = true;
# Compte d'administration local # Compte d'administration local.
# Son mot de passe est créé/géré localement et n'est pas défini ici.
users.users.localadm = { users.users.localadm = {
isNormalUser = true; isNormalUser = true;
description = "Administrateur local"; description = "Administrateur local";
@@ -19,7 +20,7 @@
]; ];
}; };
# Utilisateur standard # Utilisateur standard.
users.users.alice = { users.users.alice = {
isNormalUser = true; isNormalUser = true;
description = "Alice"; description = "Alice";
@@ -27,8 +28,13 @@
# Alice n'est pas administratrice. # Alice n'est pas administratrice.
extraGroups = [ ]; extraGroups = [ ];
# Utilisé uniquement lors de la création initiale du compte. # LAB uniquement.
# Demo pass : LaboTest@1980 # Mot de passe temporaire : LaboTest@1980
initialHashedPassword = "$y$j9T$XiIgBUxXjqAYbQQs3eBtr.$dT01AYyRiBtjoaF1MIG83cx2h0bRxEILE6tpilE2V9D"; #
# Avec users.mutableUsers = true, ce hash sert uniquement lors de la
# création initiale du compte. Après changement via passwd, le nouveau
# mot de passe local est conservé lors des activations suivantes.
initialHashedPassword =
"$6$VwAqDD0hXRojZr2T$5EVBlLOVnOvyJxde9uAGj.ehkiQaRis5SwTrSLuVAhiXXvG4DH9DNC.88pWfiL2O28wanR52.23INxuyEtNSQ/";
}; };
} }
+291
View File
@@ -0,0 +1,291 @@
{ config, lib, pkgs, ... }:
let
cfg = config.nixosWorkstations.workstationSetup;
passwordHelper = pkgs.writeTextFile {
name = "nixos-workstations-password-helper";
executable = true;
text = ''
#!${pkgs.expect}/bin/expect -f
# Les secrets arrivent uniquement par stdin depuis l'application.
# Ils ne sont jamais passés dans argv et aucun transcript n'est affiché.
log_user 0
exp_internal 0
set timeout 30
if {[gets stdin current] < 0 || [gets stdin newpass] < 0 || [gets stdin confirm] < 0} {
puts stderr "INPUT_ERROR"
exit 20
}
if {$newpass ne $confirm} {
puts stderr "CONFIRM_MISMATCH"
exit 21
}
spawn -noecho ${pkgs.coreutils}/bin/env LC_ALL=C LANG=C /run/wrappers/bin/passwd
expect {
-re {(?i)(current.*password|unix password|password.*current).*:} {
send -- "$current\r"
}
eof {
puts stderr "CURRENT_REJECTED"
exit 22
}
timeout {
puts stderr "TIMEOUT_CURRENT"
exit 124
}
}
# Efface la copie du mot de passe actuel dès qu'elle n'est plus utile.
set current ""
expect {
-re {(?i)new.*password.*:} {
send -- "$newpass\r"
}
eof {
puts stderr "CURRENT_REJECTED"
exit 23
}
timeout {
puts stderr "TIMEOUT_NEW"
exit 124
}
}
expect {
-re {(?i)(retype|repeat|confirm).*password.*:} {
send -- "$confirm\r"
}
-re {(?i)new.*password.*:} {
puts stderr "NEW_REJECTED"
exit 24
}
eof {
puts stderr "NEW_REJECTED"
exit 25
}
timeout {
puts stderr "TIMEOUT_CONFIRM"
exit 124
}
}
set newpass ""
set confirm ""
expect eof
set waitResult [wait]
set exitCode [lindex $waitResult 3]
if {$exitCode == 0} {
puts "OK"
exit 0
}
puts stderr "PASSWD_FAILED"
exit $exitCode
'';
};
pinHelper = pkgs.writeTextFile {
name = "nixos-workstations-pin-helper";
executable = true;
text = ''
#!${pkgs.expect}/bin/expect -f
# Même principe que pour passwd : aucune valeur secrète dans argv.
log_user 0
exp_internal 0
set timeout 30
if {[gets stdin current] < 0 || [gets stdin newpin] < 0 || [gets stdin confirm] < 0} {
puts stderr "INPUT_ERROR"
exit 30
}
if {$newpin ne $confirm} {
puts stderr "CONFIRM_MISMATCH"
exit 31
}
spawn -noecho ${pkgs.coreutils}/bin/env LC_ALL=C LANG=C ${pkgs.yubikey-manager}/bin/ykman fido access change-pin
set transcript ""
expect {
-re {Enter your current PIN.*:} {
append transcript $expect_out(buffer)
send -- "$current\r"
}
-re {No YubiKey|Failed to connect|No FIDO} {
puts stderr "NO_YUBIKEY"
exit 32
}
eof {
append transcript $expect_out(buffer)
if {[regexp -nocase {No YubiKey|Failed to connect|No FIDO} $transcript]} {
puts stderr "NO_YUBIKEY"
} else {
puts stderr "PIN_FAILED"
}
exit 33
}
timeout {
puts stderr "TIMEOUT_CURRENT_PIN"
exit 124
}
}
set current ""
expect {
-re {Enter your new PIN.*:} {
append transcript $expect_out(buffer)
send -- "$newpin\r"
}
eof {
append transcript $expect_out(buffer)
puts stderr "PIN_FAILED"
exit 34
}
timeout {
puts stderr "TIMEOUT_NEW_PIN"
exit 124
}
}
expect {
-re {(?i)(repeat|confirm).*:} {
append transcript $expect_out(buffer)
send -- "$confirm\r"
}
eof {
append transcript $expect_out(buffer)
puts stderr "PIN_FAILED"
exit 35
}
timeout {
puts stderr "TIMEOUT_CONFIRM_PIN"
exit 124
}
}
set newpin ""
set confirm ""
expect eof
append transcript $expect_out(buffer)
set waitResult [wait]
set exitCode [lindex $waitResult 3]
if {$exitCode == 0} {
puts "OK"
exit 0
}
if {[regexp -nocase {Wrong PIN|PIN_INVALID} $transcript]} {
puts stderr "WRONG_PIN"
} elseif {[regexp -nocase {authentication is currently blocked|PIN_AUTH_BLOCKED} $transcript]} {
puts stderr "PIN_AUTH_BLOCKED"
} elseif {[regexp -nocase {PIN is blocked|PIN_BLOCKED} $transcript]} {
puts stderr "PIN_BLOCKED"
} elseif {[regexp -nocase {No YubiKey|Failed to connect|No FIDO} $transcript]} {
puts stderr "NO_YUBIKEY"
} elseif {[regexp -nocase {complexity|policy|at least|at most} $transcript]} {
puts stderr "PIN_POLICY"
} else {
puts stderr "PIN_FAILED"
}
exit $exitCode
'';
};
workstationSetup = pkgs.stdenv.mkDerivation {
pname = "nixos-workstations-setup";
version = "1.0.0";
src = ../workstation-setup;
nativeBuildInputs = [
pkgs.cmake
pkgs.ninja
pkgs.pkg-config
pkgs.kdePackages.wrapQtAppsHook
];
buildInputs = with pkgs.kdePackages; [
qtbase
qtdeclarative
qtwayland
kirigami
];
cmakeFlags = [
"-DPASSWORD_HELPER_PATH=${passwordHelper}"
"-DPIN_HELPER_PATH=${pinHelper}"
"-DTARGET_USER=${cfg.user}"
];
};
launcher = pkgs.writeShellScript "nixos-workstations-setup-launcher" ''
set -eu
if [ "$(${pkgs.coreutils}/bin/id -un)" != ${lib.escapeShellArg cfg.user} ]; then
exit 0
fi
state_dir="''${XDG_STATE_HOME:-$HOME/.local/state}/nixos-workstations"
password_marker="$state_dir/password-initialized"
pin_marker="$state_dir/yubikey-pin-initialized"
if [ -e "$password_marker" ] && [ -e "$pin_marker" ]; then
exit 0
fi
# Ne jamais générer de core dump contenant potentiellement un secret.
ulimit -c 0
# Laisse Plasma finir son démarrage sans créer de logique de supervision
# susceptible de tuer ou manipuler la session utilisateur.
${pkgs.coreutils}/bin/sleep 3
exec ${workstationSetup}/bin/nixos-workstations-setup
'';
in
{
options.nixosWorkstations.workstationSetup = {
enable = lib.mkEnableOption "assistant plein écran de finalisation du poste";
user = lib.mkOption {
type = lib.types.str;
default = "alice";
description = "Utilisateur devant effectuer la personnalisation initiale.";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
workstationSetup
pkgs.yubikey-manager
];
environment.etc."xdg/autostart/nixos-workstations-setup.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Finalisation du poste
Comment=Personnalisation sécurisée des moyens d'authentification
Exec=${launcher}
OnlyShowIn=KDE;
NoDisplay=true
StartupNotify=false
'';
};
}