diff options
Diffstat (limited to 'nixpkgs/nixos/tests/shadow.nix')
-rw-r--r-- | nixpkgs/nixos/tests/shadow.nix | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/nixpkgs/nixos/tests/shadow.nix b/nixpkgs/nixos/tests/shadow.nix new file mode 100644 index 000000000000..a027af7e450b --- /dev/null +++ b/nixpkgs/nixos/tests/shadow.nix @@ -0,0 +1,172 @@ +let + password1 = "foobar"; + password2 = "helloworld"; + password3 = "bazqux"; + password4 = "asdf123"; + hashed_bcrypt = "$2b$05$8xIEflrk2RxQtcVXbGIxs.Vl0x7dF1/JSv3cyX6JJt0npzkTCWvxK"; # fnord + hashed_yeshash = "$y$j9T$d8Z4EAf8P1SvM/aDFbxMS0$VnTXMp/Hnc7QdCBEaLTq5ZFOAFo2/PM0/xEAFuOE88."; # fnord + hashed_sha512crypt = "$6$ymzs8WINZ5wGwQcV$VC2S0cQiX8NVukOLymysTPn4v1zJoJp3NGyhnqyv/dAf4NWZsBWYveQcj6gEJr4ZUjRBRjM0Pj1L8TCQ8hUUp0"; # meow +in import ./make-test-python.nix ({ pkgs, ... }: { + name = "shadow"; + meta = with pkgs.lib.maintainers; { maintainers = [ nequissimus ]; }; + + nodes.shadow = { pkgs, ... }: { + environment.systemPackages = [ pkgs.shadow ]; + + users = { + mutableUsers = true; + users.emma = { + isNormalUser = true; + password = password1; + shell = pkgs.bash; + }; + users.layla = { + isNormalUser = true; + password = password2; + shell = pkgs.shadow; + }; + users.ash = { + isNormalUser = true; + password = password4; + shell = pkgs.bash; + }; + users.berta = { + isNormalUser = true; + hashedPasswordFile = (pkgs.writeText "hashed_bcrypt" hashed_bcrypt).outPath; + shell = pkgs.bash; + }; + users.yesim = { + isNormalUser = true; + hashedPassword = hashed_yeshash; + shell = pkgs.bash; + }; + users.leo = { + isNormalUser = true; + initialHashedPassword = "!"; + hashedPassword = hashed_sha512crypt; # should take precedence over initialHashedPassword + shell = pkgs.bash; + }; + }; + }; + + 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") + shadow.wait_until_succeeds("[ $(fgconsole) = 2 ]") + shadow.wait_for_unit("getty@tty2.service") + shadow.wait_until_succeeds("pgrep -f 'agetty.*tty2'") + shadow.wait_until_tty_matches("2", "login: ") + shadow.send_chars("emma\n") + shadow.wait_until_tty_matches("2", "login: emma") + shadow.wait_until_succeeds("pgrep login") + shadow.sleep(2) + 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") + + 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") + + with subtest("Change password"): + shadow.send_key("alt-f3") + shadow.wait_until_succeeds("[ $(fgconsole) = 3 ]") + shadow.wait_for_unit("getty@tty3.service") + shadow.wait_until_succeeds("pgrep -f 'agetty.*tty3'") + shadow.wait_until_tty_matches("3", "login: ") + shadow.send_chars("emma\n") + shadow.wait_until_tty_matches("3", "login: emma") + shadow.wait_until_succeeds("pgrep login") + shadow.sleep(2) + 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") + shadow.wait_until_succeeds("[ $(fgconsole) = 4 ]") + shadow.wait_for_unit("getty@tty4.service") + shadow.wait_until_succeeds("pgrep -f 'agetty.*tty4'") + shadow.wait_until_tty_matches("4", "login: ") + shadow.send_chars("emma\n") + shadow.wait_until_tty_matches("4", "login: emma") + shadow.wait_until_succeeds("pgrep login") + shadow.sleep(2) + shadow.send_chars("${password1}\n") + shadow.wait_until_tty_matches("4", "Login incorrect") + shadow.wait_until_tty_matches("4", "login:") + shadow.send_chars("emma\n") + shadow.wait_until_tty_matches("4", "login: emma") + shadow.wait_until_succeeds("pgrep login") + shadow.sleep(2) + 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") + shadow.wait_until_succeeds("[ $(fgconsole) = 5 ]") + shadow.wait_for_unit("getty@tty5.service") + shadow.wait_until_succeeds("pgrep -f 'agetty.*tty5'") + shadow.wait_until_tty_matches("5", "login: ") + shadow.send_chars("layla\n") + shadow.wait_until_tty_matches("5", "login: layla") + shadow.wait_until_succeeds("pgrep login") + shadow.send_chars("${password2}\n") + shadow.wait_until_tty_matches("5", "login:") + + 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") + + with subtest("Ensure hashedPassword does not get overridden by initialHashedPassword"): + shadow.send_key("alt-f6") + shadow.wait_until_succeeds("[ $(fgconsole) = 6 ]") + 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("leo\n") + shadow.wait_until_tty_matches("6", "login: leo") + shadow.wait_until_succeeds("pgrep login") + shadow.sleep(2) + shadow.send_chars("meow\n") + shadow.send_chars("whoami > /tmp/leo\n") + shadow.wait_for_file("/tmp/leo") + assert "leo" in shadow.succeed("cat /tmp/leo") + shadow.send_chars("logout\n") + ''; +}) |