From 50a2a0dbccfabfbde55b5b2e79233cdea852475f Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Mon, 1 Jul 2024 13:04:05 +0200 Subject: [PATCH] Fixes #37614 - Use SHA512 for password hashing when no OS is set In e2dee7d6f7ffb505d317ca1b205f302ccd622063 the default for new operating systems was changed to SHA512, but there's an edge case where no is know for a host that makes it use SHA256. SHA512 has been the recommended value for hashing since EL5 and at least in EL6 it was also the default (didn't have EL5 on hand to check /etc/login.defs). --- app/models/concerns/host_common.rb | 2 +- app/services/password_crypt.rb | 7 ++++++- test/models/hostgroup_test.rb | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/models/concerns/host_common.rb b/app/models/concerns/host_common.rb index 524b3e6d0af..f1217570676 100644 --- a/app/models/concerns/host_common.rb +++ b/app/models/concerns/host_common.rb @@ -171,7 +171,7 @@ def crypt_pass(unencrypted_pass, pass_kind) case pass_kind when :root - operatingsystem.nil? ? PasswordCrypt.passw_crypt(unencrypted_pass) : PasswordCrypt.passw_crypt(unencrypted_pass, operatingsystem.password_hash) + PasswordCrypt.passw_crypt(unencrypted_pass, operatingsystem&.password_hash) when :grub PasswordCrypt.grub2_passw_crypt(unencrypted_pass) else diff --git a/app/services/password_crypt.rb b/app/services/password_crypt.rb index ca549b3a535..10577633bbf 100644 --- a/app/services/password_crypt.rb +++ b/app/services/password_crypt.rb @@ -2,6 +2,10 @@ class PasswordCrypt ALGORITHMS = {'SHA512' => '$6$', 'SHA256' => '$5$', 'Base64' => '', 'Base64-Windows' => ''} + # Matches ENCRYPT_METHOD in /etc/login.defs on EL6+ + # When changing this, be sure to add a migration for operatingsystems' + # default value + DEFAULT_HASH_ALGORHITHM = 'SHA512' if Foreman::Fips.md5_available? ALGORITHMS['MD5'] = '$1$' @@ -12,7 +16,8 @@ def self.generate_linux_salt SecureRandom.alphanumeric(16) end - def self.passw_crypt(passwd, hash_alg = 'SHA256') + def self.passw_crypt(passwd, hash_alg = nil) + hash_alg ||= DEFAULT_HASH_ALGORHITHM raise Foreman::Exception.new(N_("Unsupported password hash function '%s'"), hash_alg) unless ALGORITHMS.has_key?(hash_alg) case hash_alg diff --git a/test/models/hostgroup_test.rb b/test/models/hostgroup_test.rb index 933fd0b4808..2b213c7eb8e 100644 --- a/test/models/hostgroup_test.rb +++ b/test/models/hostgroup_test.rb @@ -224,7 +224,7 @@ class HostgroupTest < ActiveSupport::TestCase test "root_pass inherited from settings if blank" do Setting[:root_pass] = '12345678' PasswordCrypt.expects(:crypt_gnu_compatible?).at_least_once.returns(true) - PasswordCrypt.expects(:passw_crypt).with(Setting[:root_pass]).at_least_once.returns(Setting[:root_pass]) + PasswordCrypt.expects(:passw_crypt).with(Setting[:root_pass], nil).at_least_once.returns(Setting[:root_pass]) hostgroup = FactoryBot.build(:hostgroup, :root_pass => '') assert_equal '12345678', hostgroup.root_pass hostgroup.save! @@ -234,7 +234,7 @@ class HostgroupTest < ActiveSupport::TestCase test "root_pass inherited from settings if group and parent are blank" do Setting[:root_pass] = '12345678' PasswordCrypt.expects(:crypt_gnu_compatible?).at_least_once.returns(true) - PasswordCrypt.expects(:passw_crypt).with(Setting[:root_pass]).at_least_once.returns(Setting[:root_pass]) + PasswordCrypt.expects(:passw_crypt).with(Setting[:root_pass], nil).at_least_once.returns(Setting[:root_pass]) parent = FactoryBot.create(:hostgroup, :root_pass => '') hostgroup = FactoryBot.build(:hostgroup, :parent => parent, :root_pass => '') assert_equal '12345678', hostgroup.root_pass