inspec-core 4.17.17 → 4.18.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9cfd01a9da3acdf34494cfad5f09ce2656ab12bd0bc727322eb8de72c342fa3
4
- data.tar.gz: 111c6ea5d24bc14f76b0d9d3b25d92639a2fdcdb14711b2e8045e51b4b5033f4
3
+ metadata.gz: 965a170fc5beed002ad3a6ee98635fc4e6f5ffea8c546b35a6f16585f3c9c988
4
+ data.tar.gz: 73751911bb9d7b894df68b733dac98409bce75818d96401139094b9f8bfa7750
5
5
  SHA512:
6
- metadata.gz: bd3169c135e2600a54d7282e5e86579043b118530377ecaac4537805eba272ef7f87f64f0ad744812fb04dda6f53326e14687c1e15b5b0fe031379cc6fe1c9fd
7
- data.tar.gz: 1c6f45bf5e0372ae8c529f275df59cd336ec180cf118f8d34219f7de0a85b46659c6c084e468963eca38d841c1fc7961bfbebd6496caf557e8a4c217e7732d6c
6
+ metadata.gz: 13481358fd713598dda518674674e4a74b819dbfcd096be411421d8b2170c0bc34bab6dc52057b757a5edacbada2cbe881a0363052e945ce2a9d76d3e8322b83
7
+ data.tar.gz: daad1335c0bfafffcf7b47f2f14293a8d636c34b9a8537570c68a5236d6ff0caf615e279d30d78d32edcf9a361934bfae22fe7081b1cfbd80705c3e807b0ac39
@@ -222,16 +222,20 @@ module Inspec
222
222
 
223
223
  private
224
224
 
225
+ ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html yaml documentation progress}.freeze # BUT WHY?!?!
226
+
225
227
  def suppress_log_output?(opts)
226
228
  return false if opts["reporter"].nil?
227
229
 
228
- match = %w{json json-min json-rspec json-automate junit html yaml documentation progress} & opts["reporter"].keys
230
+ match = ALL_OF_OUR_REPORTERS & opts["reporter"].keys
231
+
229
232
  unless match.empty?
230
233
  match.each do |m|
231
234
  # check to see if we are outputting to stdout
232
235
  return true if opts["reporter"][m]["stdout"] == true
233
236
  end
234
237
  end
238
+
235
239
  false
236
240
  end
237
241
 
@@ -9,6 +9,7 @@ module Inspec # TODO: move this somewhere "better"?
9
9
  autoload :BaseCLI, "inspec/base_cli"
10
10
  autoload :Deprecation, "inspec/utils/deprecation"
11
11
  autoload :Exceptions, "inspec/exceptions"
12
+ autoload :EnvPrinter, "inspec/env_printer"
12
13
  autoload :Fetcher, "inspec/fetcher"
13
14
  autoload :Formatters, "inspec/formatters"
14
15
  autoload :Globals, "inspec/globals"
@@ -340,7 +341,15 @@ class Inspec::InspecCLI < Inspec::BaseCLI
340
341
  ui.exit res unless run_type == :ruby_eval
341
342
 
342
343
  # No InSpec tests - just print evaluation output.
343
- res = (res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)) if o["reporter"]&.keys&.include?("json")
344
+ reporters = o["reporter"] || {}
345
+ if reporters.keys.include?("json")
346
+ res = if res.respond_to?(:to_json)
347
+ res.to_json
348
+ else
349
+ JSON.dump(res)
350
+ end
351
+ end
352
+
344
353
  puts res
345
354
  ui.exit Inspec::UI::EXIT_NORMAL
346
355
  rescue RuntimeError, Train::UserError => e
@@ -34,6 +34,8 @@ module Inspec::DSL
34
34
  # resource.
35
35
 
36
36
  def self.method_missing_resource(backend, id, *arguments)
37
+ return unless backend
38
+
37
39
  begin
38
40
  require "inspec/resources/#{id}"
39
41
  rescue LoadError
