inspec-core 4.22.22 → 4.23.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: feb9a92b579da111caf36845c7ba22e6d0831233d59c5f6f5de0212aa8ef529c
4
- data.tar.gz: 945341a0aa073b969ce15e35d058246af5584d3ddfb94a5b7ffbd86cb8162254
3
+ metadata.gz: a2786d0d36c3218a4d79f4578c4a814469115787d4470fa81d422b05b2025462
4
+ data.tar.gz: a0d30c7b81dbb4e58e6b9e8c0447f0855ce1f94f223c1f4f5861a03dfce2ce6c
5
5
  SHA512:
6
- metadata.gz: 148281428e3b5d2855a2c89eccb3a29e4b159933b025049d9852eab4336b9ffb0f267bb48701b208c06fc71ce2c173fe175466622b3ec535ddb4a2692d3d927f
7
- data.tar.gz: ac2e46f5dc21b7359b76df729d6b47c0f51f1f8bd272872121477204f3422d49028982a39a01df60a4ae796f03ccb41f6a448a994e22e2feb7e4d946b574cc27
6
+ metadata.gz: 915bbf9f4302c5fe2e8a41bc131b935bc42861cd4f76d0163ef1aeddc231cdbaf1f653ffd621bb79e5a531baa941e59852b34550d114bf30d95d4eb2ff5aa876
7
+ data.tar.gz: d7b5f80f550bf092aaa0faaf660225f99e3e4d6b600d9a89a45c0648b752a00cac5e30aaaf74fdb940bb135b2ae2ae02112f9617adbe6c25abc46c10d9492c5d
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  # Implementation dependencies
26
26
  spec.add_dependency "chef-telemetry", "~> 1.0"
27
- spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
27
+ spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
28
28
  spec.add_dependency "thor", ">= 0.20", "< 2.0"
29
29
  spec.add_dependency "json_schemer", ">= 0.2.1", "< 0.2.12"
30
30
  spec.add_dependency "method_source", ">= 0.8", "< 2.0"
@@ -158,6 +158,10 @@ module Inspec
158
158
  option :silence_deprecations, type: :array,
159
159
  banner: "[all]|[GROUP GROUP...]",
160
160
  desc: "Suppress deprecation warnings. See install_dir/etc/deprecations.json for list of GROUPs or use 'all'."
161
+ option :diff, type: :boolean, default: true,
162
+ desc: "Use --no-diff to suppress 'diff' output of failed textual test results."
163
+ option :sort_results_by, type: :string, default: "file", banner: "--sort-results-by=none|control|file|random",
164
+ desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
161
165
  end
162
166
 
163
167
  def self.format_platform_info(params: {}, indent: 0, color: 39)
@@ -405,6 +405,18 @@ module Inspec
405
405
  @plugin_cfg = data
406
406
  end
407
407
 
408
+ def validate_sort_results_by!(option_value)
409
+ expected = %w{
410
+ none
411
+ control
412
+ file
413
+ random
414
+ }
415
+ return if expected.include? option_value
416
+
417
+ raise Inspec::ConfigError::Invalid, "--sort-results-by must be one of #{expected.join(", ")}"
418
+ end
419
+
408
420
  #-----------------------------------------------------------------------#
409
421
  # Merging Options
410
422
  #-----------------------------------------------------------------------#
@@ -435,6 +447,7 @@ module Inspec
435
447
  finalize_parse_reporters(options)
436
448
  finalize_handle_sudo(options)
437
449
  finalize_compliance_login(options)
450
+ finalize_sort_results(options)
438
451
 
439
452
  Thor::CoreExt::HashWithIndifferentAccess.new(options)
440
453
  end
@@ -509,6 +522,12 @@ module Inspec
509
522
  end
510
523
  end
511
524
 
525
+ def finalize_sort_results(options)
526
+ if options.key?("sort_results_by")
527
+ validate_sort_results_by!(options["sort_results_by"])
528
+ end
529
+ end
530
+
512
531
  class Defaults
