2020-12-23 18:28:30 +00:00
|
|
|
let
|
|
|
|
password1 = "foobar";
|
|
|
|
password2 = "helloworld";
|
|
|
|
password3 = "bazqux";
|
2021-01-03 12:53:34 +00:00
|
|
|
password4 = "asdf123";
|
2022-09-26 21:45:24 +01:00
|
|
|
hashed_bcrypt = "$2b$05$8xIEflrk2RxQtcVXbGIxs.Vl0x7dF1/JSv3cyX6JJt0npzkTCWvxK"; # fnord
|
|
|
|
hashed_yeshash = "$y$j9T$d8Z4EAf8P1SvM/aDFbxMS0$VnTXMp/Hnc7QdCBEaLTq5ZFOAFo2/PM0/xEAFuOE88."; # fnord
|
2020-12-23 18:28:30 +00:00
|
|
|
in import ./make-test-python.nix ({ pkgs, ... }: {
|
|
|
|
name = "shadow";
|
2021-01-10 19:08:30 +00:00
|
|
|
meta = with pkgs.lib.maintainers; { maintainers = [ nequissimus ]; };
|
2020-12-23 18:28:30 +00:00
|
|
|
|
|
|
|
nodes.shadow = { pkgs, ... }: {
|
|
|
|
environment.systemPackages = [ pkgs.shadow ];
|
|
|
|
|
|
|
|
users = {
|
|
|
|
mutableUsers = true;
|
|
|
|
users.emma = {
|
2021-03-07 13:54:00 +00:00
|
|
|
isNormalUser = true;
|
2020-12-23 18:28:30 +00:00
|
|
|
password = password1;
|
|
|
|
shell = pkgs.bash;
|
|
|
|
};
|
|
|
|
users.layla = {
|
2021-03-07 13:54:00 +00:00
|
|
|
isNormalUser = true;
|
2020-12-23 18:28:30 +00:00
|
|
|
password = password2;
|
|
|
|
shell = pkgs.shadow;
|
|
|
|
};
|
2021-01-03 12:53:34 +00:00
|
|
|
users.ash = {
|
2021-03-07 13:54:00 +00:00
|
|
|
isNormalUser = true;
|
2021-01-03 12:53:34 +00:00
|
|
|
password = password4;
|
|
|
|
shell = pkgs.bash;
|
|
|
|
};
|
2022-09-26 21:45:24 +01:00
|
|
|
users.berta = {
|
|
|
|
isNormalUser = true;
|
|
|
|
hashedPassword = hashed_bcrypt;
|
|
|
|
shell = pkgs.bash;
|
|
|
|
};
|
|
|
|
users.yesim = {
|
|
|
|
isNormalUser = true;
|
|
|
|
hashedPassword = hashed_yeshash;
|
|
|
|
shell = pkgs.bash;
|
|
|
|
};
|
2020-12-23 18:28:30 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
testScript = ''
|
|
|
|
shadow.wait_for_unit("multi-user.target")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
|
|
|
|
|
|
|
|
with subtest("Normal login"):
|
|
|
|
shadow.send_key("alt-f2")
|
2021-05-08 22:46:07 +01:00
|
|
|
shadow.wait_until_succeeds("[ $(fgconsole) = 2 ]")
|
|
|
|
shadow.wait_for_unit("getty@tty2.service")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("2", "login: ")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("emma\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("2", "login: emma")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
2020-12-23 22:48:12 +00:00
|
|
|
shadow.sleep(2)
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("${password1}\n")
|
|
|
|
shadow.send_chars("whoami > /tmp/1\n")
|
|
|
|
shadow.wait_for_file("/tmp/1")
|
|
|
|
assert "emma" in shadow.succeed("cat /tmp/1")
|
|
|
|
|
2021-01-03 12:53:34 +00:00
|
|
|
with subtest("Switch user"):
|
|
|
|
shadow.send_chars("su - ash\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("${password4}\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("whoami > /tmp/3\n")
|
|
|
|
shadow.wait_for_file("/tmp/3")
|
|
|
|
assert "ash" in shadow.succeed("cat /tmp/3")
|
|
|
|
|
2020-12-23 18:28:30 +00:00
|
|
|
with subtest("Change password"):
|
|
|
|
shadow.send_key("alt-f3")
|
2021-05-08 22:46:07 +01:00
|
|
|
shadow.wait_until_succeeds("[ $(fgconsole) = 3 ]")
|
|
|
|
shadow.wait_for_unit("getty@tty3.service")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty3'")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("3", "login: ")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("emma\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("3", "login: emma")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
2020-12-23 22:48:12 +00:00
|
|
|
shadow.sleep(2)
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("${password1}\n")
|
|
|
|
shadow.send_chars("passwd\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("${password1}\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("${password3}\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("${password3}\n")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_key("alt-f4")
|
2021-05-08 22:46:07 +01:00
|
|
|
shadow.wait_until_succeeds("[ $(fgconsole) = 4 ]")
|
|
|
|
shadow.wait_for_unit("getty@tty4.service")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty4'")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("4", "login: ")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("emma\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("4", "login: emma")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
2020-12-23 22:48:12 +00:00
|
|
|
shadow.sleep(2)
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("${password1}\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("4", "Login incorrect")
|
|
|
|
shadow.wait_until_tty_matches("4", "login:")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("emma\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("4", "login: emma")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
2020-12-23 22:48:12 +00:00
|
|
|
shadow.sleep(2)
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("${password3}\n")
|
|
|
|
shadow.send_chars("whoami > /tmp/2\n")
|
|
|
|
shadow.wait_for_file("/tmp/2")
|
|
|
|
assert "emma" in shadow.succeed("cat /tmp/2")
|
|
|
|
|
|
|
|
with subtest("Groups"):
|
|
|
|
assert "foobar" not in shadow.succeed("groups emma")
|
|
|
|
shadow.succeed("groupadd foobar")
|
|
|
|
shadow.succeed("usermod -a -G foobar emma")
|
|
|
|
assert "foobar" in shadow.succeed("groups emma")
|
|
|
|
|
|
|
|
with subtest("nologin shell"):
|
|
|
|
shadow.send_key("alt-f5")
|
2021-05-08 22:46:07 +01:00
|
|
|
shadow.wait_until_succeeds("[ $(fgconsole) = 5 ]")
|
|
|
|
shadow.wait_for_unit("getty@tty5.service")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty5'")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("5", "login: ")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.send_chars("layla\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("5", "login: layla")
|
2020-12-23 18:28:30 +00:00
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
|
|
|
shadow.send_chars("${password2}\n")
|
2022-06-04 05:22:03 +01:00
|
|
|
shadow.wait_until_tty_matches("5", "login:")
|
2022-09-26 21:45:24 +01:00
|
|
|
|
|
|
|
with subtest("check alternate password hashes"):
|
|
|
|
shadow.send_key("alt-f6")
|
|
|
|
shadow.wait_until_succeeds("[ $(fgconsole) = 6 ]")
|
|
|
|
for u in ["berta", "yesim"]:
|
|
|
|
shadow.wait_for_unit("getty@tty6.service")
|
|
|
|
shadow.wait_until_succeeds("pgrep -f 'agetty.*tty6'")
|
|
|
|
shadow.wait_until_tty_matches("6", "login: ")
|
|
|
|
shadow.send_chars(f"{u}\n")
|
|
|
|
shadow.wait_until_tty_matches("6", f"login: {u}")
|
|
|
|
shadow.wait_until_succeeds("pgrep login")
|
|
|
|
shadow.sleep(2)
|
|
|
|
shadow.send_chars("fnord\n")
|
|
|
|
shadow.send_chars(f"whoami > /tmp/{u}\n")
|
|
|
|
shadow.wait_for_file(f"/tmp/{u}")
|
|
|
|
print(shadow.succeed(f"cat /tmp/{u}"))
|
|
|
|
assert u in shadow.succeed(f"cat /tmp/{u}")
|
|
|
|
shadow.send_chars("logout\n")
|
2020-12-23 18:28:30 +00:00
|
|
|
'';
|
|
|
|
})
|