@@ -259,6 +259,11 @@ module Inspec::Formatters
259
259
  example.delete(:id)
260
260
  example.delete(:profile_id)
261
261
  control[:results].push(example)
262
+
263
+ # Waiver data, if available, is internally stored on a per-result
264
+ # (that is, per-describe-block) basis, because that is the only granularity
265
+ # available to us in the RSpec report data structure which we use as a vehicle.
266
+ control[:waiver_data] ||= example[:waiver_data] || {}
262
267
  end
263
268
  end
264
269
  end
@@ -40,7 +40,6 @@ module Inspec::Reporters
40
40
  message: r[:message],
41
41
  exception: r[:exception],
42
42
  backtrace: r[:backtrace],
43
- waiver_data: r[:waiver_data],
44
43
  }.reject { |_k, v| v.nil? }
45
44
  }
46
45
  end
@@ -96,6 +95,7 @@ module Inspec::Reporters
96
95
  line: c[:source_location][:line],
97
96
  ref: c[:source_location][:ref],
98
97
  },
98
+ waiver_data: c[:waiver_data] || {},
99
99
  results: profile_results(c),
100
100
  }
101
101
  }
@@ -87,12 +87,14 @@ module Inspec::Resources
87
87
  active = raw_line == line
88
88
 
89
89
  # formats:
90
+ # deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
90
91
  # deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
91
92
  # deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
92
93
 
93
94
  words = line.split
94
95
  words.delete 1 if words[1] && words[1].start_with?("[")
95
96
  type, url, distro, *components = words
97
+ url = url.delete('"') if url
96
98
 
97
99
  next if components.empty?
98
100
  next unless URI::HTTP === URI.parse(url)
@@ -17,38 +17,34 @@ module Inspec::Resources
17
17
  its('ipv6_cidrs') { should include '::1/128' }
18
18
  end
19
19
  EXAMPLE
20
+
20
21
  def initialize(iface)
21
22
  @iface = iface
22
-
23
- @interface_provider = nil
24
- if inspec.os.linux?
25
- @interface_provider = LinuxInterface.new(inspec)
26
- elsif inspec.os.windows?
27
- @interface_provider = WindowsInterface.new(inspec)
28
- else
29
- return skip_resource "The `interface` resource is not supported on your OS yet."
30
- end
31
23
  end
32
24
 
33
25
  def exists?
34
- !interface_info.nil? && !interface_info[:name].nil?
26
+ !!(interface_info && interface_info[:name])
35
27
  end
36
28
 
37
29
  def up?
38
- interface_info.nil? ? false : interface_info[:up]
30
+ !!(interface_info && interface_info[:up])
31
+ end
32
+
33
+ def name
34
+ interface_info[:name]
39
35
  end
40
36
 
41
37
  # returns link speed in Mbits/sec
42
38
  def speed
43
- interface_info.nil? ? nil : interface_info[:speed]
39
+ interface_info && interface_info[:speed]
44
40
  end
45
41
 
46
42
  def ipv4_address?
47
- !ipv4_addresses.nil? && !ipv4_addresses.empty?
43
+ ipv4_addresses && !ipv4_addresses.empty?
48
44
  end
49
45
 
50
46
  def ipv6_address?
51
- !ipv6_addresses.nil? && !ipv6_addresses.empty?
47
+ ipv6_addresses && !ipv6_addresses.empty?
52
48
  end
53
49
 
54
50
  def ipv4_addresses
@@ -72,11 +68,11 @@ module Inspec::Resources
72
68
  end
73
69
 
74
70
  def ipv4_cidrs
75
- interface_info.nil? ? [] : interface_info[:ipv4_addresses]
71
+ interface_info && Array(interface_info[:ipv4_addresses])
76
72
  end
77
73
 
78
74
  def ipv6_cidrs
79
- interface_info.nil? ? [] : interface_info[:ipv6_addresses]
75
+ interface_info && Array(interface_info[:ipv6_addresses])
80
76
  end
81
77
 
82
78
  def to_s
