diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index bf6e15da..9cfe335a 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -20,6 +20,7 @@ jobs: pwd-manager, firewall, screenlock, + screenlock-plasma5, secureboot, luks, zfs, diff --git a/checks/linux/password_unlock.go b/checks/linux/password_unlock.go index 4b2a842f..fb5a625c 100644 --- a/checks/linux/password_unlock.go +++ b/checks/linux/password_unlock.go @@ -93,10 +93,14 @@ func (f *PasswordToUnlock) Run() error { } // Check if running KDE - if _, err := lookPath("kreadconfig5"); err == nil { + if _, err := lookPath("kreadconfig6"); err == nil { + // Plasma 6 detected + f.passed = f.checkKDE5() // Same config format, just different tools + } else if _, err := lookPath("kreadconfig5"); err == nil { + // Plasma 5 detected f.passed = f.checkKDE5() } else { - log.Debug("KDE environment(5) not detected for screensaver lock check") + log.Debug("KDE environment not detected for screensaver lock check") } // Check if running Sway diff --git a/flake.lock b/flake.lock index 0688e71d..27fbcf00 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1751413152, - "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", + "lastModified": 1756770412, + "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", + "rev": "4524271976b625a4a605beefd893f270620fd751", "type": "github" }, "original": { @@ -19,11 +19,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1751949589, - "narHash": "sha256-mgFxAPLWw0Kq+C8P3dRrZrOYEQXOtKuYVlo9xvPntt8=", + "lastModified": 1758262103, + "narHash": "sha256-aBGl3XEOsjWw6W3AHiKibN7FeoG73dutQQEqnd/etR8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9b008d60392981ad674e04016d25619281550a9d", + "rev": "12bd230118a1901a4a5d393f9f56b6ad7e571d01", "type": "github" }, "original": { @@ -33,13 +33,29 @@ "type": "github" } }, + "nixpkgs-2411": { + "locked": { + "lastModified": 1751274312, + "narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-lib": { "locked": { - "lastModified": 1751159883, - "narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=", + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", "type": "github" }, "original": { @@ -51,7 +67,8 @@ "root": { "inputs": { "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "nixpkgs-2411": "nixpkgs-2411" } } }, diff --git a/flake.nix b/flake.nix index 7eb5b71c..419f7f1a 100644 --- a/flake.nix +++ b/flake.nix @@ -1,20 +1,25 @@ { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs-2411.url = "github:NixOS/nixpkgs/nixos-24.11"; }; outputs = inputs@{ flake-parts, nixpkgs, + nixpkgs-2411, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = nixpkgs.lib.systems.flakeExposed; perSystem = - { pkgs, ... }: + { pkgs, system, ... }: let + # Create pkgs from nixpkgs-24.11 for Plasma 5 testing + pkgs2411 = import nixpkgs-2411 { inherit system; }; + # Extend pkgs with our paretosecurity overlay pkgsOverlayed = pkgs.extend ( final: prev: { @@ -33,17 +38,32 @@ packages.default = pkgsOverlayed.paretosecurity; checks = { + autologin = pkgsOverlayed.testers.runNixOSTest ./test/integration/autologin.nix; cli = pkgsOverlayed.testers.runNixOSTest ./test/integration/cli.nix; firewall = pkgsOverlayed.testers.runNixOSTest ./test/integration/firewall.nix; help = pkgsOverlayed.testers.runNixOSTest ./test/integration/help.nix; luks = pkgsOverlayed.testers.runNixOSTest ./test/integration/luks.nix; - zfs = pkgsOverlayed.testers.runNixOSTest ./test/integration/zfs.nix; pwd-manager = pkgsOverlayed.testers.runNixOSTest ./test/integration/pwd-manager.nix; - screenlock = pkgsOverlayed.testers.runNixOSTest ./test/integration/screenlock.nix; secureboot = pkgsOverlayed.testers.runNixOSTest ./test/integration/secureboot.nix; trayicon = pkgsOverlayed.testers.runNixOSTest ./test/integration/trayicon.nix; xfce = pkgsOverlayed.testers.runNixOSTest ./test/integration/desktop/xfce.nix; - autologin = pkgsOverlayed.testers.runNixOSTest ./test/integration/autologin.nix; + zfs = pkgsOverlayed.testers.runNixOSTest ./test/integration/zfs.nix; + + screenlock = pkgsOverlayed.testers.runNixOSTest ./test/integration/screenlock.nix; + screenlock-plasma5 = + let + # Extend pkgs2411 with our paretosecurity overlay + pkgs2411Overlayed = pkgs2411.extend ( + _: _: { + inherit (pkgsOverlayed) paretosecurity; + } + ); + in + pkgs2411Overlayed.testers.runNixOSTest ( + import ./test/integration/screenlock-plasma5.nix { + inherit pkgsOverlayed; + } + ); }; }; }; diff --git a/test/integration/autologin.nix b/test/integration/autologin.nix index 60acd25a..9976487c 100644 --- a/test/integration/autologin.nix +++ b/test/integration/autologin.nix @@ -118,9 +118,9 @@ in ]; services.paretosecurity.enable = true; services.xserver.enable = true; - services.xserver.desktopManager.plasma5.enable = true; + services.desktopManager.plasma6.enable = true; services.displayManager.sddm.enable = true; - services.displayManager.defaultSession = "plasma"; + services.displayManager.defaultSession = "plasmax11"; services.displayManager.autoLogin = { enable = true; user = "testuser"; diff --git a/test/integration/cli.nix b/test/integration/cli.nix index 8d9c1773..460be903 100644 --- a/test/integration/cli.nix +++ b/test/integration/cli.nix @@ -36,7 +36,7 @@ in " • Access Security: SSH keys have password protection > [DISABLED] No private keys found in ~/.ssh directory\n" " • Access Security: SSH keys have sufficient algorithm strength > [DISABLED] No private keys found in the ~/.ssh directory\n" " • System Integrity: SecureBoot is enabled > [FAIL] System is not running in UEFI mode\n" - " • Application Updates: Apps are up to date > [OK] All packages are up to date\n" + " • [root] Application Updates: Apps are up to date > [OK] All packages are up to date\n" " • Firewall & Sharing: Sharing printers is off > [OK] Sharing printers is off\n" " • [root] System Integrity: Filesystem encryption is enabled > [FAIL] Block device encryption is disabled\n" " • Firewall & Sharing: Remote login is disabled > [OK] No remote access services found running\n" diff --git a/test/integration/screenlock-plasma5.nix b/test/integration/screenlock-plasma5.nix new file mode 100644 index 00000000..389bad99 --- /dev/null +++ b/test/integration/screenlock-plasma5.nix @@ -0,0 +1,35 @@ +# Test for KDE Plasma 5 using nixpkgs-24.11 +# This is separate because Plasma 5 was removed from newer nixpkgs +{ pkgsOverlayed }: +{ + name = "Screen Lock - Plasma 5"; + interactive.sshBackdoor.enable = true; + + nodes = { + kde5 = + { ... }: + { + services.paretosecurity.enable = true; + services.paretosecurity.package = pkgsOverlayed.paretosecurity; + + # Install KDE Plasma 5 Desktop Environment + services.xserver.enable = true; + services.xserver.desktopManager.plasma5.enable = true; + services.displayManager.sddm.enable = true; + services.colord.enable = false; + }; + }; + + testScript = '' + # Test KDE Plasma 5 + # Test 1: Check passes with lock enabled + kde5.succeed("kwriteconfig5 --file kscreenlockerrc --group Daemon --key LockOnResume true") + out = kde5.succeed("paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8") + assert "[OK] Password after sleep or screensaver is on" in out, f"Expected check to pass, got \n{out}" + + # Test 2: Check fails when lock is disabled + kde5.succeed("kwriteconfig5 --file kscreenlockerrc --group Daemon --key LockOnResume false") + status, out = kde5.execute("paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8") + assert "[FAIL] Password after sleep or screensaver is off" in out, f"Expected check to fail, got \n{out}" + ''; +} diff --git a/test/integration/screenlock.nix b/test/integration/screenlock.nix index 3a09cb62..30619a81 100644 --- a/test/integration/screenlock.nix +++ b/test/integration/screenlock.nix @@ -8,19 +8,36 @@ { services.paretosecurity.enable = true; # Install GNOME Desktop Environment - services.xserver.desktopManager.gnome.enable = true; - services.xserver.displayManager.gdm.enable = true; + services.desktopManager.gnome.enable = true; + services.displayManager.gdm.enable = true; }; kde = - { ... }: + { pkgs, ... }: { services.paretosecurity.enable = true; - # Install KDE Plasma 5 Desktop Environment + # Install KDE Plasma 6 Desktop Environment services.xserver.enable = true; - services.xserver.desktopManager.plasma5.enable = true; - services.xserver.displayManager.sddm.enable = true; + services.desktopManager.plasma6.enable = true; + services.displayManager.sddm.enable = true; + services.displayManager.autoLogin.enable = true; + services.displayManager.autoLogin.user = "alice"; services.colord.enable = false; + + # Increase memory for Plasma 6 + virtualisation.memorySize = 2048; + + # Create alice user + users.users.alice = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + password = "alice"; + }; + + # Add kconfig package which includes kwriteconfig6 and kreadconfig6 + environment.systemPackages = with pkgs; [ + kdePackages.kconfig + ]; }; sway = @@ -171,15 +188,23 @@ status, out = gnome.execute("paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8") assert "[FAIL] Password after sleep or screensaver is off" in out, f"Expected check to fail, got \n{out}" - # Test KDE - # Test 1: Check passes with lock enabled - kde.succeed("kwriteconfig5 --file kscreenlockerrc --group Daemon --key LockOnResume true") - out = kde.succeed("paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8") + # Test KDE Plasma 6 + # Wait for KDE to start and alice to be logged in + kde.wait_for_unit("graphical.target") + + # First ensure lock is enabled (Plasma 6 might have different defaults) + # Run as alice user + kde.succeed("su - alice -c 'kwriteconfig6 --file kscreenlockerrc --group Daemon --key LockOnResume true'") + kde.succeed("su - alice -c 'kwriteconfig6 --file kscreenlockerrc --group Daemon --key Autolock true'") + + # Test 1: Check passes with lock enabled (run as alice) + out = kde.succeed("su - alice -c 'paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8'") assert "[OK] Password after sleep or screensaver is on" in out, f"Expected check to pass, got \n{out}" # Test 2: Check fails when lock is disabled - kde.succeed("kwriteconfig5 --file kscreenlockerrc --group Daemon --key LockOnResume false") - status, out = kde.execute("paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8") + kde.succeed("su - alice -c 'kwriteconfig6 --file kscreenlockerrc --group Daemon --key LockOnResume false'") + kde.succeed("su - alice -c 'kwriteconfig6 --file kscreenlockerrc --group Daemon --key Autolock false'") + status, out = kde.execute("su - alice -c 'paretosecurity check --only 37dee029-605b-4aab-96b9-5438e5aa44d8'") assert "[FAIL] Password after sleep or screensaver is off" in out, f"Expected check to fail, got \n{out}" # Test Sway diff --git a/test/integration/trayicon.nix b/test/integration/trayicon.nix index 27fd7539..002f9c88 100644 --- a/test/integration/trayicon.nix +++ b/test/integration/trayicon.nix @@ -17,8 +17,8 @@ in services.paretosecurity.enable = true; services.xserver.enable = true; - services.xserver.displayManager.gdm.enable = true; - services.xserver.desktopManager.gnome.enable = true; + services.displayManager.gdm.enable = true; + services.desktopManager.gnome.enable = true; services.displayManager.defaultSession = "gnome"; # Add AppIndicator extension for system tray support