513
532
  DEFAULTS = {
514
533
  exec: {
@@ -171,7 +171,7 @@ module Inspec
171
171
  # are free to go higher.
172
172
  DEFAULT_PRIORITY_FOR_VALUE_SET = 60
173
173
 
174
- attr_reader :description, :events, :identifier, :name, :required, :title, :type
174
+ attr_reader :description, :events, :identifier, :name, :required, :sensitive, :title, :type
175
175
 
176
176
  def initialize(name, options = {})
177
177
  @name = name
@@ -264,6 +264,7 @@ module Inspec
264
264
  @required = options[:required] if options.key?(:required)
265
265
  @identifier = options[:identifier] if options.key?(:identifier) # TODO: determine if this is ever used
266
266
  @type = options[:type] if options.key?(:type)
267
+ @sensitive = options[:sensitive] if options.key?(:sensitive)
267
268
  end
268
269
 
269
270
  def make_creation_event(options)
@@ -320,7 +321,7 @@ module Inspec
320
321
 
321
322
  def to_hash
322
323
  as_hash = { name: name, options: {} }
323
- %i{description title identifier type required value}.each do |field|
324
+ %i{description title identifier type required value sensitive}.each do |field|
324
325
  val = send(field)
325
326
  next if val.nil?
326
327
 
@@ -334,7 +335,7 @@ module Inspec
334
335
  #--------------------------------------------------------------------------#
335
336
 
336
337
  def to_s
337
- "Input #{name} with #{current_value}"
338
+ "Input #{name} with value " + (sensitive ? "*** (senstive)" : "#{current_value}")
338
339
  end
339
340
 
340
341
  #--------------------------------------------------------------------------#
@@ -29,6 +29,8 @@ module Inspec
29
29
  def_delegator :inputs_by_profile, :select
30
30
  def_delegator :profile_aliases, :key?, :profile_alias?
31
31
 
32
+ attr_accessor :cache_inputs
33
+
32
34
  def initialize
33
35
  # Keyed on String profile_name => Hash of String input_name => Input object
34
36
  @inputs_by_profile = {}
@@ -43,6 +45,9 @@ module Inspec
43
45
  activator.activate!
44
46
  activator.implementation_class.new
45
47
  end
48
+
49
+ # Activate caching for inputs by default
50
+ @cache_inputs = true
46
51
  end
47
52
 
48
53
  #-------------------------------------------------------------#
@@ -84,7 +89,7 @@ module Inspec
84
89
 
85
90
  # Find or create the input
86
91
  inputs_by_profile[profile_name] ||= {}
87
- if inputs_by_profile[profile_name].key?(input_name)
92
+ if inputs_by_profile[profile_name].key?(input_name) && cache_inputs
88
93
  inputs_by_profile[profile_name][input_name].update(options)
89
94
  else
90
95
  inputs_by_profile[profile_name][input_name] = Inspec::Input.new(input_name, options)
@@ -316,6 +321,7 @@ module Inspec
316
321
  profile_name,
317
322
  type: input_options[:type],
318
323
  required: input_options[:required],
324
+ sensitive: input_options[:sensitive],
319
325
  event: evt
320
326
  )
321
327
  end
@@ -1,18 +1,20 @@
1
1
  require_relative "../../../run_data"
2
+ require_relative "../../../utils/run_data_filters"
2
3
 
3
4
  module Inspec::Plugin::V2::PluginType
4
5
  class Reporter < Inspec::Plugin::V2::PluginBase
5
6
  register_plugin_type(:reporter)
7
+ include Inspec::Utils::RunDataFilters
6
8
 
7
9
  attr_reader :run_data
8
10
 
9
11
  def initialize(config)
10
12
  @config = config
11
13
 
12
- # Trim the run_data while still a Hash; if it is huge, this
14
+ # Filter the run_data while still a Hash; if it is huge, this
13
15
  # saves on conversion time
14
16
  @run_data = config[:run_data] || {}
15
- apply_report_resize_options
17
+ apply_run_data_filters_to_hash
16
18
 
17
19
  unless Inspec::RunData.compatible_schema?(self.class.run_data_schema_constraints)
18
20
  # Best we can do is warn here, the InSpec run has finished
@@ -24,26 +26,6 @@ module Inspec::Plugin::V2::PluginType
24
26
  @output = ""
25
27
  end
26
28
 
27
- # This is a temporary duplication of code from lib/inspec/reporters/base.rb
28
- # To be DRY'd up once the core reporters become plugins...
29
- # Apply options such as message truncation and removal of backtraces
30
- def apply_report_resize_options
31
- runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
32
-
33
- message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
34
- @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
35
- include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
36
-
37
- @run_data[:profiles]&.each do |p|
38
- p[:controls].each do |c|
39
- c[:results]&.map! do |r|
40
- r.delete(:backtrace) unless include_backtrace
41
- process_message_truncation(r)
42
- end
43
- end
44
- end
45
- end
46
-
47
29
  def output(str, newline = true)
48
30
  @output << str
49
31
  @output << "\n" if newline
@@ -61,14 +43,5 @@ module Inspec::Plugin::V2::PluginType
61
43
  def self.run_data_schema_constraints
62
44
  raise NotImplementedError, "#{self.class} must implement a `run_data_schema_constraints` class method to declare its compatibiltity with the RunData API."
63
45
  end
64
-
65
- private
66
-
67
- def process_message_truncation(result)
68
- if result.key?(:message) && result[:message] != "" && @trunc > -1 && result[:message].length > @trunc
69
- result[:message] = result[:message][0...@trunc] + "[Truncated to #{@trunc} characters]"
70
- end
71
- result
72
- end
73
46
  end
74
47
  end
@@ -1,30 +1,17 @@
1
+ require_relative "../utils/run_data_filters"
2
+
1
3
  module Inspec::Reporters
2
4
  class Base
5
+ include Inspec::Utils::RunDataFilters
6
+
3
7
  attr_reader :run_data
4
8
 
5
9
  def initialize(config)
6
10
  @config = config
7
- @run_data = config[:run_data]
8
- apply_report_resize_options unless @run_data.nil?
9
- @output = ""
10
- end
11
-
12
- # Apply options such as message truncation and removal of backtraces
13
- def apply_report_resize_options
14
- runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
11
+ @run_data = config[:run_data] || {}
12
+ apply_run_data_filters_to_hash
15
13
 
16
- message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
17
- @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
18
- include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
19
-
20
- @run_data[:profiles]&.each do |p|
21
- p[:controls].each do |c|
22
- c[:results]&.map! do |r|
23
- r.delete(:backtrace) unless include_backtrace
24
- process_message_truncation(r)
25
- end
26
- end
27
- end
14
+ @output = ""
28
15
  end
29
16
 
30
17
  def output(str, newline = true)
@@ -40,14 +27,5 @@ module Inspec::Reporters
40
27
  def render
41
28
  raise NotImplementedError, "#{self.class} must implement a `#render` method to format its output."
42
29
  end
43
-
44
- private
45
-
46
- def process_message_truncation(result)
47
- if result.key?(:message) && result[:message] != "" && @trunc > -1 && result[:message].length > @trunc
48
- result[:message] = result[:message][0...@trunc] + "[Truncated to #{@trunc} characters]"
49
- end
50
- result
51
- end
52
30
  end
53
31
  end
@@ -26,12 +26,13 @@ module Inspec::Resources
26
26
  supports platform: "windows"
27
27
  desc "Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database."
28
28
  example <<~EXAMPLE
29
- sql = postgres_session('username', 'password', 'host')
29
+ sql = postgres_session('username', 'password', 'host', 'port')
30
30
  query('sql_query', ['database_name'])` contains the query and (optional) database to execute
31
31
 
32
32
  # default values:
33
33
  # username: 'postgres'
34
34
  # host: 'localhost'
35
+ # port: 5432
35
36
  # db: databse == db_user running the sql query
36
37
 
37
38
  describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
@@ -39,10 +40,11 @@ module Inspec::Resources
39
40
  end
40
41
  EXAMPLE
41
42
 
42
- def initialize(user, pass, host = nil)
43
+ def initialize(user, pass, host = nil, port = nil)
43
44
  @user = user || "postgres"
44
45
  @pass = pass
45
46
  @host = host || "localhost"
47
+ @port = port || 5432
46
48
  end
47
49
 
48
50
  def query(query, db = [])
@@ -64,7 +66,7 @@ module Inspec::Resources
64
66
 
65
67
  def create_psql_cmd(query, db = [])
66
68
  dbs = db.map { |x| "-d #{x}" }.join(" ")
67
- "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}"
69
+ "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -p #{@port} -A -t -c #{escaped_query(query)}"
68
70
  end
69
71
  end
70
72
  end
@@ -138,7 +138,7 @@ module Inspec::Resources
138
138
  command: 8,
139
139
  }
140
140
  else
141
- command = "ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command"
141
+ command = "ps wwaxo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command"
142
142
  regex = /^(.+?)\s+(\d+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
143
143
  field_map = {
144
144
  label: 1,
@@ -96,11 +96,12 @@ module Inspec
96
96
  # There are probably others
97
97
  :value,
98
98
  :type,
99
- :required
99
+ :required,
100
+ :sensitive
100
101
  ) do
101
102
  include HashLikeStruct
102
103
  def initialize(raw_opts_data)
103
- %i{value type required}.each { |f| self[f] = raw_opts_data[f] }
104
+ %i{value type required sensitive}.each { |f| self[f] = raw_opts_data[f] }
104
105
  end
105
106
  end
106
107
  end
@@ -0,0 +1,104 @@
1
+ module Inspec
2
+ module Utils
3
+ # RunDataFilters is a mixin for core Reporters and plugin reporters.
4
+ # The methods operate on the run_data Hash (prior to any conversion to a
5
+ # full RunData object).
6
+ # All methods here operate using the run_data accessor and modify
7
+ # its contents in place (if needed).
8
+ module RunDataFilters
9
+
10
+ # Long name, but we want to be clear this operates on the Hash
11
+ # This is the only method that client libraries need to call; any future
12
+ # feature growth should be handled internally here.
13
+ def apply_run_data_filters_to_hash
14
+ @config[:runtime_config] = Inspec::Config.cached || {}
15
+ apply_report_resize_options
16
+ redact_sensitive_inputs
17
+ suppress_diff_output
18
+ sort_controls
19
+ end
20
+
21
+ # Apply options such as message truncation and removal of backtraces
22
+ def apply_report_resize_options
23
+ runtime_config = @config[:runtime_config]
24
+
25
+ message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
26
+ @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
27
+ include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
28
+
29
+ @run_data[:profiles]&.each do |p|
30
+ p[:controls].each do |c|
31
+ c[:results]&.map! do |r|
32
+ r.delete(:backtrace) unless include_backtrace
33
+ process_message_truncation(r)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ # Find any inputs with :sensitive = true and replace their values with "***"
40
+ def redact_sensitive_inputs
41
+ @run_data[:profiles]&.each do |p|
42
+ p[:inputs]&.each do |i|
43
+ next unless i[:options][:sensitive]
44
+
45
+ i[:options][:value] = "***"
46
+ end
47
+ end
48
+ end
49
+
50
+ # Optionally suppress diff output in the message field
51
+ def suppress_diff_output
52
+ return if @config[:runtime_config][:diff]
53
+
54
+ @run_data[:profiles]&.each do |p|
55
+ p[:controls]&.each do |c|
56
+ c[:results]&.each do |r|
57
+ next unless r[:message] # :message only set on failure
58
+
59
+ pos = r[:message].index("\n\nDiff:")
60
+ next unless pos # Only textual tests get Diffs
61
+
62
+ r[:message] = r[:message].slice(0, pos)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ # Optionally sort controls within each profile in report
69
+ def sort_controls
70
+ sort_type = @config[:runtime_config][:sort_results_by]
71
+ return unless sort_type
72
+ return if sort_type == "none"
73
+
74
+ @run_data[:profiles]&.each do |p|
75
+ p[:controls] ||= []
76
+ p[:groups] ||= []
77
+
78
+ case sort_type
79
+ when "control"
80
+ p[:controls].sort_by! { |c| c[:id] }
81
+ when "random"
82
+ p[:controls].shuffle!
83
+ when "file"
84
+ # Sort the controls by file, but preserve order within the file.
85
+ # Files are called "groups" in the run_data, and the filename is in the id.
86
+ sorted_control_ids = p[:groups].sort_by { |g| g[:id] }.map { |g| g[:controls] }.flatten
87
+ controls_by_id = {}
88
+ p[:controls].each { |c| controls_by_id[c[:id]] = c }
89
+ p[:controls] = sorted_control_ids.map { |cid| controls_by_id[cid] }
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def process_message_truncation(result)
97
+ if result.key?(:message) && result[:message] != "" && @trunc > -1 && result[:message].length > @trunc
98
+ result[:message] = result[:message][0...@trunc] + "[Truncated to #{@trunc} characters]"
99
+ end
100
+ result
101
+ end
102
+ end
103
+ end
104
+ end
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.22.22".freeze
2
+ VERSION = "4.23.4".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.22.22
4
+ version: 4.23.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-26 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 0.2.13
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '2.0'
36
+ version: '3.0'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 0.2.13
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '2.0'
46
+ version: '3.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: thor
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -638,6 +638,7 @@ files:
638
638
  - lib/inspec/utils/object_traversal.rb
639
639
  - lib/inspec/utils/parser.rb
640
640
  - lib/inspec/utils/pkey_reader.rb
641
+ - lib/inspec/utils/run_data_filters.rb
641
642
  - lib/inspec/utils/simpleconfig.rb
642
643
  - lib/inspec/utils/spdx.rb
643
644
  - lib/inspec/utils/spdx.txt