@@ -86,9 +82,11 @@ module Inspec::Resources
86
82
  private
87
83
 
88
84
  def interface_info
89
- return @cache if defined?(@cache)
90
-
91
- @cache = @interface_provider.interface_info(@iface) unless @interface_provider.nil?
85
+ @cache ||= begin
86
+ provider = LinuxInterface.new(inspec) if inspec.os.linux?
87
+ provider = WindowsInterface.new(inspec) if inspec.os.windows?
88
+ Hash(provider && provider.interface_info(@iface))
89
+ end
92
90
  end
93
91
  end
94
92
 
@@ -3,6 +3,7 @@ require "inspec/utils/convert"
3
3
  require "inspec/utils/filter"
4
4
  require "inspec/utils/simpleconfig"
5
5
  require "inspec/resources/powershell"
6
+ require "date"
6
7
 
7
8
  module Inspec::Resources
8
9
  # This file contains two resources, the `user` and `users` resource.
@@ -116,6 +117,24 @@ module Inspec::Resources
116
117
  # its('mindays') { should eq 0 }
117
118
  # its('maxdays') { should eq 99 }
118
119
  # its('warndays') { should eq 5 }
120
+ # its('passwordage') { should be >= 0 }
121
+ # its('maxbadpasswords') { should eq nil } // not yet supported on linux
122
+ # its('badpasswordattempts') { should eq 0 }
123
+ # end
124
+ # describe user('Administrator') do
125
+ # it { should exist }
126
+ # its('uid') { should eq "S-1-5-21-1759981009-4135989804-1844563890-500" }
127
+ # its('gid') { should eq nil } // not supported on Windows
128
+ # its('group') { should eq nil } // not supported on Windows
129
+ # its('groups') { should eq ['Administrators', 'Users']}
130
+ # its('home') { should eq '' }
131
+ # its('shell') { should eq nil } // not supported on Windows
132
+ # its('mindays') { should eq 0 }
133
+ # its('maxdays') { should eq 42 }
134
+ # its('warndays') { should eq nil }
135
+ # its('passwordage') { should eq 355 }
136
+ # its('maxbadpasswords') { should eq 0 }
137
+ # its('badpasswordattempts') { should eq 0 }
119
138
  # end
120
139
  #
121
140
  # The following Serverspec matchers are deprecated in favor for direct value access
@@ -196,6 +215,14 @@ module Inspec::Resources
196
215
  meta_info[:shell] unless meta_info.nil?
197
216
  end
198
217
 
218
+ def domain
219
+ meta_info[:domain] unless meta_info.nil?
220
+ end
221
+
222
+ def userflags
223
+ meta_info[:userflags] unless meta_info.nil?
224
+ end
225
+
199
226
  # returns the minimum days between password changes
200
227
  def mindays
201
228
  credentials[:mindays] unless credentials.nil?
@@ -211,6 +238,18 @@ module Inspec::Resources
211
238
  credentials[:warndays] unless credentials.nil?
212
239
  end
213
240
 
241
+ def badpasswordattempts
242
+ credentials[:badpasswordattempts] unless credentials.nil?
243
+ end
244
+
245
+ def maxbadpasswords
246
+ credentials[:maxbadpasswords] unless credentials.nil?
247
+ end
248
+
249
+ def passwordage
250
+ credentials[:passwordage] unless credentials.nil?
251
+ end
252
+
214
253
  # implement 'mindays' method to be compatible with serverspec
215
254
  def minimum_days_between_password_change
216
255
  Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `minimum_days_between_password_change` property is deprecated. Please use `mindays`.")
@@ -425,10 +464,17 @@ module Inspec::Resources
425
464
  multiple_values: false
426
465
  ).params
427
466
 
