From 6cbbb1863d71675743d8b230b51d4947868938cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Mon, 31 Mar 2025 12:03:33 +0200 Subject: [PATCH] encrypt_pw: allow yescrypt in addition to sha256 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this has been the default for Debian since Bullseye[0]. besides password setting for the PAM/PVE/PMG realms, this is also used to hash cloud-init passwords for Linux VMs, where only a subset of prefixes is currently allowed. 'j9T' is the default cost factor for yescrypt. 0: https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#pam-default-password Signed-off-by: Fabian Grünbichler --- src/PVE/Tools.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 761500d..c86fb62 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -1805,7 +1805,7 @@ sub fchownat($$$$$) { my $salt_starter = time(); sub encrypt_pw { - my ($pw) = @_; + my ($pw, $prefix) = @_; $salt_starter++; my $salt = substr(Digest::SHA::sha1_base64(time() + $salt_starter + $$), 0, 8); @@ -1813,7 +1813,18 @@ sub encrypt_pw { # crypt does not want '+' in salt (see 'man crypt') $salt =~ s/\+/X/g; - return crypt(encode("utf8", $pw), "\$5\$$salt\$"); + $prefix = '5' if !$prefix; + + my $input; + if ($prefix eq '5') { + $input = "\$5\$$salt\$"; + } elsif ($prefix eq 'y') { + $input = "\$y\$j9T\$$salt\$" + } else { + die "Cannot hash password, unknown crypt prefix '$prefix'\n"; + } + + return crypt(encode("utf8", $pw), $input); } # intended usage: convert_size($val, "kb" => "gb")