From 271ba540a8cf702526b26b1eeba4b06fcb584665 Mon Sep 17 00:00:00 2001 From: "Brideau, Patrick" Date: Mon, 24 Nov 2025 12:02:50 -0500 Subject: [PATCH 1/4] feat: add yescrypt support to pw_hash --- lib/puppet/parser/functions/pw_hash.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 7bd8fd62a..8a9f74209 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -24,6 +24,7 @@ |bcrypt-a |2a |bug compatible | |bcrypt-x |2x |bug compatible | |bcrypt-y |2y |historic alias for 2b| + |yescrypt |y | | The third argument to this function is the salt to use. For bcrypt-type hashes, the first two characters of the salt represent a strength parameter, with a value @@ -54,7 +55,8 @@ 'bcrypt' => { prefix: '2b', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, 'bcrypt-a' => { prefix: '2a', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, 'bcrypt-x' => { prefix: '2x', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, - 'bcrypt-y' => { prefix: '2y', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} } + 'bcrypt-y' => { prefix: '2y', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'yescrypt' => { prefix: 'y', salt: %r{^[./A-Za-z0-9]+\$[./A-Za-z0-9]{,86}} } } raise ArgumentError, 'pw_hash(): first argument must be a string' unless args[0].is_a?(String) || args[0].nil? @@ -76,7 +78,7 @@ # handle weak implementations of String#crypt # dup the string to get rid of frozen status for testing - if RUBY_PLATFORM == 'java' && !args[1].downcase.start_with?('bcrypt') + if RUBY_PLATFORM == 'java' && !['bcrypt', 'bcrypt-a', 'bcrypt-x', 'bcrypt-y', 'yescrypt'].include?(args[1].downcase) # puppetserver bundles Apache Commons Codec org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt) elsif (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' From 5ca6b80bb85e1b7747dd81a676e46de54d4c7663 Mon Sep 17 00:00:00 2001 From: "Brideau, Patrick" Date: Mon, 24 Nov 2025 12:11:30 -0500 Subject: [PATCH 2/4] feat: add explicit test for yescrypt --- lib/puppet/parser/functions/pw_hash.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 8a9f74209..831aa4dd0 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -81,7 +81,9 @@ if RUBY_PLATFORM == 'java' && !['bcrypt', 'bcrypt-a', 'bcrypt-x', 'bcrypt-y', 'yescrypt'].include?(args[1].downcase) # puppetserver bundles Apache Commons Codec org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt) - elsif (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' + elsif args[1].downcase == 'yescrypt' && (+'test').crypt('$y$j9T$') == '$y$j9T$$6tN6tt5mmPHxQskcf5Oi7Sb.1nKYbi5cOZgTiMq7Qw4' + password.crypt(salt) + elsif args[1].downcase.start_with?('bcrypt') && (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' password.crypt(salt) else # JRuby < 1.7.17 From 0675096e734ea87e6249d17ff5df5ad9af80e2c5 Mon Sep 17 00:00:00 2001 From: "Brideau, Patrick" Date: Mon, 24 Nov 2025 12:58:36 -0500 Subject: [PATCH 3/4] test: yescrypt support in pw_hash --- spec/functions/pw_hash_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb index 5e9af8921..e870e06ce 100644 --- a/spec/functions/pw_hash_spec.rb +++ b/spec/functions/pw_hash_spec.rb @@ -111,4 +111,10 @@ end end end + + if 'test'.crypt('$y$j9T$') == '$y$j9T$$6tN6tt5mmPHxQskcf5Oi7Sb.1nKYbi5cOZgTiMq7Qw4' + describe 'on systems with yescrypt support' do + it { is_expected.to run.with_params('password', 'yescrypt', 'j9T$salt').and_return('$y$j9T$salt$Cw3H19laQT.rHIYMLvuoUzLb8st7PboO9rfxAylYPx9') } + end + end end From 591504de01ebef8028dd7d4df23970cf75c4da90 Mon Sep 17 00:00:00 2001 From: "Brideau, Patrick" Date: Fri, 5 Dec 2025 13:00:08 -0500 Subject: [PATCH 4/4] fix: more explicit regex --- lib/puppet/parser/functions/pw_hash.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 831aa4dd0..76c7ff311 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -56,7 +56,7 @@ 'bcrypt-a' => { prefix: '2a', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, 'bcrypt-x' => { prefix: '2x', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, 'bcrypt-y' => { prefix: '2y', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, - 'yescrypt' => { prefix: 'y', salt: %r{^[./A-Za-z0-9]+\$[./A-Za-z0-9]{,86}} } + 'yescrypt' => { prefix: 'y', salt: %r{^[./A-Za-z0-9]+\$[./A-Za-z0-9]{0,86}} } } raise ArgumentError, 'pw_hash(): first argument must be a string' unless args[0].is_a?(String) || args[0].nil?