inspec-core 4.17.17 → 4.18.0

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: 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