diff --git a/attributes.yml b/attributes.yml index 01cb6331c..5151d5f03 100644 --- a/attributes.yml +++ b/attributes.yml @@ -219,8 +219,8 @@ exempt_home_users: [] # main grub boot config file grub_main_cfg: '/boot/grub2/grub.cfg' -# superusers for grub boot ( array ) -grub_superusers: ['root'] +# superusers for grub boot +grub_superusers: 'root' # grub boot config files grub_user_boot_files: ['/boot/grub2/user.cfg'] diff --git a/controls/V-71961.rb b/controls/V-71961.rb index f72661f51..4eecd34f8 100644 --- a/controls/V-71961.rb +++ b/controls/V-71961.rb @@ -1,6 +1,5 @@ # encoding: utf-8 # - grub_superusers = input( 'grub_superusers', description: 'superusers for grub boot ( array )', @@ -75,18 +74,60 @@ # mv /tmp/grub2.cfg /boot/grub2/grub.cfg " tag "fix_id": "F-78313r2_fix" - describe file(grub_main_cfg) do - its('content') { should match %r{^\s*password_pbkdf2\s+root } } + + grub_main_content = file(grub_main_cfg).content + + # Check if any additional superusers are set + pattern = %r{\s*set superusers=\"(\w+)\"}i + matches = grub_main_content.match(pattern) + superusers = matches.nil? ? [] : matches.captures + describe "There must be only one grub2 superuser, and it must have the value #{grub_superuser}" do + subject { superusers } + its('length') { should cmp 1 } + its('first') { should cmp grub_superuser } end - grub_user_boot_files.each do |user_cfg_file| - next if !file(user_cfg_file).exist? - describe.one do - grub_superusers.each do |user| - describe file(user_cfg_file) do - its('content') { should match %r{^\s*password_pbkdf2\s+#{user} } } + # Need each password entry that has the superuser + pattern = %r{(.*)\s#{grub_superuser}\s}i + matches = grub_main_content.match(pattern) + password_entries = matches.nil? ? [] : matches.captures + # Each of the entries should start with password_pbkdf2 + describe 'The grub2 superuser password entry must begin with \'password_pbkdf2\'' do + subject { password_entries } + its('length') { is_expected.to be >= 1} + password_entries.each do |entry| + subject { entry } + it { should include 'password_pbkdf2'} + end + end + + # Get lines such as 'password_pbkdf2 root ${ENV}' + pattern = %r{password_pbkdf2\s#{grub_superuser}\s(\${\w+})}i + matches = grub_main_content.match(pattern) + env_vars = matches.nil? ? [] : matches.captures + if env_vars.length > 0 + # If there is an environment variable in the configuration file check that it is set with correct values by looking + # in user.cfg files. + env_vars = env_vars.map { |env_var| env_var.gsub(/[${}]/, '') } + present_user_boot_files = grub_user_boot_files.select { |user_boot_file| file(user_boot_file).exist? } + describe 'grub2 user configuration files for the superuser should be present if they set an environment variable' do + subject { present_user_boot_files } + its('length') { is_expected.to be >= 1 } + present_user_boot_files.each do |user_boot_file| + env_vars.each do |env_var| + describe "#{user_boot_file} should set #{env_var} to a pbkdf2 value" do + subject { file(user_boot_file) } + its('content') { should match %r{^#{env_var}=grub.pbkdf2}i } + end end end end + else + # If there are no environment variable set, look for pbkdf2 after the superuser name + pattern = %r{password_pbkdf2\s#{grub_superuser}\sgrub\.pbkdf2}i + describe 'The grub2 superuser account password should be encrypted with pbkdf2.' do + subject { grub_main_content } + it { should match pattern } + end end end