467
+ dparse = Date.parse "#{params['Last password change']}"
468
+ dayslastset = (Date.today - dparse).to_i
469
+ cmd = inspec.command("lastb -w -a | grep #{username} | wc -l")
470
+ badpasswordattempts = convert_to_i(cmd.stdout.chomp) if cmd.exit_status == 0
471
+
428
472
  {
429
473
  mindays: convert_to_i(params["Minimum number of days between password change"]),
430
474
  maxdays: convert_to_i(params["Maximum number of days between password change"]),
431
475
  warndays: convert_to_i(params["Number of days of warning before password expires"]),
476
+ passwordage: dayslastset,
477
+ badpasswordattempts: badpasswordattempts,
432
478
  }
433
479
  end
434
480
  end
@@ -481,6 +527,8 @@ module Inspec::Resources
481
527
  mindays: user_sec[1].to_i * 7,
482
528
  maxdays: user_sec[2].to_i * 7,
483
529
  warndays: user_sec[3].to_i,
530
+ passwordage: nil,
531
+ badpasswordattempts: nil,
484
532
  }
485
533
  end
486
534
  end
@@ -573,6 +621,31 @@ module Inspec::Resources
573
621
  res[0] unless res.empty?
574
622
  end
575
623
 
624
+ def meta_info(username)
625
+ res = identity(username)
626
+ return if res.nil?
627
+ {
628
+ home: res[:home],
629
+ shell: res[:shell],
630
+ domain: res[:domain],
631
+ userflags: res[:userflags],
632
+ }
633
+ end
634
+
635
+ def credentials(username)
636
+ res = identity(username)
637
+ return if res.nil?
638
+ {
639
+ mindays: res[:mindays],
640
+ maxdays: res[:maxdays],
641
+ warndays: res[:warndays],
642
+ badpasswordattempts: res[:badpasswordattempts],
643
+ maxbadpasswords: res[:maxbadpasswords],
644
+ minpasswordlength: res[:minpasswordlength],
645
+ passwordage: res[:passwordage],
646
+ }
647
+ end
648
+
576
649
  def list_users
577
650
  collect_user_details.map { |user| user[:username] }
578
651
  end
@@ -50,6 +50,7 @@ module Inspec
50
50
  def method_missing(method_name, *arguments, &block)
51
51
  # see if it is a resource first
52
52
  begin
53
+ inspec = inspec if respond_to?(:inspec) # backend not available??
53
54
  resource = Inspec::DSL.method_missing_resource(inspec, method_name, *arguments)
54
55
  return resource if resource
55
56
  rescue LoadError
@@ -297,11 +297,11 @@ module Inspec
297
297
  __waiver_data["skipped_due_to_waiver"] = false
298
298
  __waiver_data["message"] = ""
299
299
 
300
- # Waivers should have a hash value with keys possibly including skip and
301
- # expiration_date. We only care here if it has a skip key and it
302
- # is yes-like, since all non-skipped waiver operations are handled
300
+ # Waivers should have a hash value with keys possibly including "run" and
301
+ # expiration_date. We only care here if it has a "run" key and it
302
+ # is false-like, since all non-skipped waiver operations are handled
303
303
  # during reporting phase.
304
- return unless __waiver_data.key?("skip") && __waiver_data["skip"]
304
+ return unless __waiver_data.key?("run") && !__waiver_data["run"]
305
305
 
306
306
  # OK, the intent is to skip. Does it have an expiration date, and
307
307
  # if so, is it in the future?
@@ -83,7 +83,7 @@ module Inspec
83
83
  return @rspec_exit_code if @formatter.results.empty?
84
84
 
85
85
  stats = @formatter.results[:statistics][:controls]
86
- skipped = @formatter.results&.fetch(:profiles, nil)&.first&.fetch(:status, nil) == "skipped"
86
+ skipped = @formatter.results.dig(:profiles, 0, :status) == "skipped"
87
87
  if stats[:failed][:total] == 0 && stats[:skipped][:total] == 0 && !skipped
88
88
  0
89
89
  elsif stats[:failed][:total] > 0
@@ -96,6 +96,16 @@ module Inspec
96
96
  },
97
97
  },
98
98
  "results" => { "type" => "array", "items" => RESULT },
