inspec-core 5.22.72 → 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Chef-EULA +9 -0
 - data/Gemfile +24 -38
 - data/etc/features.sig +6 -0
 - data/etc/features.yaml +94 -0
 - data/inspec-core.gemspec +16 -15
 - data/lib/inspec/backend.rb +2 -0
 - data/lib/inspec/base_cli.rb +80 -4
 - data/lib/inspec/cached_fetcher.rb +24 -3
 - data/lib/inspec/cli.rb +292 -235
 - data/lib/inspec/config.rb +24 -11
 - data/lib/inspec/dependencies/cache.rb +33 -0
 - data/lib/inspec/dependencies/dependency_set.rb +2 -2
 - data/lib/inspec/dsl.rb +1 -1
 - data/lib/inspec/enhanced_outcomes.rb +1 -0
 - data/lib/inspec/errors.rb +5 -0
 - data/lib/inspec/exceptions.rb +2 -0
 - data/lib/inspec/feature/config.rb +75 -0
 - data/lib/inspec/feature/runner.rb +26 -0
 - data/lib/inspec/feature.rb +34 -0
 - data/lib/inspec/fetcher/git.rb +5 -0
 - data/lib/inspec/fetcher/url.rb +7 -29
 - data/lib/inspec/globals.rb +6 -0
 - data/lib/inspec/input_registry.rb +1 -5
 - data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
 - data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
 - data/lib/inspec/profile.rb +46 -3
 - data/lib/inspec/reporters/cli.rb +1 -1
 - data/lib/inspec/reporters.rb +67 -54
 - data/lib/inspec/resources/groups.rb +0 -52
 - data/lib/inspec/resources/nftables.rb +1 -14
 - data/lib/inspec/resources/oracledb_session.rb +3 -9
 - data/lib/inspec/resources/postgres_session.rb +5 -9
 - data/lib/inspec/resources/sybase_session.rb +2 -11
 - data/lib/inspec/resources/virtualization.rb +1 -1
 - data/lib/inspec/rule.rb +9 -14
 - data/lib/inspec/run_data.rb +7 -5
 - data/lib/inspec/runner.rb +35 -6
 - data/lib/inspec/runner_rspec.rb +12 -9
 - data/lib/inspec/secrets/yaml.rb +9 -3
 - data/lib/inspec/shell.rb +10 -0
 - data/lib/inspec/ui.rb +4 -0
 - data/lib/inspec/utils/licensing_config.rb +9 -0
 - data/lib/inspec/utils/profile_ast_helpers.rb +2 -1
 - data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
 - data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
 - data/lib/inspec/version.rb +1 -1
 - data/lib/inspec/waiver_file_reader.rb +68 -27
 - data/lib/inspec.rb +2 -1
 - data/lib/matchers/matchers.rb +3 -3
 - data/lib/plugins/inspec-compliance/README.md +1 -11
 - data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +189 -170
 - data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
 - data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
 - data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
 - data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
 - data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
 - data/lib/plugins/inspec-license/README.md +16 -0
 - data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
 - data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
 - data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
 - data/lib/plugins/inspec-parallel/README.md +27 -0
 - data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
 - data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
 - data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +10 -11
 - data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
 - data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
 - data/lib/source_readers/inspec.rb +1 -1
 - metadata +45 -25
 
    
        data/lib/inspec/reporters.rb
    CHANGED
    
    | 
         @@ -4,76 +4,89 @@ require "inspec/reporters/json" 
     | 
|
| 
       4 
4 
     | 
    
         
             
            require "inspec/reporters/json_automate"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "inspec/reporters/automate"
         
     | 
| 
       6 
6 
     | 
    
         
             
            require "inspec/reporters/yaml"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "inspec/feature"
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            module Inspec::Reporters
         
     | 
| 
       9 
10 
     | 
    
         
             
              # rubocop:disable Metrics/CyclomaticComplexity
         
     | 
| 
       10 
11 
     | 
    
         
             
              def self.render(reporter, run_data, enhanced_outcomes = false)
         
     | 
| 
       11 
12 
     | 
    
         
             
                name, config = reporter.dup
         
     | 
| 
       12 
     | 
    
         
            -
                 
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                   
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                   
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
                Inspec.with_feature("inspec-reporter-#{name}") {
         
     | 
| 
      
 14 
     | 
    
         
            +
                  config[:run_data] = run_data
         
     | 
| 
      
 15 
     | 
    
         
            +
                  case name
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when "cli"
         
     | 
| 
      
 17 
     | 
    
         
            +
                    reporter = Inspec::Reporters::CLI.new(config)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  when "json"
         
     | 
| 
      
 19 
     | 
    
         
            +
                    reporter = Inspec::Reporters::Json.new(config)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # This reporter is only used for Chef internal. We reserve the
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # right to introduce breaking changes to this reporter at any time.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  when "json-automate"
         
     | 
| 
      
 23 
     | 
    
         
            +
                    reporter = Inspec::Reporters::JsonAutomate.new(config)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  when "automate"
         
     | 
| 
      
 25 
     | 
    
         
            +
                    reporter = Inspec::Reporters::Automate.new(config)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  when "yaml"
         
     | 
| 
      
 27 
     | 
    
         
            +
                    reporter = Inspec::Reporters::Yaml.new(config)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  else
         
     | 
| 
      
 29 
     | 
    
         
            +
                    # If we made it here, it must be a plugin, and we know it exists (because we validated it in config.rb)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    activator = Inspec::Plugin::V2::Registry.instance.find_activator(plugin_type: :reporter, activator_name: name.to_sym)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    activator.activate!
         
     | 
| 
      
 32 
     | 
    
         
            +
                    reporter = activator.implementation_class.new(config)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
                  if enhanced_outcomes
         
     | 
| 
      
 36 
     | 
    
         
            +
                    Inspec.with_feature("inspec-enhanced-outcomes") {
         
     | 
| 
      
 37 
     | 
    
         
            +
                      reporter.enhanced_outcomes = enhanced_outcomes
         
     | 
| 
      
 38 
     | 
    
         
            +
                    }
         
     | 
| 
      
 39 
     | 
    
         
            +
                  else
         
     | 
| 
      
 40 
     | 
    
         
            +
                    reporter.enhanced_outcomes = enhanced_outcomes
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
       36 
42 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 43 
     | 
    
         
            +
                  # optional send_report method on reporter
         
     | 
| 
      
 44 
     | 
    
         
            +
                  return reporter.send_report if defined?(reporter.send_report)
         
     | 
| 
       39 
45 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 46 
     | 
    
         
            +
                  reporter.render
         
     | 
| 
      
 47 
     | 
    
         
            +
                  output = reporter.rendered_output
         
     | 
| 
      
 48 
     | 
    
         
            +
                  config_file = config["file"]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if config_file
         
     | 
| 
      
 50 
     | 
    
         
            +
                    config_file.gsub!("CHILD_PID", Process.pid.to_s)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    # create destination directory if it does not exist
         
     | 
| 
      
 52 
     | 
    
         
            +
                    dirname = File.dirname(config_file)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
         
     | 
| 
       44 
54 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 55 
     | 
    
         
            +
                    File.write(config_file, output)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  elsif config["stdout"] == true
         
     | 
| 
      
 57 
     | 
    
         
            +
                    print output
         
     | 
| 
      
 58 
     | 
    
         
            +
                    $stdout.flush
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                }
         
     | 
