1import ./make-test-python.nix (
2 { lib, pkgs, ... }:
3 let
4 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
5 in
6 {
7 name = "ssh-agent-auth";
8 meta.maintainers = with lib.maintainers; [ nicoo ];
9
10 nodes =
11 let
12 nodeConfig =
13 n:
14 { ... }:
15 {
16 users.users = {
17 admin = {
18 isNormalUser = true;
19 extraGroups = [ "wheel" ];
20 openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
21 };
22 foo.isNormalUser = true;
23 };
24
25 security.pam.sshAgentAuth = {
26 # Must be specified, as nixpkgs CI expects everything to eval without warning
27 authorizedKeysFiles = [ "/etc/ssh/authorized_keys.d/%u" ];
28 enable = true;
29 };
30 security.${lib.replaceStrings [ "_" ] [ "-" ] n} = {
31 enable = true;
32 wheelNeedsPassword = true; # We are checking `pam_ssh_agent_auth(8)` works for a sudoer
33 };
34
35 # Necessary for pam_ssh_agent_auth >_>'
36 services.openssh.enable = true;
37 };
38 in
39 lib.genAttrs [ "sudo" "sudo_rs" ] nodeConfig;
40
41 testScript =
42 let
43 privateKeyPath = "/home/admin/.ssh/id_ecdsa";
44 userScript = pkgs.writeShellScript "test-script" ''
45 set -e
46 ssh-add -q ${privateKeyPath}
47
48 # faketty needed to ensure `sudo` doesn't write to the controlling PTY,
49 # which would break the test-driver's line-oriented protocol.
50 ${lib.getExe pkgs.faketty} sudo -u foo -- id -un
51 '';
52 in
53 ''
54 for vm in (sudo, sudo_rs):
55 sudo_impl = vm.name.replace("_", "-")
56 with subtest(f"wheel user can auth with ssh-agent for {sudo_impl}"):
57 vm.copy_from_host("${snakeOilPrivateKey}", "${privateKeyPath}")
58 vm.succeed("chmod -R 0700 /home/admin")
59 vm.succeed("chown -R admin:users /home/admin")
60
61 # Run `userScript` in an environment with an SSH-agent available
62 assert vm.succeed("sudo -u admin -- ssh-agent ${userScript} 2>&1").strip() == "foo"
63 '';
64 }
65)