From 7e70c084709574ad423159dcb461f8aede020d58 Mon Sep 17 00:00:00 2001 From: nicoo Date: Wed, 8 Nov 2023 20:47:33 +0000 Subject: [PATCH 1/2] nixosTests.ssh-agent-auth: init --- nixos/tests/all-tests.nix | 1 + nixos/tests/ssh-agent-auth.nix | 48 +++++++++++++++++++ .../linux/pam_ssh_agent_auth/default.nix | 4 +- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 nixos/tests/ssh-agent-auth.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index f09c79e782b8..e5ba9afe206f 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -782,6 +782,7 @@ in { spark = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./spark {}; sqlite3-to-mysql = handleTest ./sqlite3-to-mysql.nix {}; sslh = handleTest ./sslh.nix {}; + ssh-agent-auth = handleTest ./ssh-agent-auth.nix {}; ssh-audit = handleTest ./ssh-audit.nix {}; sssd = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd.nix {}; sssd-ldap = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd-ldap.nix {}; diff --git a/nixos/tests/ssh-agent-auth.nix b/nixos/tests/ssh-agent-auth.nix new file mode 100644 index 000000000000..2233ce0b3279 --- /dev/null +++ b/nixos/tests/ssh-agent-auth.nix @@ -0,0 +1,48 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: + let + inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey; + in { + name = "ssh-agent-auth"; + meta.maintainers = with lib.maintainers; [ nicoo ]; + + nodes.sudoVM = { lib, ... }: { + users.users = { + admin = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; + }; + foo.isNormalUser = true; + }; + + security.pam.enableSSHAgentAuth = true; + security.sudo = { + enable = true; + wheelNeedsPassword = true; # We are checking `pam_ssh_agent_auth(8)` works for a sudoer + }; + + # Necessary for pam_ssh_agent_auth >_>' + services.openssh.enable = true; + }; + + testScript = let + privateKeyPath = "/home/admin/.ssh/id_ecdsa"; + userScript = pkgs.writeShellScript "test-script" '' + set -e + ssh-add -q ${privateKeyPath} + + # faketty needed to ensure `sudo` doesn't write to the controlling PTY, + # which would break the test-driver's line-oriented protocol. + ${lib.getExe pkgs.faketty} sudo -u foo -- id -un + ''; + in '' + sudoVM.copy_from_host("${snakeOilPrivateKey}", "${privateKeyPath}") + sudoVM.succeed("chmod -R 0700 /home/admin") + sudoVM.succeed("chown -R admin:users /home/admin") + + with subtest("sudoer can auth through pam_ssh_agent_auth(8)"): + # Run `userScript` in an environment with an SSH-agent available + assert sudoVM.succeed("sudo -u admin -- ssh-agent ${userScript} 2>&1").strip() == "foo" + ''; + } +) diff --git a/pkgs/os-specific/linux/pam_ssh_agent_auth/default.nix b/pkgs/os-specific/linux/pam_ssh_agent_auth/default.nix index f28cb28ef373..46587028f296 100644 --- a/pkgs/os-specific/linux/pam_ssh_agent_auth/default.nix +++ b/pkgs/os-specific/linux/pam_ssh_agent_auth/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, fetchpatch, fetchFromGitHub, pam, openssl, perl }: +{ lib, stdenv, nixosTests, fetchpatch, fetchFromGitHub, pam, openssl, perl }: stdenv.mkDerivation rec { pname = "pam_ssh_agent_auth"; @@ -46,6 +46,8 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; + passthru.tests.sudo = nixosTests.ssh-agent-auth; + meta = { homepage = "https://github.com/jbeverly/pam_ssh_agent_auth"; description = "PAM module for authentication through the SSH agent"; From 9b8812794b8c489ddb7756a7993affcef7fdd36f Mon Sep 17 00:00:00 2001 From: nicoo Date: Sun, 24 Dec 2023 15:50:12 +0000 Subject: [PATCH 2/2] nixosTests.ssh-agent-auth: Test both `sudo` and `sudo-rs` --- nixos/tests/ssh-agent-auth.nix | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/nixos/tests/ssh-agent-auth.nix b/nixos/tests/ssh-agent-auth.nix index 2233ce0b3279..2274e463ce95 100644 --- a/nixos/tests/ssh-agent-auth.nix +++ b/nixos/tests/ssh-agent-auth.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: name = "ssh-agent-auth"; meta.maintainers = with lib.maintainers; [ nicoo ]; - nodes.sudoVM = { lib, ... }: { + nodes = let nodeConfig = n: { ... }: { users.users = { admin = { isNormalUser = true; @@ -16,7 +16,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: }; security.pam.enableSSHAgentAuth = true; - security.sudo = { + security.${lib.replaceStrings [ "_" ] [ "-" ] n} = { enable = true; wheelNeedsPassword = true; # We are checking `pam_ssh_agent_auth(8)` works for a sudoer }; @@ -24,6 +24,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: # Necessary for pam_ssh_agent_auth >_>' services.openssh.enable = true; }; + in lib.genAttrs [ "sudo" "sudo_rs" ] nodeConfig; testScript = let privateKeyPath = "/home/admin/.ssh/id_ecdsa"; @@ -36,13 +37,15 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: ${lib.getExe pkgs.faketty} sudo -u foo -- id -un ''; in '' - sudoVM.copy_from_host("${snakeOilPrivateKey}", "${privateKeyPath}") - sudoVM.succeed("chmod -R 0700 /home/admin") - sudoVM.succeed("chown -R admin:users /home/admin") + for vm in (sudo, sudo_rs): + sudo_impl = vm.name.replace("_", "-") + with subtest(f"wheel user can auth with ssh-agent for {sudo_impl}"): + vm.copy_from_host("${snakeOilPrivateKey}", "${privateKeyPath}") + vm.succeed("chmod -R 0700 /home/admin") + vm.succeed("chown -R admin:users /home/admin") - with subtest("sudoer can auth through pam_ssh_agent_auth(8)"): - # Run `userScript` in an environment with an SSH-agent available - assert sudoVM.succeed("sudo -u admin -- ssh-agent ${userScript} 2>&1").strip() == "foo" + # Run `userScript` in an environment with an SSH-agent available + assert vm.succeed("sudo -u admin -- ssh-agent ${userScript} 2>&1").strip() == "foo" ''; } )