| 
       50 
61 
     | 
    
         
             
              end
         
     | 
| 
       51 
62 
     | 
    
         | 
| 
       52 
63 
     | 
    
         
             
              def self.report(reporter, run_data)
         
     | 
| 
       53 
64 
     | 
    
         
             
                name, config = reporter.dup
         
     | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                   
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                     
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 65 
     | 
    
         
            +
                Inspec.with_feature("inspec-reporter-#{name}") {
         
     | 
| 
      
 66 
     | 
    
         
            +
                  config[:run_data] = run_data
         
     | 
| 
      
 67 
     | 
    
         
            +
                  case name
         
     | 
| 
      
 68 
     | 
    
         
            +
                  when "json"
         
     | 
| 
      
 69 
     | 
    
         
            +
                    reporter = Inspec::Reporters::Json.new(config)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  when "json-automate"
         
     | 
| 
      
 71 
     | 
    
         
            +
                    reporter = Inspec::Reporters::JsonAutomate.new(config)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  when "yaml"
         
     | 
| 
      
 73 
     | 
    
         
            +
                    reporter = Inspec::Reporters::Yaml.new(config)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  else
         
     | 
| 
      
 75 
     | 
    
         
            +
                    # If we made it here, it might be a plugin
         
     | 
| 
      
 76 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 77 
     | 
    
         
            +
                      activator = Inspec::Plugin::V2::Registry.instance.find_activator(plugin_type: :reporter, activator_name: name.to_sym)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      activator.activate!
         
     | 
| 
      
 79 
     | 
    
         
            +
                      reporter = activator.implementation_class.new(config)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      unless reporter.respond_to(:report?)
         
     | 
| 
      
 81 
     | 
    
         
            +
                        return run_data
         
     | 
| 
      
 82 
     | 
    
         
            +
                      end
         
     | 
| 
      
 83 
     | 
    
         
            +
                    rescue Inspec::Plugin::V2::LoadError
         
     | 
| 
      
 84 
     | 
    
         
            +
                      # Must not have been a plugin - just return the run_data
         
     | 
| 
       69 
85 
     | 
    
         
             
                      return run_data
         
     | 
| 
       70 
86 
     | 
    
         
             
                    end
         
     | 
| 
       71 
     | 
    
         
            -
                  rescue Inspec::Plugin::V2::LoadError
         
     | 
| 
       72 
     | 
    
         
            -
                    # Must not have been a plugin - just return the run_data
         
     | 
| 
       73 
     | 
    
         
            -
                    return run_data
         
     | 
| 
       74 
87 
     | 
    
         
             
                  end
         
     | 
| 
       75 
     | 
    
         
            -
                end
         
     | 
| 
       76 
88 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 89 
     | 
    
         
            +
                  reporter.report
         
     | 
| 
      
 90 
     | 
    
         
            +
                }
         
     | 
| 
       78 
91 
     | 
    
         
             
              end
         
     | 
| 
       79 
92 
     | 
    
         
             
            end
         
     | 
| 
         @@ -200,60 +200,8 @@ module Inspec::Resources 
     | 
|
| 
       200 
200 
     | 
    
         
             
              # implements generic unix groups via /etc/group
         
     | 
| 
       201 
201 
     | 
    
         
             
              class UnixGroup < GroupInfo
         
     | 
| 
       202 
202 
     | 
    
         
             
                def groups
         
     | 
| 
       203 
     | 
    
         
            -
                  get_group_info
         
     | 
| 
       204 
     | 
    
         
            -
                end
         
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
                private
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
                def get_group_info
         
     | 
| 
       209 
     | 
    
         
            -
                  # First, try to fetch group info using getent
         
     | 
| 
       210 
     | 
    
         
            -
                  group_info = fetch_group_info_using_getent
         
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
                  return group_info unless group_info.empty?
         
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
                  # If getent fails, fallback to reading group info from /etc/group using inspec.etc_group.entries
         
     | 
| 
       215 
     | 
    
         
            -
                  Inspec::Log.debug("Falling back to reading group info from /etc/group as getent is unavailable or failed.")
         
     | 
| 
       216 
203 
     | 
    
         
             
                  inspec.etc_group.entries
         
     | 
| 
       217 
204 
     | 
    
         
             
                end
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                # Fetches group information using the getent utility
         
     | 
| 
       220 
     | 
    
         
            -
                def fetch_group_info_using_getent
         
     | 
| 
       221 
     | 
    
         
            -
                  # Find getent utility on the system
         
     | 
| 
       222 
     | 
    
         
            -
                  bin = find_getent_utility
         
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
                  # If getent is available, fetch group info
         
     | 
| 
       225 
     | 
    
         
            -
                  return [] unless bin
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
                  cmd = inspec.command("#{bin} group")
         
     | 
| 
       228 
     | 
    
         
            -
                  return parse_group_info(cmd) if cmd.exit_status.to_i == 0
         
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
                  # If getent fails, log the error and return an empty array
         
     | 
| 
       231 
     | 
    
         
            -
                  Inspec::Log.debug("Failed to execute #{bin} group: #{cmd.stderr}.")
         
     | 
| 
       232 
     | 
    
         
            -
                  []
         
     | 
| 
       233 
     | 
    
         
            -
                end
         
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
                # Parses group info from the command output
         
     | 
| 
       236 
     | 
    
         
            -
                def parse_group_info(cmd)
         
     | 
| 
       237 
     | 
    
         
            -
                  cmd.stdout.strip.split("\n").map do |line|
         
     | 
| 
       238 
     | 
    
         
            -
                    name, password, gid, members = line.split(":")
         
     | 