99
+ "waiver_data" => {
100
+ "type" => "object",
101
+ "properties" => {
102
+ "skipped_due_to_waiver" => { "type" => "string" },
103
+ "run" => { "type" => "boolean" },
104
+ "message" => { "type" => "string" },
105
+ "expiration_date" => { "type" => "string" },
106
+ "justification" => { "type" => "string" },
107
+ },
108
+ },
99
109
  },
100
110
  }.freeze
101
111
 
@@ -20,13 +20,14 @@ module PasswdParser
20
20
  def parse_passwd_line(line)
21
21
  x = line.split(":")
22
22
  {
23
- "user" => x.at(0),
24
- "password" => x.at(1),
25
- "uid" => x.at(2),
26
- "gid" => x.at(3),
27
- "desc" => x.at(4),
28
- "home" => x.at(5),
29
- "shell" => x.at(6),
23
+ # rubocop:disable Layout/AlignHash
24
+ "user" => x[0],
25
+ "password" => x[1],
26
+ "uid" => x[2],
27
+ "gid" => x[3],
28
+ "desc" => x[4],
29
+ "home" => x[5],
30
+ "shell" => x[6],
30
31
  }
31
32
  end
32
33
  end
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.17.17".freeze
2
+ VERSION = "4.18.0".freeze
3
3
  end
@@ -19,22 +19,22 @@ class Module
19
19
  include Minitest::Spec::DSL # TODO: NO! remove this!
20
20
  end
21
21
 
22
- module Inspec
23
- class FuncTestRunResult
24
- attr_reader :train_result
25
- attr_reader :payload
26
-
27
- extend Forwardable
28
- def_delegator :train_result, :stdout
29
- def_delegator :train_result, :stderr
30
- def_delegator :train_result, :exit_status
31
-
32
- def initialize(train_result)
33
- @train_result = train_result
34
- @payload = OpenStruct.new
35
- end
36
- end
37
- end
22
+ # module Inspec
23
+ # class FuncTestRunResult
24
+ # attr_reader :train_result
25
+ # attr_reader :payload
26
+ #
27
+ # extend Forwardable
28
+ # def_delegator :train_result, :stdout
29
+ # def_delegator :train_result, :stderr
30
+ # def_delegator :train_result, :exit_status
31
+ #
32
+ # def initialize(train_result)
33
+ # @train_result = train_result
34
+ # @payload = OpenStruct.new
35
+ # end
36
+ # end
37
+ # end
38
38
 
39
39
  module CorePluginBaseHelper
40
40
  libdir = File.expand_path "lib"
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.17.17
4
+ version: 4.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-02 00:00:00.000000000 Z
11
+ date: 2019-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train-core
@@ -106,14 +106,20 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '3'
109
+ version: '3.0'
110
+ - - "<"
111
+ - !ruby/object:Gem::Version
112
+ version: '3.9'
110
113
  type: :runtime
111
114
  prerelease: false
112
115
  version_requirements: !ruby/object:Gem::Requirement
113
116
  requirements:
114
117
  - - "~>"
115
118
  - !ruby/object:Gem::Version
116
- version: '3'
119
+ version: '3.0'
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '3.9'
117
123
  - !ruby/object:Gem::Dependency
118
124
  name: rspec-its
119
125
  requirement: !ruby/object:Gem::Requirement
@@ -449,7 +455,6 @@ files:
449
455
  - lib/inspec/plugin/v2/plugin_types/mock.rb
450
456
  - lib/inspec/plugin/v2/registry.rb
451
457
  - lib/inspec/plugin/v2/status.rb
452
- - lib/inspec/polyfill.rb
453
458
  - lib/inspec/profile.rb
454
459
  - lib/inspec/profile_context.rb
455
460
  - lib/inspec/profile_vendor.rb
@@ -1,9 +0,0 @@
1
- # copyright: 2016, Chef Software Inc.
2
-
3
- class Struct
4
- unless instance_methods.include? :to_h
5
- def to_h
6
- Hash[each_pair.to_a]
7
- end
8
- end
9
- end