1{ ... }:
2
3let
4 userPassword = "password";
5 mismatchPass = "mismatch";
6in
7{
8 name = "pam-zfs-key";
9
10 nodes.machine =
11 { ... }:
12 {
13 boot.supportedFilesystems = [ "zfs" ];
14
15 networking.hostId = "12345678";
16
17 security.pam.zfs.enable = true;
18
19 users.users = {
20 alice = {
21 isNormalUser = true;
22 password = userPassword;
23 };
24 bob = {
25 isNormalUser = true;
26 password = userPassword;
27 };
28 };
29 };
30
31 testScript =
32 { nodes, ... }:
33 let
34 homes = nodes.machine.security.pam.zfs.homes;
35 pool = builtins.head (builtins.split "/" homes);
36 in
37 ''
38 machine.wait_for_unit("multi-user.target")
39 machine.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
40
41 with subtest("Create encrypted ZFS datasets"):
42 machine.succeed("truncate -s 64M /testpool.img")
43 machine.succeed("zpool create -O canmount=off '${pool}' /testpool.img")
44 machine.succeed("zfs create -o canmount=off -p '${homes}'")
45 machine.succeed("echo ${userPassword} | zfs create -o canmount=noauto -o encryption=on -o keyformat=passphrase '${homes}/alice'")
46 machine.succeed("zfs unload-key '${homes}/alice'")
47 machine.succeed("echo ${mismatchPass} | zfs create -o canmount=noauto -o encryption=on -o keyformat=passphrase '${homes}/bob'")
48 machine.succeed("zfs unload-key '${homes}/bob'")
49
50 with subtest("Switch to tty2"):
51 machine.fail("pgrep -f 'agetty.*tty2'")
52 machine.send_key("alt-f2")
53 machine.wait_until_succeeds("[ $(fgconsole) = 2 ]")
54 machine.wait_for_unit("getty@tty2.service")
55 machine.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
56
57 with subtest("Log in as user with home locked by login password"):
58 machine.wait_until_tty_matches("2", "login: ")
59 machine.send_chars("alice\n")
60 machine.wait_until_tty_matches("2", "login: alice")
61 machine.wait_until_succeeds("pgrep login")
62 machine.wait_until_tty_matches("2", "Password: ")
63 machine.send_chars("${userPassword}\n")
64 machine.wait_until_succeeds("pgrep -u alice bash")
65 machine.succeed("mount | grep ${homes}/alice")
66
67 with subtest("Switch to tty3"):
68 machine.fail("pgrep -f 'agetty.*tty3'")
69 machine.send_key("alt-f3")
70 machine.wait_until_succeeds("[ $(fgconsole) = 3 ]")
71 machine.wait_for_unit("getty@tty3.service")
72 machine.wait_until_succeeds("pgrep -f 'agetty.*tty3'")
73
74 with subtest("Log in as user with home locked by password different from login"):
75 machine.wait_until_tty_matches("3", "login: ")
76 machine.send_chars("bob\n")
77 machine.wait_until_tty_matches("3", "login: bob")
78 machine.wait_until_succeeds("pgrep login")
79 machine.wait_until_tty_matches("3", "Password: ")
80 machine.send_chars("${userPassword}\n")
81 machine.wait_until_succeeds("pgrep -u bob bash")
82 machine.fail("mount | grep ${homes}/bob")
83 '';
84}