inspec 4.16.0 → 4.17.7
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/lib/inspec.rb +0 -1
- data/lib/inspec/backend.rb +7 -0
- data/lib/inspec/base_cli.rb +2 -0
- data/lib/inspec/cli.rb +3 -10
- data/lib/inspec/config.rb +3 -4
- data/lib/inspec/control_eval_context.rb +5 -3
- data/lib/inspec/dsl.rb +24 -1
- data/lib/inspec/errors.rb +0 -26
- data/lib/inspec/file_provider.rb +33 -43
- data/lib/inspec/formatters/base.rb +1 -0
- data/lib/inspec/impact.rb +2 -0
- data/lib/inspec/input.rb +410 -0
- data/lib/inspec/input_registry.rb +10 -1
- data/lib/inspec/objects.rb +3 -1
- data/lib/inspec/objects/input.rb +5 -387
- data/lib/inspec/objects/tag.rb +1 -1
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +16 -5
- data/lib/inspec/plugin/v2/activator.rb +4 -8
- data/lib/inspec/plugin/v2/loader.rb +19 -3
- data/lib/inspec/profile.rb +1 -1
- data/lib/inspec/profile_context.rb +1 -1
- data/lib/inspec/reporters/json.rb +70 -88
- data/lib/inspec/resource.rb +1 -0
- data/lib/inspec/resources.rb +9 -2
- data/lib/inspec/resources/aide_conf.rb +4 -0
- data/lib/inspec/resources/apt.rb +19 -19
- data/lib/inspec/resources/etc_fstab.rb +4 -0
- data/lib/inspec/resources/etc_hosts.rb +4 -0
- data/lib/inspec/resources/firewalld.rb +4 -0
- data/lib/inspec/resources/json.rb +10 -3
- data/lib/inspec/resources/mssql_session.rb +1 -1
- data/lib/inspec/resources/platform.rb +18 -13
- data/lib/inspec/resources/postfix_conf.rb +6 -2
- data/lib/inspec/resources/security_identifier.rb +4 -0
- data/lib/inspec/resources/sys_info.rb +65 -4
- data/lib/inspec/resources/user.rb +1 -0
- data/lib/inspec/rule.rb +68 -6
- data/lib/inspec/runner.rb +6 -1
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/shell.rb +8 -1
- data/lib/inspec/utils/pkey_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +2 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/help_test.rb +23 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/helper.rb +62 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/install_test.rb +368 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/list_test.rb +101 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/search_test.rb +129 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/uninstall_test.rb +63 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/update_test.rb +84 -0
- metadata +11 -3
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +0 -845
@@ -93,10 +93,17 @@ module Inspec::Resources
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def load_raw_from_command(command)
|
96
|
-
|
97
|
-
raise Inspec::Exceptions::ResourceSkipped, "No output from command: #{command}" if command_output.nil? || command_output.empty?
|
96
|
+
result = inspec.command(command)
|
98
97
|
|
99
|
-
|
98
|
+
return result.stdout unless result.stdout.empty?
|
99
|
+
|
100
|
+
msg = if result.stderr.empty?
|
101
|
+
"No JSON output, STDERR was empty"
|
102
|
+
else
|
103
|
+
"No JSON output, STDERR:\n #{result.stderr}"
|
104
|
+
end
|
105
|
+
|
106
|
+
raise Inspec::Exceptions::ResourceFailed, msg
|
100
107
|
end
|
101
108
|
|
102
109
|
# for resources the subclass JsonConfig, this allows specification of the resource
|
@@ -53,7 +53,7 @@ module Inspec::Resources
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def query(q) # rubocop:disable Metrics/PerceivedComplexity
|
56
|
-
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '
|
56
|
+
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '""').gsub(/\$/, '\\$')
|
57
57
|
# surpress 'x rows affected' in SQLCMD with 'set nocount on;'
|
58
58
|
cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
|
59
59
|
cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil?
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "inspec/resource"
|
2
|
+
|
1
3
|
module Inspec::Resources
|
2
4
|
class PlatformResource < Inspec.resource(1)
|
3
5
|
name "platform"
|
@@ -67,19 +69,22 @@ module Inspec::Resources
|
|
67
69
|
return true if supports.nil? || supports.empty?
|
68
70
|
|
69
71
|
status = true
|
70
|
-
supports.each do |
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
72
|
+
supports.each do |support|
|
73
|
+
support.each do |k, v|
|
74
|
+
status =
|
75
|
+
case k
|
76
|
+
when :os_family, :"os-family", :platform_family, :"platform-family" then
|
77
|
+
in_family?(v)
|
78
|
+
when :os, :platform then
|
79
|
+
platform?(v)
|
80
|
+
when :os_name, :"os-name", :platform_name, :"platform-name" then
|
81
|
+
name == v
|
82
|
+
when :release then
|
83
|
+
check_release(v)
|
84
|
+
else
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
83
88
|
break if status == false
|
84
89
|
end
|
85
90
|
return true if status == true
|
@@ -11,7 +11,7 @@ module Inspec::Resources
|
|
11
11
|
def initialize(*opts)
|
12
12
|
@params = {}
|
13
13
|
if opts.length == 1
|
14
|
-
@raw_content = load_raw_content(opts)
|
14
|
+
@raw_content = load_raw_content(opts[0])
|
15
15
|
else
|
16
16
|
@raw_content = load_raw_content("/etc/postfix/main.cf")
|
17
17
|
end
|
@@ -22,10 +22,14 @@ module Inspec::Resources
|
|
22
22
|
SimpleConfig.new(content).params
|
23
23
|
end
|
24
24
|
|
25
|
+
def to_s
|
26
|
+
"Postfix Mail Transfer Agent"
|
27
|
+
end
|
28
|
+
|
25
29
|
private
|
26
30
|
|
27
31
|
def resource_base_name
|
28
|
-
"
|
32
|
+
"Postfix Config"
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -13,20 +13,77 @@ module Inspec::Resources
|
|
13
13
|
describe sys_info do
|
14
14
|
its('hostname') { should eq 'example.com' }
|
15
15
|
end
|
16
|
+
|
17
|
+
describe sys_info do
|
18
|
+
its('fqdn') { should eq 'user.example.com' }
|
19
|
+
end
|
20
|
+
|
16
21
|
EXAMPLE
|
17
22
|
|
23
|
+
%w{ domain fqdn ip_address short }.each do |opt|
|
24
|
+
define_method(opt.to_sym) do
|
25
|
+
hostname(opt)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
18
29
|
# returns the hostname of the local system
|
19
|
-
def hostname
|
30
|
+
def hostname(opt = nil)
|
20
31
|
os = inspec.os
|
21
|
-
if os.linux?
|
22
|
-
|
32
|
+
if os.linux?
|
33
|
+
linux_hostname(opt)
|
34
|
+
elsif os.darwin?
|
35
|
+
mac_hostname(opt)
|
23
36
|
elsif os.windows?
|
24
|
-
|
37
|
+
if !opt.nil?
|
38
|
+
skip_resource "The `sys_info.hostname` resource is not supported with that option on your OS."
|
39
|
+
else
|
40
|
+
inspec.powershell("$env:computername").stdout.chomp
|
41
|
+
end
|
25
42
|
else
|
26
43
|
skip_resource "The `sys_info.hostname` resource is not supported on your OS yet."
|
27
44
|
end
|
28
45
|
end
|
29
46
|
|
47
|
+
def linux_hostname(opt = nil)
|
48
|
+
if !opt.nil?
|
49
|
+
opt = case opt
|
50
|
+
when "f", "long", "fqdn", "full"
|
51
|
+
" -f"
|
52
|
+
when "d", "domain"
|
53
|
+
" -d"
|
54
|
+
when "i", "ip_address"
|
55
|
+
" -I"
|
56
|
+
when "s", "short"
|
57
|
+
" -s"
|
58
|
+
else
|
59
|
+
"ERROR"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
if opt == "ERROR"
|
63
|
+
skip_resource "The `sys_info.hostname` resource is not supported with that option on your OS."
|
64
|
+
else
|
65
|
+
inspec.command("hostname#{opt}").stdout.chomp
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def mac_hostname(opt = nil)
|
70
|
+
if !opt.nil?
|
71
|
+
opt = case opt
|
72
|
+
when "f", "long", "fqdn", "full"
|
73
|
+
" -f"
|
74
|
+
when "s", "short"
|
75
|
+
" -s"
|
76
|
+
else
|
77
|
+
"ERROR"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
if opt == "ERROR"
|
81
|
+
skip_resource "The `sys_info.hostname` resource is not supported with that option on your OS."
|
82
|
+
else
|
83
|
+
inspec.command("hostname#{opt}").stdout.chomp
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
30
87
|
# returns the Manufacturer of the local system
|
31
88
|
def manufacturer
|
32
89
|
os = inspec.os
|
@@ -54,5 +111,9 @@ module Inspec::Resources
|
|
54
111
|
skip_resource "The `sys_info.model` resource is not supported on your OS yet."
|
55
112
|
end
|
56
113
|
end
|
114
|
+
|
115
|
+
def to_s
|
116
|
+
"System Information"
|
117
|
+
end
|
57
118
|
end
|
58
119
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "inspec/resources/users"
|
data/lib/inspec/rule.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# copyright: 2015, Dominik Richter
|
2
2
|
|
3
3
|
require "method_source"
|
4
|
+
require "date"
|
4
5
|
require "inspec/describe"
|
5
6
|
require "inspec/expect"
|
6
7
|
require "inspec/resource"
|
7
8
|
require "inspec/resources/os"
|
9
|
+
require "inspec/input_registry"
|
8
10
|
|
9
11
|
module Inspec
|
10
12
|
class Rule
|
@@ -28,6 +30,7 @@ module Inspec
|
|
28
30
|
@resource_dsl
|
29
31
|
end
|
30
32
|
|
33
|
+
attr_reader :__waiver_data
|
31
34
|
def initialize(id, profile_id, opts, &block)
|
32
35
|
@impact = nil
|
33
36
|
@title = nil
|
@@ -42,7 +45,7 @@ module Inspec
|
|
42
45
|
@__rule_id = id
|
43
46
|
@__profile_id = profile_id
|
44
47
|
@__checks = []
|
45
|
-
@__skip_rule = {}
|
48
|
+
@__skip_rule = {} # { result: true, message: "Why", type: [:only_if, :waiver] }
|
46
49
|
@__merge_count = 0
|
47
50
|
@__merge_changes = []
|
48
51
|
@__skip_only_if_eval = opts[:skip_only_if_eval]
|
@@ -52,6 +55,11 @@ module Inspec
|
|
52
55
|
|
53
56
|
begin
|
54
57
|
instance_eval(&block)
|
58
|
+
|
59
|
+
# By applying waivers *after* the instance eval, we assure that
|
60
|
+
# waivers have higher precedence than only_if.
|
61
|
+
__apply_waivers
|
62
|
+
|
55
63
|
rescue StandardError => e
|
56
64
|
# We've encountered an exception while trying to eval the code inside the
|
57
65
|
# control block. We need to prevent the exception from bubbling up, and
|
@@ -141,6 +149,7 @@ module Inspec
|
|
141
149
|
return if @__skip_only_if_eval == true
|
142
150
|
|
143
151
|
@__skip_rule[:result] ||= !yield
|
152
|
+
@__skip_rule[:type] = :only_if
|
144
153
|
@__skip_rule[:message] = message
|
145
154
|
end
|
146
155
|
|
@@ -193,9 +202,9 @@ module Inspec
|
|
193
202
|
rule.instance_variable_get(:@__skip_rule)
|
194
203
|
end
|
195
204
|
|
196
|
-
def self.set_skip_rule(rule, value, message = nil)
|
205
|
+
def self.set_skip_rule(rule, value, message = nil, type = :only_if)
|
197
206
|
rule.instance_variable_set(:@__skip_rule,
|
198
|
-
{ result: value, message: message })
|
207
|
+
{ result: value, message: message, type: type })
|
199
208
|
end
|
200
209
|
|
201
210
|
def self.merge_count(rule)
|
@@ -206,14 +215,16 @@ module Inspec
|
|
206
215
|
rule.instance_variable_get(:@__merge_changes)
|
207
216
|
end
|
208
217
|
|
218
|
+
# If a rule is marked to be skipped, this
|
219
|
+
# creates a dummay array of "checks" with a skip outcome
|
209
220
|
def self.prepare_checks(rule)
|
210
221
|
skip_check = skip_status(rule)
|
211
222
|
return checks(rule) unless skip_check[:result].eql?(true)
|
212
223
|
|
213
224
|
if skip_check[:message]
|
214
|
-
msg = "Skipped control due to
|
225
|
+
msg = "Skipped control due to #{skip_check[:type]} condition: #{skip_check[:message]}"
|
215
226
|
else
|
216
|
-
msg = "Skipped control due to
|
227
|
+
msg = "Skipped control due to #{skip_check[:type]} condition."
|
217
228
|
end
|
218
229
|
|
219
230
|
# TODO: we use os as the carrier here, but should consider
|
@@ -251,7 +262,8 @@ module Inspec
|
|
251
262
|
skip_check = skip_status(src)
|
252
263
|
sr = skip_check[:result]
|
253
264
|
msg = skip_check[:message]
|
254
|
-
|
265
|
+
skip_type = skip_check[:type]
|
266
|
+
set_skip_rule(dst, sr, msg, skip_type) unless sr.nil?
|
255
267
|
|
256
268
|
# Save merge history
|
257
269
|
dst.instance_variable_set(:@__merge_count, merge_count(dst) + 1)
|
@@ -267,6 +279,56 @@ module Inspec
|
|
267
279
|
@__checks.push([describe_or_expect, values, block])
|
268
280
|
end
|
269
281
|
|
282
|
+
# Look for an input with a matching ID, and if found, apply waiver
|
283
|
+
# skipping logic. Basically, if we have a current waiver, and it says
|
284
|
+
# to skip, we'll replace all the checks with a dummy check (same as
|
285
|
+
# only_if mechanism)
|
286
|
+
# Double underscore: not intended to be called as part of the DSL
|
287
|
+
def __apply_waivers
|
288
|
+
input_name = @__rule_id # TODO: control ID slugging
|
289
|
+
registry = Inspec::InputRegistry.instance
|
290
|
+
input = registry.inputs_by_profile.dig(@__profile_id, input_name)
|
291
|
+
return unless input
|
292
|
+
|
293
|
+
# An InSpec Input is a datastructure that tracks a profile parameter
|
294
|
+
# over time. Its value can be set by many sources, and it keeps a
|
295
|
+
# log of each "set" event so that when it is collapsed to a value,
|
296
|
+
# it can determine the correct (highest priority) value.
|
297
|
+
# Store in an instance variable for.. later reading???
|
298
|
+
@__waiver_data = input.value
|
299
|
+
__waiver_data["skipped_due_to_waiver"] = false
|
300
|
+
__waiver_data["message"] = ""
|
301
|
+
|
302
|
+
# Waivers should have a hash value with keys possibly including skip and
|
303
|
+
# expiration_date. We only care here if it has a skip key and it
|
304
|
+
# is yes-like, since all non-skipped waiver operations are handled
|
305
|
+
# during reporting phase.
|
306
|
+
return unless __waiver_data.key?("skip") && __waiver_data["skip"]
|
307
|
+
|
308
|
+
# OK, the intent is to skip. Does it have an expiration date, and
|
309
|
+
# if so, is it in the future?
|
310
|
+
expiry = __waiver_data["expiration_date"]
|
311
|
+
if expiry
|
312
|
+
if expiry.is_a?(Date)
|
313
|
+
# It appears that yaml.rb automagically parses dates for us
|
314
|
+
if expiry < Date.today # If the waiver expired, return - no skip applied
|
315
|
+
__waiver_data["message"] = "Waiver expired on #{expiry}, evaluating control normally"
|
316
|
+
return
|
317
|
+
end
|
318
|
+
else
|
319
|
+
ui = Inspec::UI.new
|
320
|
+
ui.error("Unable to parse waiver expiration date '#{expiry}' for control #{@__rule_id}")
|
321
|
+
ui.exit(:usage_error)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# OK, apply a skip.
|
326
|
+
@__skip_rule[:result] = true
|
327
|
+
@__skip_rule[:type] = :waiver
|
328
|
+
@__skip_rule[:message] = __waiver_data["justification"]
|
329
|
+
__waiver_data["skipped_due_to_waiver"] = true
|
330
|
+
end
|
331
|
+
|
270
332
|
#
|
271
333
|
# Takes a block and returns a block that will run the given block
|
272
334
|
# with access to the resource_dsl of the current class. This is to
|
data/lib/inspec/runner.rb
CHANGED
@@ -9,7 +9,6 @@ require "inspec/metadata"
|
|
9
9
|
require "inspec/config"
|
10
10
|
require "inspec/dependencies/cache"
|
11
11
|
require "inspec/dist"
|
12
|
-
require "inspec/resources"
|
13
12
|
require "inspec/reporters"
|
14
13
|
require "inspec/runner_rspec"
|
15
14
|
# spec requirements
|
@@ -57,6 +56,12 @@ module Inspec
|
|
57
56
|
RunnerRspec.new(@conf)
|
58
57
|
end
|
59
58
|
|
59
|
+
if @conf[:waiver_file]
|
60
|
+
waivers = @conf.delete(:waiver_file)
|
61
|
+
@conf[:input_file] ||= []
|
62
|
+
@conf[:input_file].concat waivers
|
63
|
+
end
|
64
|
+
|
60
65
|
# About reading inputs:
|
61
66
|
# @conf gets passed around a lot, eventually to
|
62
67
|
# Inspec::InputRegistry.register_external_inputs.
|
data/lib/inspec/runner_rspec.rb
CHANGED
@@ -171,6 +171,7 @@ module Inspec
|
|
171
171
|
metadata[:descriptions] = rule.descriptions
|
172
172
|
metadata[:code] = rule.instance_variable_get(:@__code)
|
173
173
|
metadata[:source_location] = rule.instance_variable_get(:@__source_location)
|
174
|
+
metadata[:waiver_data] = rule.__waiver_data
|
174
175
|
end
|
175
176
|
end
|
176
177
|
end
|
data/lib/inspec/shell.rb
CHANGED
@@ -112,6 +112,7 @@ module Inspec
|
|
112
112
|
#{print_target_info}
|
113
113
|
EOF
|
114
114
|
elsif topic == "resources"
|
115
|
+
require "inspec/resources"
|
115
116
|
resources.sort.each do |resource|
|
116
117
|
puts " - #{resource}"
|
117
118
|
end
|
@@ -134,7 +135,13 @@ module Inspec
|
|
134
135
|
info += "https://www.inspec.io/docs/reference/resources/#{topic}\n\n"
|
135
136
|
puts info
|
136
137
|
else
|
137
|
-
|
138
|
+
begin
|
139
|
+
require "inspec/resources/#{topic}"
|
140
|
+
help topic
|
141
|
+
rescue LoadError
|
142
|
+
# TODO: stderr!
|
143
|
+
puts "The resource #{topic} does not exist. For a list of valid resources, type: help resources"
|
144
|
+
end
|
138
145
|
end
|
139
146
|
end
|
140
147
|
|
data/lib/inspec/version.rb
CHANGED