nixos/tests/shadow: new hashes support with libxcrypt

Changed files
+31 -1
nixos
modules
tests
+1 -1
nixos/modules/config/users-groups.nix
···
value = "[a-zA-Z0-9/+.-]+";
options = "${id}(=${value})?(,${id}=${value})*";
scheme = "${id}(${sep}${options})?";
-
content = "${base64}${sep}${base64}";
mcf = "^${sep}${scheme}${sep}${content}$";
in
if (allowsLogin user.hashedPassword
···
value = "[a-zA-Z0-9/+.-]+";
options = "${id}(=${value})?(,${id}=${value})*";
scheme = "${id}(${sep}${options})?";
+
content = "${base64}${sep}${base64}(${sep}${base64})?";
mcf = "^${sep}${scheme}${sep}${content}$";
in
if (allowsLogin user.hashedPassword
+30
nixos/tests/shadow.nix
···
password2 = "helloworld";
password3 = "bazqux";
password4 = "asdf123";
in import ./make-test-python.nix ({ pkgs, ... }: {
name = "shadow";
meta = with pkgs.lib.maintainers; { maintainers = [ nequissimus ]; };
···
users.ash = {
isNormalUser = true;
password = password4;
shell = pkgs.bash;
};
};
···
shadow.wait_until_succeeds("pgrep login")
shadow.send_chars("${password2}\n")
shadow.wait_until_tty_matches("5", "login:")
'';
})
···
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
in import ./make-test-python.nix ({ pkgs, ... }: {
name = "shadow";
meta = with pkgs.lib.maintainers; { maintainers = [ nequissimus ]; };
···
users.ash = {
isNormalUser = true;
password = password4;
+
shell = pkgs.bash;
+
};
+
users.berta = {
+
isNormalUser = true;
+
hashedPassword = hashed_bcrypt;
+
shell = pkgs.bash;
+
};
+
users.yesim = {
+
isNormalUser = true;
+
hashedPassword = hashed_yeshash;
shell = pkgs.bash;
};
};
···
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")
'';
})