| 
       239 
     | 
    
         
            -
                    {
         
     | 
| 
       240 
     | 
    
         
            -
                      "name" => name,
         
     | 
| 
       241 
     | 
    
         
            -
                      "password" => password,
         
     | 
| 
       242 
     | 
    
         
            -
                      "gid" => gid.to_i,
         
     | 
| 
       243 
     | 
    
         
            -
                      "members" => members,
         
     | 
| 
       244 
     | 
    
         
            -
                    }
         
     | 
| 
       245 
     | 
    
         
            -
                  end
         
     | 
| 
       246 
     | 
    
         
            -
                end
         
     | 
| 
       247 
     | 
    
         
            -
             
     | 
| 
       248 
     | 
    
         
            -
                # Checks if getent exists on the system
         
     | 
| 
       249 
     | 
    
         
            -
                def find_getent_utility
         
     | 
| 
       250 
     | 
    
         
            -
                  %w{/usr/bin/getent /bin/getent getent}.each do |cmd|
         
     | 
| 
       251 
     | 
    
         
            -
                    return cmd if inspec.command(cmd).exist?
         
     | 
| 
       252 
     | 
    
         
            -
                  end
         
     | 
| 
       253 
     | 
    
         
            -
                  # Log debug information if getent is not found
         
     | 
| 
       254 
     | 
    
         
            -
                  Inspec::Log.debug("Could not find `getent` on your system.")
         
     | 
| 
       255 
     | 
    
         
            -
                  nil # Return nil if getent is not found
         
     | 
| 
       256 
     | 
    
         
            -
                end
         
     | 
| 
       257 
205 
     | 
    
         
             
              end
         
     | 
| 
       258 
206 
     | 
    
         | 
| 
       259 
207 
     | 
    
         
             
              # OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
         
     | 
| 
         @@ -135,20 +135,7 @@ module Inspec::Resources 
     | 
|
| 
       135 
135 
     | 
    
         
             
                  cmd = inspec.command(nftables_cmd)
         
     | 
| 
       136 
136 
     | 
    
         
             
                  return [] if cmd.exit_status.to_i != 0
         
     | 
| 
       137 
137 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
                   
     | 
| 
       139 
     | 
    
         
            -
                  # Update @nftables_cache with sanitized command output
         
     | 
| 
       140 
     | 
    
         
            -
                  @nftables_cache[idx] = cmd.stdout.gsub("\t", "").split("\n")
         
     | 
| 
       141 
     | 
    
         
            -
                    .reject { |line| line =~ /^(table|set|type|size|flags|typeof|auto-merge)/ || line =~ /^}$/ } # Reject lines that match certain patterns
         
     | 
| 
       142 
     | 
    
         
            -
                    .map { |line| line.gsub("elements = {", "").gsub("}", "").split(",") } # Use gsub to replace all occurrences of specified strings
         
     | 
| 
       143 
     | 
    
         
            -
                    .flatten # Flatten the array of arrays into a single array
         
     | 
| 
       144 
     | 
    
         
            -
                    .map(&:strip) # Remove leading and trailing whitespace from each element
         
     | 
| 
       145 
     | 
    
         
            -
                    .map { |element| sanitize_input(element) } # Sanitize each element to prevent injection attacks
         
     | 
| 
       146 
     | 
    
         
            -
                end
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
                # Method to sanitize input
         
     | 
| 
       149 
     | 
    
         
            -
                def sanitize_input(input)
         
     | 
| 
       150 
     | 
    
         
            -
                  # Replace potentially dangerous characters with their escaped counterparts
         
     | 
| 
       151 
     | 
    
         
            -
                  input.gsub(/([\\'";])/, '\\\\\1')
         
     | 
| 
      
 138 
     | 
    
         
            +
                  @nftables_cache[idx] = cmd.stdout.gsub("\t", "").split("\n").reject { |line| line =~ /^(table|set|type|size|flags|typeof|auto-merge)/ || line =~ /^}$/ }.map { |line| line.sub("elements = {", "").sub("}", "").split(",") }.flatten.map(&:strip)
         
     | 
| 
       152 
139 
     | 
    
         
             
                end
         
     | 
| 
       153 
140 
     | 
    
         | 
| 
       154 
141 
     | 
    
         
             
                def retrieve_chain_rules
         
     | 
| 
         @@ -57,7 +57,7 @@ module Inspec::Resources 
     | 
|
| 
       57 
57 
     | 
    
         
             
                  inspec_cmd = inspec.command(command)
         
     | 
| 
       58 
58 
     | 
    
         
             
                  out = inspec_cmd.stdout + "\n" + inspec_cmd.stderr
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                  if inspec_cmd.exit_status != 0 || out.downcase =~ /^error.*/
         
     | 
| 
      
 60 
     | 
    
         
            +
                  if inspec_cmd.exit_status != 0 || !inspec_cmd.stderr.empty? || out.downcase =~ /^error.*/
         
     | 
| 
       61 
61 
     | 
    
         
             
                    raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}"
         
     | 
| 
       62 
62 
     | 
    
         
             
                  else
         
     | 
| 
       63 
63 
     | 
    
         
             
                    begin
         
     | 
| 
         @@ -96,7 +96,8 @@ module Inspec::Resources 
     | 
|
| 
       96 
96 
     | 
    
         
             
                  if @db_role.nil? || @su_user.nil?
         
     | 
| 
       97 
97 
     | 
    
         
             
                    verified_query = verify_query(query)
         
     | 
| 
       98 
98 
     | 
    
         
             
                  else
         
     | 
| 
       99 
     | 
    
         
            -
                    escaped_query =  
     | 
| 
      
 99 
     | 
    
         
            +
                    escaped_query = query.gsub(/\\\\/, "\\").gsub(/"/, '\\"')
         
     | 
| 
      
 100 
     | 
    
         
            +
                    escaped_query = escaped_query.gsub("$", '\\$') unless escaped_query.include? "\\$"
         
     | 
| 
       100 
101 
     | 
    
         
             
                    verified_query = verify_query(escaped_query)
         
     | 
| 
       101 
102 
     | 
    
         
             
                  end
         
     | 
| 
       102 
103 
     | 
    
         | 
| 
         @@ -133,17 +134,10 @@ module Inspec::Resources 
     | 
|
| 
       133 
134 
     | 
    
         
             
                  query
         
     | 
| 
       134 
135 
     | 
    
         
             
                end
         
     | 
| 
       135 
136 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
                def escape_query(query)
         
     | 
| 
       137 
     | 
    
         
            -
                  escaped_query = query.gsub(/\\\\/, "\\").gsub(/"/, '\\"')
         
     | 
| 
       138 
     | 
    
         
            -
                  escaped_query = escaped_query.gsub("$", '\\$') unless escaped_query.include? "\\$"
         
     | 
| 
       139 
     | 
    
         
            -
                  escaped_query
         
     | 
| 
       140 
     | 
    
         
            -
                end
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
137 
     | 
    
         
             
                def parse_csv_result(stdout)
         
     | 
| 
       143 
138 
     | 
    
         
             
                  output = stdout.split("oracle_query_string")[-1]
         
     | 
| 
       144 
139 
     | 
    
         
             
                  # comma_query_sub replaces the csv delimiter "," in the output.
         
     | 
| 
       145 
140 
     | 
    
         
             
                  # Handles CSV parsing of data like this (DROP,3) etc
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
141 
     | 
    
         
             
                  output = output.sub(/\r/, "").strip.gsub(",", "comma_query_sub")
         
     | 
| 
       148 
142 
     | 
    
         
             
                  converter = ->(header) { header.downcase }
         
     | 
| 
       149 
143 
     | 
    
         
             
                  CSV.parse(output, headers: true, header_converters: converter).map do |row|
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # copyright: 2015, Vulcano Security GmbH
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require "shellwords" unless defined?(Shellwords)
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       5 
5 
     | 
    
         
             
            module Inspec::Resources
         
     | 
| 
       6 
6 
     | 
    
         
             
              class Lines
         
     | 
| 
       7 
7 
     | 
    
         
             
                attr_reader :output, :exit_status
         
     | 
| 
         @@ -55,7 +55,7 @@ module Inspec::Resources 
     | 
|
| 
       55 
55 
     | 
    
         
             
                  psql_cmd = create_psql_cmd(query, db)
         
     | 
| 
       56 
56 
     | 
    
         
             
                  cmd = inspec.command(psql_cmd, redact_regex: %r{(:\/\/[a-z]*:).*(@)})
         
     | 
| 
       57 
57 
     | 
    
         
             
                  out = cmd.stdout + "\n" + cmd.stderr
         
     | 
| 
       58 
     | 
    
         
            -
                  if cmd.exit_status != 0 && ( out =~ /could not connect to/ || out =~ /password authentication failed/ ) &&  
     | 
| 
      
 58 
     | 
    
         
            +
                  if cmd.exit_status != 0 && ( out =~ /could not connect to/ || out =~ /password authentication failed/ ) && out.downcase =~ /error:/
         
     | 
| 
       59 
59 
     | 
    
         
             
                    raise Inspec::Exceptions::ResourceFailed, "PostgreSQL connection error: #{out}"
         
     | 
| 
       60 
60 
     | 
    
         
             
                  elsif cmd.exit_status != 0 && out.downcase =~ /error:/
         
     | 
| 
       61 
61 
     | 
    
         
             
                    Lines.new(out, "PostgreSQL query with error: #{query}", cmd.exit_status)
         
     | 
| 
         @@ -74,10 +74,6 @@ module Inspec::Resources 
     | 
|
| 
       74 
74 
     | 
    
         
             
                  Shellwords.escape(query)
         
     | 
| 
       75 
75 
     | 
    
         
             
                end
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
                def encoded_password(password)
         
     | 
| 
       78 
     | 
    
         
            -
                  CGI.escape(password)
         
     | 
| 
       79 
     | 
    
         
            -
                end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
77 
     | 
    
         
             
                def create_psql_cmd(query, db = [])
         
     | 
| 
       82 
78 
     | 
    
         
             
                  dbs = db.map { |x| "#{x}" }.join(" ")
         
     | 
| 
       83 
79 
     | 
    
         | 
| 
         @@ -86,14 +82,14 @@ module Inspec::Resources 
     | 
|
| 
       86 
82 
     | 
    
         
             
                    # Socket connection only enabled for non-windows platforms
         
     | 
| 
       87 
83 
     | 
    
         
             
                    # Windows does not support unix domain sockets
         
     | 
| 
       88 
84 
     | 
    
         
             
                    option_port = @port.nil? ? "" : "-p #{@port}" # add explicit port if specified
         
     | 
| 
       89 
     | 
    
         
            -
                    "psql -d postgresql://#{@user}:#{ 
     | 
| 
      
 85 
     | 
    
         
            +
                    "psql -d postgresql://#{@user}:#{@pass}@/#{dbs}?host=#{@socket_path} #{option_port} -A -t -w -c #{escaped_query(query)}"
         
     | 
| 
       90 
86 
     | 
    
         
             
                  else
         
     | 
| 
       91 
87 
     | 
    
         
             
                    # Host in connection string establishes tcp/ip connection
         
     | 
| 
       92 
88 
     | 
    
         
             
                    if inspec.os.windows?
         
     | 
| 
       93 
89 
     | 
    
         
             
                      warn "Socket based connection not supported in windows, connecting using host" if @socket_path
         
     | 
| 
       94 
     | 
    
         
            -
                      "psql -d postgresql://#{@user}:#{ 
     | 
| 
      
 90 
     | 
    
         
            +
                      "psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c \"#{query}\""
         
     | 
| 
       95 
91 
     | 
    
         
             
                    else
         
     | 
| 
       96 
     | 
    
         
            -
                      "psql -d postgresql://#{@user}:#{ 
     | 
| 
      
 92 
     | 
    
         
            +
                      "psql -d postgresql://#{@user}:#{@pass}@#{@host}:#{@port}/#{dbs} -A -t -w -c #{escaped_query(query)}"
         
     | 
| 
       97 
93 
     | 
    
         
             
                    end
         
     | 
| 
       98 
94 
     | 
    
         
             
                  end
         
     | 
| 
       99 
95 
     | 
    
         
             
                end
         
     | 
| 
         @@ -44,19 +44,10 @@ module Inspec::Resources 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  # try to get a temp path
         
     | 
| 
       45 
45 
     | 
    
         
             
                  sql_file_path = upload_sql_file(sql)
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                  # TODO: Find if there is better way to get the current shell
         
     | 
| 
       48 
     | 
    
         
            -
                  current_shell = inspec.command("echo $SHELL")
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  res = current_shell.exit_status
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
47 
     | 
    
         
             
                  # isql reuires that we have a matching locale set, but does not support C.UTF-8. en_US.UTF-8 is the least evil.
         
     | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
       54 
     | 
    
         
            -
                    command = "source #{sybase_home}/SYBASE.csh; setenv LANG en_US.UTF-8; #{bin} -s\"#{col_sep}\" -w80000 -S #{server} -U #{username} -D #{database} -P \"#{password}\" < #{sql_file_path}"
         
     | 
| 
       55 
     | 
    
         
            -
                  else
         
     | 
| 
       56 
     | 
    
         
            -
                    command = "LANG=en_US.UTF-8 SYBASE=#{sybase_home} #{bin} -s\"#{col_sep}\" -w80000 -S #{server} -U #{username} -D #{database} -P \"#{password}\" < #{sql_file_path}"
         
     | 
| 
       57 
     | 
    
         
            -
                  end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
                  command = "LANG=en_US.UTF-8 SYBASE=#{sybase_home} #{bin} -s\"#{col_sep}\" -w80000 -S #{server} -U #{username} -D #{database} -P \"#{password}\" < #{sql_file_path}"
         
     | 
| 
       59 
49 
     | 
    
         
             
                  isql_cmd = inspec.command(command)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       60 
51 
     | 
    
         
             
                  # Check for isql errors
         
     | 
| 
       61 
52 
     | 
    
         
             
                  res = isql_cmd.exit_status
         
     | 
| 
       62 
53 
     | 
    
         
             
                  raise Inspec::Exceptions::ResourceFailed.new("isql exited with code #{res} and stderr '#{isql_cmd.stderr}', stdout '#{isql_cmd.stdout}'") unless res == 0
         
     | 
| 
         @@ -223,7 +223,7 @@ module Inspec::Resources 
     | 
|
| 
       223 
223 
     | 
    
         
             
                  elsif cgroup_content =~ %r{^\d+:[^:]+:/(kubepods)/.+$}
         
     | 
| 
       224 
224 
     | 
    
         
             
                    @virtualization_data[:system] = $1
         
     | 
| 
       225 
225 
     | 
    
         
             
                    @virtualization_data[:role] = "guest"
         
     | 
| 
       226 
     | 
    
         
            -
                  elsif /container=podman/.match?( 
     | 
| 
      
 226 
     | 
    
         
            +
                  elsif /container=podman/.match?(file_read("/proc/1/environ"))
         
     | 
| 
       227 
227 
     | 
    
         
             
                    @virtualization_data[:system] = "podman"
         
     | 
| 
       228 
228 
     | 
    
         
             
                    @virtualization_data[:role] = "guest"
         
     | 
| 
       229 
229 
     | 
    
         
             
                  elsif lxc_version_exists? && cgroup_content =~ %r{\d:[^:]+:/$}
         
     | 
    
        data/lib/inspec/rule.rb
    CHANGED
    
    | 
         @@ -375,24 +375,19 @@ module Inspec 
     | 
|
| 
       375 
375 
     | 
    
         
             
                # only_if mechanism)
         
     | 
| 
       376 
376 
     | 
    
         
             
                # Double underscore: not intended to be called as part of the DSL
         
     | 
| 
       377 
377 
     | 
    
         
             
                def __apply_waivers
         
     | 
| 
       378 
     | 
    
         
            -
                  @__waiver_data = nil
         
     | 
| 
       379 
378 
     | 
    
         
             
                  control_id = @__rule_id # TODO: control ID slugging
         
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
       381 
379 
     | 
    
         
             
                  waiver_files = Inspec::Config.cached.final_options["waiver_file"] if Inspec::Config.cached.respond_to?(:final_options)
         
     | 
| 
       382 
     | 
    
         
            -
                  unless waiver_files.nil? || waiver_files.empty?
         
     | 
| 
       383 
     | 
    
         
            -
                    waiver_data_by_profile = Inspec::WaiverFileReader.fetch_waivers_by_profile(__profile_id, waiver_files)
         
     | 
| 
       384 
     | 
    
         
            -
                    return unless waiver_data_by_profile && waiver_data_by_profile[control_id] && waiver_data_by_profile[control_id].is_a?(Hash)
         
     | 
| 
       385 
380 
     | 
    
         | 
| 
       386 
     | 
    
         
            -
             
     | 
| 
       387 
     | 
    
         
            -
                  else
         
     | 
| 
       388 
     | 
    
         
            -
                    # Support for input registry is provided for backward compatibilty with compliance phase of chef-client
         
     | 
| 
       389 
     | 
    
         
            -
                    # Chef-client sends waiver information in inputs hash
         
     | 
| 
       390 
     | 
    
         
            -
                    input_registry = Inspec::InputRegistry.instance
         
     | 
| 
       391 
     | 
    
         
            -
                    waiver_data_via_input = input_registry.inputs_by_profile.dig(__profile_id, control_id)
         
     | 
| 
       392 
     | 
    
         
            -
                    return unless waiver_data_via_input && waiver_data_via_input.has_value? && waiver_data_via_input.value.is_a?(Hash)
         
     | 
| 
      
 381 
     | 
    
         
            +
                  waiver_data_by_profile = Inspec::WaiverFileReader.fetch_waivers_by_profile(__profile_id, waiver_files) unless waiver_files.nil?
         
     | 
| 
       393 
382 
     | 
    
         | 
| 
       394 
     | 
    
         
            -
             
     | 
| 
       395 
     | 
    
         
            -
             
     | 
| 
      
 383 
     | 
    
         
            +
                  return unless waiver_data_by_profile && waiver_data_by_profile[control_id] && waiver_data_by_profile[control_id].is_a?(Hash)
         
     | 
| 
      
 384 
     | 
    
         
            +
             
     | 
| 
      
 385 
     | 
    
         
            +
                  # An InSpec Input is a datastructure that tracks a profile parameter
         
     | 
| 
      
 386 
     | 
    
         
            +
                  # over time. Its value can be set by many sources, and it keeps a
         
     | 
| 
      
 387 
     | 
    
         
            +
                  # log of each "set" event so that when it is collapsed to a value,
         
     | 
| 
      
 388 
     | 
    
         
            +
                  # it can determine the correct (highest priority) value.
         
     | 
| 
      
 389 
     | 
    
         
            +
                  # Store in an instance variable for.. later reading???
         
     | 
| 
      
 390 
     | 
    
         
            +
                  @__waiver_data = waiver_data_by_profile[control_id]
         
     | 
| 
       396 
391 
     | 
    
         | 
| 
       397 
392 
     | 
    
         
             
                  __waiver_data["skipped_due_to_waiver"] = false
         
     | 
| 
       398 
393 
     | 
    
         
             
                  __waiver_data["message"] = ""
         
     | 
    
        data/lib/inspec/run_data.rb
    CHANGED
    
    | 
         @@ -27,11 +27,13 @@ module Inspec 
     | 
|
| 
       27 
27 
     | 
    
         
             
              ) do
         
     | 
| 
       28 
28 
     | 
    
         
             
                include HashLikeStruct
         
     | 
| 
       29 
29 
     | 
    
         
             
                def initialize(raw_run_data)
         
     | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                  self. 
     | 
| 
       33 
     | 
    
         
            -
                  self. 
     | 
| 
       34 
     | 
    
         
            -
                  self. 
     | 
| 
      
 30 
     | 
    
         
            +
                  @raw_run_data = raw_run_data
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  self.controls   = @raw_run_data[:controls].map { |c| Inspec::RunData::Control.new(c) }
         
     | 
| 
      
 33 
     | 
    
         
            +
                  self.profiles   = @raw_run_data[:profiles].map { |p| Inspec::RunData::Profile.new(p) }
         
     | 
| 
      
 34 
     | 
    
         
            +
                  self.statistics = Inspec::RunData::Statistics.new(@raw_run_data[:statistics])
         
     | 
| 
      
 35 
     | 
    
         
            +
                  self.platform   = Inspec::RunData::Platform.new(@raw_run_data[:platform])
         
     | 
| 
      
 36 
     | 
    
         
            +
                  self.version    = @raw_run_data[:version]
         
     | 
| 
       35 
37 
     | 
    
         
             
                end
         
     | 
| 
       36 
38 
     | 
    
         
             
              end
         
     | 
| 
       37 
39 
     | 
    
         | 
    
        data/lib/inspec/runner.rb
    CHANGED
    
    | 
         @@ -11,6 +11,7 @@ require "inspec/dependencies/cache" 
     | 
|
| 
       11 
11 
     | 
    
         
             
            require "inspec/dist"
         
     | 
| 
       12 
12 
     | 
    
         
             
            require "inspec/reporters"
         
     | 
| 
       13 
13 
     | 
    
         
             
            require "inspec/runner_rspec"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require "chef-licensing"
         
     | 
| 
       14 
15 
     | 
    
         
             
            # spec requirements
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
            module Inspec
         
     | 
| 
         @@ -60,11 +61,13 @@ module Inspec 
     | 
|
| 
       60 
61 
     | 
    
         
             
                  end
         
     | 
| 
       61 
62 
     | 
    
         | 
| 
       62 
63 
     | 
    
         
             
                  if @conf[:waiver_file]
         
     | 
| 
       63 
     | 
    
         
            -
                     
     | 
| 
       64 
     | 
    
         
            -
                       
     | 
| 
       65 
     | 
    
         
            -
                         
     | 
| 
      
 64 
     | 
    
         
            +
                    Inspec.with_feature("inspec-waivers") {
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @conf[:waiver_file].each do |file|
         
     | 
| 
      
 66 
     | 
    
         
            +
                        unless File.file?(file)
         
     | 
| 
      
 67 
     | 
    
         
            +
                          raise Inspec::Exceptions::WaiversFileDoesNotExist, "Waiver file #{file} does not exist."
         
     | 
| 
      
 68 
     | 
    
         
            +
                        end
         
     | 
| 
       66 
69 
     | 
    
         
             
                      end
         
     | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
      
 70 
     | 
    
         
            +
                    }
         
     | 
| 
       68 
71 
     | 
    
         
             
                  end
         
     | 
| 
       69 
72 
     | 
    
         | 
| 
       70 
73 
     | 
    
         
             
                  # About reading inputs:
         
     | 
| 
         @@ -142,7 +145,7 @@ module Inspec 
     | 
|
| 
       142 
145 
     | 
    
         
             
                        get_check_example(m, a, b)
         
     | 
| 
       143 
146 
     | 
    
         
             
                      end.compact
         
     | 
| 
       144 
147 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
                      examples.map { |example| total_checks += example. 
     | 
| 
      
 148 
     | 
    
         
            +
                      examples.map { |example| total_checks += example.examples.count }
         
     | 
| 
       146 
149 
     | 
    
         | 
| 
       147 
150 
     | 
    
         
             
                      unless control_describe_checks.empty?
         
     | 
| 
       148 
151 
     | 
    
         
             
                        # controls with empty tests are avoided
         
     | 
| 
         @@ -159,16 +162,42 @@ module Inspec 
     | 
|
| 
       159 
162 
     | 
    
         
             
                end
         
     | 
| 
       160 
163 
     | 
    
         | 
| 
       161 
164 
     | 
    
         
             
                def run(with = nil)
         
     | 
| 
      
 165 
     | 
    
         
            +
                  ChefLicensing.check_software_entitlement! if Inspec::Dist::EXEC_NAME == "inspec"
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  # Validate if profiles are signed and verified
         
     | 
| 
      
 168 
     | 
    
         
            +
                  # Additional check is required to provide error message in case of inspec exec command (exec command can use multiple profiles as well)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  # Only runs this block when preview flag CHEF_PREVIEW_MANDATORY_PROFILE_SIGNING is set
         
     | 
| 
      
 170 
     | 
    
         
            +
                  Inspec.with_feature("inspec-mandatory-profile-signing") {
         
     | 
| 
      
 171 
     | 
    
         
            +
                    unless @conf.allow_unsigned_profiles?
         
     | 
| 
      
 172 
     | 
    
         
            +
                      verify_target_profiles_if_signed(@target_profiles)
         
     | 
| 
      
 173 
     | 
    
         
            +
                    end
         
     | 
| 
      
 174 
     | 
    
         
            +
                  }
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
       162 
176 
     | 
    
         
             
                  Inspec::Log.debug "Starting run with targets: #{@target_profiles.map(&:to_s)}"
         
     | 
| 
       163 
177 
     | 
    
         
             
                  load
         
     | 
| 
       164 
178 
     | 
    
         
             
                  run_tests(with)
         
     | 
| 
      
 179 
     | 
    
         
            +
                rescue ChefLicensing::SoftwareNotEntitled
         
     | 
| 
      
 180 
     | 
    
         
            +
                  Inspec::Log.error "License is not entitled to use InSpec."
         
     | 
| 
      
 181 
     | 
    
         
            +
                  Inspec::UI.new.exit(:license_not_entitled)
         
     | 
| 
      
 182 
     | 
    
         
            +
                rescue ChefLicensing::Error => e
         
     | 
| 
      
 183 
     | 
    
         
            +
                  Inspec::Log.error e.message
         
     | 
| 
      
 184 
     | 
    
         
            +
                  Inspec::UI.new.exit(:usage_error)
         
     | 
| 
      
 185 
     | 
    
         
            +
                end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                def verify_target_profiles_if_signed(target_profiles)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  unsigned_profiles = []
         
     | 
| 
      
 189 
     | 
    
         
            +
                  target_profiles.each do |profile|
         
     | 
| 
      
 190 
     | 
    
         
            +
                    unsigned_profiles << profile.name unless profile.verify_if_signed
         
     | 
| 
      
 191 
     | 
    
         
            +
                  end
         
     | 
| 
      
 192 
     | 
    
         
            +
                  raise Inspec::ProfileSignatureRequired, "Signature required for profile/s: #{unsigned_profiles.join(", ")}. Please provide a signed profile. Or set CHEF_ALLOW_UNSIGNED_PROFILES in the environment. Or use `--allow-unsigned-profiles` flag with InSpec CLI. " unless unsigned_profiles.empty?
         
     | 
| 
       165 
193 
     | 
    
         
             
                end
         
     | 
| 
       166 
194 
     | 
    
         | 
| 
       167 
195 
     | 
    
         
             
                def render_output(run_data)
         
     | 
| 
       168 
196 
     | 
    
         
             
                  return if @conf["reporter"].nil?
         
     | 
| 
       169 
197 
     | 
    
         | 
| 
       170 
198 
     | 
    
         
             
                  @conf["reporter"].each do |reporter|
         
     | 
| 
       171 
     | 
    
         
            -
                     
     | 
| 
      
 199 
     | 
    
         
            +
                    enhanced_outcome_flag = @conf["enhanced_outcomes"]
         
     | 
| 
      
 200 
     | 
    
         
            +
                    result = Inspec::Reporters.render(reporter, run_data, enhanced_outcome_flag)
         
     | 
| 
       172 
201 
     | 
    
         
             
                    raise Inspec::ReporterError, "Error generating reporter '#{reporter[0]}'" if result == false
         
     | 
| 
       173 
202 
     | 
    
         
             
                  end
         
     | 
| 
       174 
203 
     | 
    
         
             
                end
         
     | 
    
        data/lib/inspec/runner_rspec.rb
    CHANGED
    
    | 
         @@ -177,16 +177,18 @@ module Inspec 
     | 
|
| 
       177 
177 
     | 
    
         
             
                    next unless streaming_reporters.include? streaming_reporter_name
         
     | 
| 
       178 
178 
     | 
    
         | 
| 
       179 
179 
     | 
    
         
             
                    # Activate the plugin so the formatter ID gets registered with RSpec, presumably
         
     | 
| 
       180 
     | 
    
         
            -
                    activator = reg.find_activator(plugin_type: :streaming_reporter, activator_name: streaming_reporter_name.to_sym)
         
     | 
| 
       181 
     | 
    
         
            -
                    activator.activate!
         
     | 
| 
       182 
180 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
                     
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
                       
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                       
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
      
 181 
     | 
    
         
            +
                    Inspec.with_feature("inspec-reporter-#{streaming_reporter_name}") {
         
     | 
| 
      
 182 
     | 
    
         
            +
                      activator = reg.find_activator(plugin_type: :streaming_reporter, activator_name: streaming_reporter_name.to_sym)
         
     | 
| 
      
 183 
     | 
    
         
            +
                      activator.activate!
         
     | 
| 
      
 184 
     | 
    
         
            +
                      # We cannot pass in a nil output path. Rspec only accepts a valid string or a IO object.
         
     | 
| 
      
 185 
     | 
    
         
            +
                      if file_target&.[]("file").nil?
         
     | 
| 
      
 186 
     | 
    
         
            +
                        RSpec.configuration.add_formatter(activator.implementation_class)
         
     | 
| 
      
 187 
     | 
    
         
            +
                      else
         
     | 
| 
      
 188 
     | 
    
         
            +
                        RSpec.configuration.add_formatter(activator.implementation_class, file_target["file"])
         
     | 
| 
      
 189 
     | 
    
         
            +
                      end
         
     | 
| 
      
 190 
     | 
    
         
            +
                      @conf["reporter"].delete(streaming_reporter_name)
         
     | 
| 
      
 191 
     | 
    
         
            +
                    }
         
     | 
| 
       190 
192 
     | 
    
         
             
                  end
         
     | 
| 
       191 
193 
     | 
    
         
             
                end
         
     | 
| 
       192 
194 
     | 
    
         | 
| 
         @@ -196,6 +198,7 @@ module Inspec 
     | 
|
| 
       196 
198 
     | 
    
         
             
                def configure_output
         
     | 
| 
       197 
199 
     | 
    
         
             
                  RSpec.configuration.output_stream = $stdout
         
     | 
| 
       198 
200 
     | 
    
         
             
                  @formatter = RSpec.configuration.add_formatter(Inspec::Formatters::Base)
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
       199 
202 
     | 
    
         
             
                  @formatter.enhanced_outcomes = @conf.final_options["enhanced_outcomes"]
         
     | 
| 
       200 
203 
     | 
    
         
             
                  RSpec.configuration.add_formatter(Inspec::Formatters::ShowProgress, $stderr) if @conf[:show_progress]
         
     | 
| 
       201 
204 
     | 
    
         
             
                  set_optional_formatters
         
     | 
    
        data/lib/inspec/secrets/yaml.rb
    CHANGED
    
    | 
         @@ -24,12 +24,18 @@ module Secrets 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    @inputs = ::YAML.load_file(target)
         
     | 
| 
       25 
25 
     | 
    
         
             
                  end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
                  # In case of empty yaml file raise the warning else raise the parsing error.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  if !@inputs || @inputs.empty?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    Inspec::Log.warn("Unable to parse #{target}: YAML file is empty.")
         
     | 
| 
       29 
30 
     | 
    
         
             
                    @inputs = nil
         
     | 
| 
      
 31 
     | 
    
         
            +
                  elsif !@inputs.is_a?(Hash)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    # Exits with usage error.
         
     | 
| 
      
 33 
     | 
    
         
            +
                    Inspec::Log.error("Unable to parse #{target}: invalid YAML or contents is not a Hash")
         
     | 
| 
      
 34 
     | 
    
         
            +
                    Inspec::UI.new.exit(:usage_error)
         
     | 
| 
       30 
35 
     | 
    
         
             
                  end
         
     | 
| 
       31 
36 
     | 
    
         
             
                rescue => e
         
     | 
| 
       32 
     | 
    
         
            -
                   
     | 
| 
      
 37 
     | 
    
         
            +
                  # Any other error related to Yaml parsing will be raised here.
         
     | 
| 
      
 38 
     | 
    
         
            +
                  raise "Error reading YAML file #{target}: #{e}"
         
     | 
| 
       33 
39 
     | 
    
         
             
                end
         
     | 
| 
       34 
40 
     | 
    
         
             
              end
         
     | 
| 
       35 
41 
     | 
    
         
             
            end
         
     | 
    
        data/lib/inspec/shell.rb
    CHANGED
    
    | 
         @@ -1,3 +1,6 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "chef-licensing"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "inspec/dist"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       1 
4 
     | 
    
         
             
            autoload :Pry, "pry"
         
     | 
| 
       2 
5 
     | 
    
         | 
| 
       3 
6 
     | 
    
         
             
            module Inspec
         
     | 
| 
         @@ -10,6 +13,7 @@ module Inspec 
     | 
|
| 
       10 
13 
     | 
    
         
             
                end
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
15 
     | 
    
         
             
                def start
         
     | 
| 
      
 16 
     | 
    
         
            +
                  ChefLicensing.check_software_entitlement! if Inspec::Dist::EXEC_NAME == "inspec"
         
     | 
| 
       13 
17 
     | 
    
         
             
                  # This will hold a single evaluation binding context as opened within
         
     | 
| 
       14 
18 
     | 
    
         
             
                  # the instance_eval context of the anonymous class that the profile
         
     | 
| 
       15 
19 
     | 
    
         
             
                  # context creates to evaluate each individual test file. We want to
         
     | 
| 
         @@ -18,6 +22,12 @@ module Inspec 
     | 
|
| 
       18 
22 
     | 
    
         
             
                  @ctx_binding = @runner.eval_with_virtual_profile("binding")
         
     | 
| 
       19 
23 
     | 
    
         
             
                  configure_pry
         
     | 
| 
       20 
24 
     | 
    
         
             
                  @ctx_binding.pry
         
     | 
| 
      
 25 
     | 
    
         
            +
                rescue ChefLicensing::SoftwareNotEntitled
         
     | 
| 
      
 26 
     | 
    
         
            +
                  Inspec::Log.error "License is not entitled to use InSpec."
         
     | 
| 
      
 27 
     | 
    
         
            +
                  Inspec::UI.new.exit(:license_not_entitled)
         
     | 
| 
      
 28 
     | 
    
         
            +
                rescue ChefLicensing::Error => e
         
     | 
| 
      
 29 
     | 
    
         
            +
                  Inspec::Log.error e.message
         
     | 
| 
      
 30 
     | 
    
         
            +
                  Inspec::UI.new.exit(:usage_error)
         
     | 
| 
       21 
31 
     | 
    
         
             
                end
         
     | 
| 
       22 
32 
     | 
    
         | 
| 
       23 
33 
     | 
    
         
             
                def configure_pry # rubocop:disable Metrics/AbcSize
         
     | 
    
        data/lib/inspec/ui.rb
    CHANGED
    
    | 
         @@ -32,9 +32,13 @@ module Inspec 
     | 
|
| 
       32 
32 
     | 
    
         
             
                EXIT_FATAL_DEPRECATION = 3
         
     | 
| 
       33 
33 
     | 
    
         
             
                EXIT_GEM_DEPENDENCY_LOAD_ERROR = 4
         
     | 
| 
       34 
34 
     | 
    
         
             
                EXIT_BAD_SIGNATURE = 5
         
     | 
| 
      
 35 
     | 
    
         
            +
                EXIT_SIGNATURE_REQUIRED = 6
         
     | 
| 
       35 
36 
     | 
    
         
             
                EXIT_LICENSE_NOT_ACCEPTED = 172
         
     | 
| 
      
 37 
     | 
    
         
            +
                EXIT_LICENSE_NOT_ENTITLED = 173
         
     | 
| 
      
 38 
     | 
    
         
            +
                EXIT_LICENSE_NOT_SET = 174
         
     | 
| 
       36 
39 
     | 
    
         
             
                EXIT_FAILED_TESTS = 100
         
     | 
| 
       37 
40 
     | 
    
         
             
                EXIT_SKIPPED_TESTS = 101
         
     | 
| 
      
 41 
     | 
    
         
            +
                EXIT_TERMINATED_BY_CTL_C = 130
         
     | 
| 
       38 
42 
     | 
    
         | 
| 
       39 
43 
     | 
    
         
             
                attr_reader :io
         
     | 
| 
       40 
44 
     | 
    
         | 
| 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "../log"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "chef-licensing"
         
     | 
| 
      
 3 
     | 
    
         
            +
            ChefLicensing.configure do |config|
         
     | 
| 
      
 4 
     | 
    
         
            +
              config.chef_product_name = "InSpec"
         
     | 
| 
      
 5 
     | 
    
         
            +
              config.chef_entitlement_id = "3ff52c37-e41f-4f6c-ad4d-365192205968"
         
     | 
| 
      
 6 
     | 
    
         
            +
              config.chef_executable_name = "inspec"
         
     | 
| 
      
 7 
     | 
    
         
            +
              config.license_server_url = "https://services.chef.io/licensing"
         
     | 
| 
      
 8 
     | 
    
         
            +
              config.logger = Inspec::Log
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -19,7 +19,7 @@ module Waivers 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    row_hash.delete("control_id")
         
     | 
| 
       20 
20 
     | 
    
         
             
                    row_hash.delete_if { |k, v| k.nil? || v.nil? }
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                    waiver_data_hash[control_id] = row_hash if control_id && ! 
     | 
| 
      
 22 
     | 
    
         
            +
                    waiver_data_hash[control_id] = row_hash if control_id && !row_hash.blank?
         
     | 
| 
       23 
23 
     | 
    
         
             
                  end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                  waiver_data_hash
         
     | 
| 
         @@ -25,7 +25,7 @@ module Waivers 
     | 
|
| 
       25 
25 
     | 
    
         
             
                      row_hash.delete_if { |k, v| k.nil? || v.nil? }
         
     | 
| 
       26 
26 
     | 
    
         
             
                    end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                    waiver_data_hash[control_id] = row_hash if control_id && ! 
     | 
| 
      
 28 
     | 
    
         
            +
                    waiver_data_hash[control_id] = row_hash if control_id && !row_hash.blank?
         
     | 
| 
       29 
29 
     | 
    
         
             
                  end
         
     | 
| 
       30 
30 
     | 
    
         
             
                  waiver_data_hash
         
     | 
| 
       31 
31 
     | 
    
         
             
                rescue Exception => e
         
     | 
    
        data/lib/inspec/version.rb
    CHANGED