inspec-core 4.46.13 → 4.49.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/inspec/base_cli.rb +4 -0
- data/lib/inspec/cli.rb +10 -3
- data/lib/inspec/profile.rb +113 -2
- data/lib/inspec/resources/cassandra.rb +64 -0
- data/lib/inspec/resources/cassandradb_conf.rb +47 -0
- data/lib/inspec/resources/cassandradb_session.rb +68 -0
- data/lib/inspec/resources/groups.rb +22 -3
- data/lib/inspec/resources/oracledb_session.rb +23 -6
- data/lib/inspec/resources/users.rb +16 -2
- data/lib/inspec/resources/windows_firewall.rb +1 -1
- data/lib/inspec/resources.rb +3 -0
- data/lib/inspec/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31dcab9ba9621f43755fc390ad061c08b7e6ab19466d26a38921d33960e1bbf5
|
4
|
+
data.tar.gz: eecdf0ec772ef012bfbf5185b379c47dd008fe902b9e91d4feee6979b0294c0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1059703ad59c2bf7c213a0914f94a8852cc550b1d305f634e07a08b364edae5c0f550927a8bcec9e712cd313949388082fdebf5c3164147ef12c21df952281b9
|
7
|
+
data.tar.gz: 1d4e6e64b8851c40349b7d696d46904fa73c0683d19c70afaa942a4c4bef4591a3ed4d7ec2c89aa5f7717da70617d70f182a7e9b894338da77592231b4c62234
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -174,6 +174,10 @@ module Inspec
|
|
174
174
|
desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
|
175
175
|
option :filter_empty_profiles, type: :boolean, default: false,
|
176
176
|
desc: "Filter empty profiles (profiles without controls) from the report."
|
177
|
+
option :filter_waived_controls, type: :boolean,
|
178
|
+
desc: "Do not execute waived controls in InSpec at all. Must use with --waiver-file. Ignores `run` setting of waiver file."
|
179
|
+
option :retain_waiver_data, type: :boolean,
|
180
|
+
desc: "EXPERIMENTAL: Only works in conjunction with --filter-waived-controls, retains waiver data about controls that were skipped"
|
177
181
|
option :command_timeout, type: :numeric,
|
178
182
|
desc: "Maximum seconds to allow commands to run during execution.",
|
179
183
|
long_desc: "Maximum seconds to allow commands to run during execution. A timed out command is considered an error."
|
data/lib/inspec/cli.rb
CHANGED
@@ -122,8 +122,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
122
122
|
end
|
123
123
|
puts
|
124
124
|
|
125
|
-
if result[:errors].empty? && result[:warnings].empty?
|
126
|
-
ui.plain_line("No errors or
|
125
|
+
if result[:errors].empty? && result[:warnings].empty? && result[:offenses].empty?
|
126
|
+
ui.plain_line("No errors, warnings, or offenses")
|
127
127
|
else
|
128
128
|
item_msg = lambda { |item|
|
129
129
|
pos = [item[:file], item[:line], item[:column]].compact.join(":")
|
@@ -135,11 +135,18 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
135
135
|
|
136
136
|
puts
|
137
137
|
|
138
|
+
unless result[:offenses].empty?
|
139
|
+
puts "Offenses:\n"
|
140
|
+
result[:offenses].each { |item| ui.cyan(" #{Inspec::UI::GLYPHS[:script_x]} #{item_msg.call(item)}\n\n") }
|
141
|
+
end
|
142
|
+
|
143
|
+
offenses = ui.cyan("#{result[:offenses].length} offenses", print: false)
|
138
144
|
errors = ui.red("#{result[:errors].length} errors", print: false)
|
139
145
|
warnings = ui.yellow("#{result[:warnings].length} warnings", print: false)
|
140
|
-
ui.plain_line("Summary: #{errors}, #{warnings}")
|
146
|
+
ui.plain_line("Summary: #{errors}, #{warnings}, #{offenses}")
|
141
147
|
end
|
142
148
|
end
|
149
|
+
|
143
150
|
ui.exit Inspec::UI::EXIT_USAGE_ERROR unless result[:summary][:valid]
|
144
151
|
rescue StandardError => e
|
145
152
|
pretty_handle_exception(e)
|
data/lib/inspec/profile.rb
CHANGED
@@ -217,6 +217,9 @@ module Inspec
|
|
217
217
|
|
218
218
|
locked_dependencies.each(&:collect_tests)
|
219
219
|
|
220
|
+
tests = filter_waived_controls
|
221
|
+
|
222
|
+
# Collect tests
|
220
223
|
tests.each do |path, content|
|
221
224
|
next if content.nil? || content.empty?
|
222
225
|
|
@@ -233,6 +236,65 @@ module Inspec
|
|
233
236
|
@runner_context.all_rules
|
234
237
|
end
|
235
238
|
|
239
|
+
# Wipe out waived controls
|
240
|
+
def filter_waived_controls
|
241
|
+
cfg = Inspec::Config.cached
|
242
|
+
return tests unless cfg["filter_waived_controls"]
|
243
|
+
|
244
|
+
## Find the waivers file
|
245
|
+
# - TODO: cli_opts and instance_variable_get could be exposed
|
246
|
+
waiver_paths = cfg.instance_variable_get(:@cli_opts)["waiver_file"]
|
247
|
+
if waiver_paths.blank?
|
248
|
+
Inspec::Log.error "Must use --waiver-file with --filter-waived-controls"
|
249
|
+
Inspec::UI.new.exit(:usage_error)
|
250
|
+
end
|
251
|
+
|
252
|
+
# # Pull together waiver
|
253
|
+
waived_control_ids = []
|
254
|
+
waiver_paths.each do |waiver_path|
|
255
|
+
waiver_content = YAML.load_file(waiver_path)
|
256
|
+
unless waiver_content
|
257
|
+
# Note that we will have already issued a detailed warning
|
258
|
+
Inspec::Log.error "YAML parsing error in #{waiver_path}"
|
259
|
+
Inspec::UI.new.exit(:usage_error)
|
260
|
+
end
|
261
|
+
waived_control_ids << waiver_content.keys
|
262
|
+
end
|
263
|
+
waived_control_id_regex = "(#{waived_control_ids.join("|")})"
|
264
|
+
|
265
|
+
## Purge tests (this could be doone in next block for performance)
|
266
|
+
## TODO: implement earlier with pure AST and pure autocorrect AST
|
267
|
+
filtered_tests = {}
|
268
|
+
if cfg["retain_waiver_data"]
|
269
|
+
# VERY EXPERIMENTAL, but an empty describe block at the top level
|
270
|
+
# of the control blocks evaluation of ruby code until later-term
|
271
|
+
# waivers (behind the scenes this tells RSpec to hold on and use its internals to lazy load the code). This allows current waiver-data (e.g. skips) to still
|
272
|
+
# be processed and rendered
|
273
|
+
tests.each do |control_filename, source_code|
|
274
|
+
cleared_tests = source_code.scan(/control\s+['"].+?['"].+?(?=(?:control\s+['"].+?['"])|\z)/m).collect do |element|
|
275
|
+
next if element.blank?
|
276
|
+
|
277
|
+
if element&.match?(waived_control_id_regex)
|
278
|
+
splitlines = element.split("\n")
|
279
|
+
splitlines[0] + "\ndescribe '---' do\n" + splitlines[1..-1].join("\n") + "\nend\n"
|
280
|
+
else
|
281
|
+
element
|
282
|
+
end
|
283
|
+
end.join("")
|
284
|
+
filtered_tests[control_filename] = cleared_tests
|
285
|
+
end
|
286
|
+
else
|
287
|
+
tests.each do |control_filename, source_code|
|
288
|
+
cleared_tests = source_code.scan(/control\s+['"].+?['"].+?(?=(?:control\s+['"].+?['"])|\z)/m).select do |control_code|
|
289
|
+
!control_code.match?(waived_control_id_regex)
|
290
|
+
end.join("")
|
291
|
+
|
292
|
+
filtered_tests[control_filename] = cleared_tests
|
293
|
+
end
|
294
|
+
end
|
295
|
+
filtered_tests
|
296
|
+
end
|
297
|
+
|
236
298
|
# This creates the list of controls provided in the --controls options which need to be include
|
237
299
|
# for evaluation.
|
238
300
|
def include_controls_list
|
@@ -386,6 +448,43 @@ module Inspec
|
|
386
448
|
res
|
387
449
|
end
|
388
450
|
|
451
|
+
def cookstyle_linting_check
|
452
|
+
msgs = []
|
453
|
+
output = cookstyle_rake_output.split("Offenses:").last
|
454
|
+
msgs = output.split("\n").select { |x| x =~ /[A-Z]:/ } unless output.nil?
|
455
|
+
msgs
|
456
|
+
end
|
457
|
+
|
458
|
+
# Cookstyle linting rake run output
|
459
|
+
def cookstyle_rake_output
|
460
|
+
require "cookstyle"
|
461
|
+
require "rubocop/rake_task"
|
462
|
+
begin
|
463
|
+
RuboCop::RakeTask.new(:cookstyle_lint) do |spec|
|
464
|
+
spec.options += [
|
465
|
+
"--display-cop-names",
|
466
|
+
"--parallel",
|
467
|
+
"--only=InSpec/Deprecations",
|
468
|
+
]
|
469
|
+
spec.patterns += Dir.glob("#{@target}/**/*.rb").reject { |f| File.directory?(f) }
|
470
|
+
spec.fail_on_error = false
|
471
|
+
end
|
472
|
+
rescue LoadError
|
473
|
+
puts "Rubocop is not available. Install the rubocop gem to run the lint tests."
|
474
|
+
end
|
475
|
+
begin
|
476
|
+
stdout = StringIO.new
|
477
|
+
$stdout = stdout
|
478
|
+
Rake::Task["cookstyle_lint"].invoke
|
479
|
+
$stdout = STDOUT
|
480
|
+
Rake.application["cookstyle_lint"].reenable
|
481
|
+
stdout.string
|
482
|
+
rescue => e
|
483
|
+
puts "Cookstyle lint checks could not be performed. Error while running cookstyle - #{e}"
|
484
|
+
""
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
389
488
|
# Check if the profile is internally well-structured. The logger will be
|
390
489
|
# used to print information on errors and warnings which are found.
|
391
490
|
#
|
@@ -402,6 +501,7 @@ module Inspec
|
|
402
501
|
},
|
403
502
|
errors: [],
|
404
503
|
warnings: [],
|
504
|
+
offenses: [],
|
405
505
|
}
|
406
506
|
|
407
507
|
entry = lambda { |file, line, column, control, msg|
|
@@ -424,6 +524,10 @@ module Inspec
|
|
424
524
|
result[:errors].push(entry.call(file, line, column, control, msg))
|
425
525
|
}
|
426
526
|
|
527
|
+
offense = lambda { |file, line, column, control, msg|
|
528
|
+
result[:offenses].push(entry.call(file, line, column, control, msg))
|
529
|
+
}
|
530
|
+
|
427
531
|
@logger.info "Checking profile in #{@target}"
|
428
532
|
meta_path = @source_reader.target.abs_path(@source_reader.metadata.ref)
|
429
533
|
|
@@ -486,8 +590,15 @@ module Inspec
|
|
486
590
|
warn.call(sfile, sline, nil, id, "Control #{id} has no tests defined") if control[:checks].nil? || control[:checks].empty?
|
487
591
|
end
|
488
592
|
|
489
|
-
#
|
490
|
-
|
593
|
+
# Running cookstyle to check for code offenses
|
594
|
+
cookstyle_linting_check.each do |lint_output|
|
595
|
+
data = lint_output.split(":")
|
596
|
+
msg = "#{data[-2]}:#{data[-1]}"
|
597
|
+
offense.call(data[0], data[1], data[2], nil, msg)
|
598
|
+
end
|
599
|
+
|
600
|
+
# profile is valid if we could not find any error & offenses
|
601
|
+
result[:summary][:valid] = result[:errors].empty? && result[:offenses].empty?
|
491
602
|
|
492
603
|
@logger.info "Control definitions OK." if result[:warnings].empty?
|
493
604
|
result
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Inspec::Resources
|
2
|
+
class Cassandra < Inspec.resource(1)
|
3
|
+
name "cassandra"
|
4
|
+
supports platform: "unix"
|
5
|
+
supports platform: "windows"
|
6
|
+
|
7
|
+
desc "The 'cassandra' resource is a helper for the 'cql_conf'"
|
8
|
+
|
9
|
+
attr_reader :conf_path
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
case inspec.os[:family]
|
13
|
+
when "debian", "redhat", "linux", "suse"
|
14
|
+
determine_conf_dir_and_path_in_linux
|
15
|
+
when "windows"
|
16
|
+
determine_conf_dir_and_path_in_windows
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"CassandraDB"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def determine_conf_dir_and_path_in_linux
|
27
|
+
cassandra_home = inspec.os_env("CASSANDRA_HOME").content
|
28
|
+
|
29
|
+
if cassandra_home.nil? || cassandra_home.empty?
|
30
|
+
warn "$CASSANDRA_HOME environment variable not set in the system"
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
conf_path = "#{cassandra_home}/cassandra.yaml"
|
34
|
+
if !inspec.file(conf_path).exist?
|
35
|
+
warn "Cassandra conf file not found in #{cassandra_home} directory."
|
36
|
+
nil
|
37
|
+
else
|
38
|
+
@conf_path = conf_path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
rescue => e
|
42
|
+
fail_resource "Errors reading cassandra conf file: #{e}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def determine_conf_dir_and_path_in_windows
|
46
|
+
cassandra_home = inspec.os_env("CASSANDRA_HOME").content
|
47
|
+
|
48
|
+
if cassandra_home.nil? || cassandra_home.empty?
|
49
|
+
warn "CASSANDRA_HOME environment variable not set in the system"
|
50
|
+
nil
|
51
|
+
else
|
52
|
+
conf_path = "#{cassandra_home}\\conf\\cassandra.yaml"
|
53
|
+
if !inspec.file(conf_path).exist?
|
54
|
+
warn "Cassandra conf file not found in #{cassandra_home}\\conf directory."
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
@conf_path = conf_path
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue => e
|
61
|
+
fail_resource "Errors reading cassandra conf file: #{e}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "inspec/resources/json"
|
2
|
+
require "inspec/resources/cassandra"
|
3
|
+
|
4
|
+
module Inspec::Resources
|
5
|
+
class CassandradbConf < JsonConfig
|
6
|
+
name "cassandradb_conf"
|
7
|
+
supports platform: "unix"
|
8
|
+
supports platform: "windows"
|
9
|
+
desc "Use the cql_conf InSpec audit resource to test the contents of the configuration file for Cassandra DB"
|
10
|
+
example <<~EXAMPLE
|
11
|
+
describe cassandradb_conf do
|
12
|
+
its('listen_address') { should eq '0.0.0.0' }
|
13
|
+
end
|
14
|
+
EXAMPLE
|
15
|
+
|
16
|
+
def initialize(conf_path = nil)
|
17
|
+
cassandra = nil
|
18
|
+
if conf_path.nil?
|
19
|
+
cassandra = inspec.cassandra
|
20
|
+
@conf_path = cassandra.conf_path
|
21
|
+
else
|
22
|
+
@conf_path = conf_path
|
23
|
+
end
|
24
|
+
|
25
|
+
if cassandra && cassandra.resource_failed?
|
26
|
+
raise cassandra.resource_exception_message
|
27
|
+
elsif @conf_path.nil?
|
28
|
+
return skip_resource "Cassandra db conf path is not set"
|
29
|
+
end
|
30
|
+
|
31
|
+
super(@conf_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def parse(content)
|
37
|
+
YAML.load(content)
|
38
|
+
rescue => e
|
39
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to parse `cassandra.yaml` file: #{e.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def resource_base_name
|
43
|
+
"Cassandra Configuration"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Inspec::Resources
|
2
|
+
class Lines
|
3
|
+
attr_reader :output
|
4
|
+
|
5
|
+
def initialize(raw, desc)
|
6
|
+
@output = raw
|
7
|
+
@desc = desc
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
@desc
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class CassandradbSession < Inspec.resource(1)
|
16
|
+
name "cassandradb_session"
|
17
|
+
supports platform: "unix"
|
18
|
+
supports platform: "windows"
|
19
|
+
desc "Use the cassandradb_session InSpec resource to test commands against an Cassandra database"
|
20
|
+
example <<~EXAMPLE
|
21
|
+
cql = cassandradb_session(user: 'my_user', password: 'password', host: 'host', port: 'port')
|
22
|
+
describe cql.query("SELECT cluster_name FROM system.local") do
|
23
|
+
its('output') { should match /Test Cluster/ }
|
24
|
+
end
|
25
|
+
EXAMPLE
|
26
|
+
|
27
|
+
attr_reader :user, :password, :host, :port
|
28
|
+
|
29
|
+
def initialize(opts = {})
|
30
|
+
@user = opts[:user] || "cassandra"
|
31
|
+
@password = opts[:password] || "cassandra"
|
32
|
+
@host = opts[:host]
|
33
|
+
@port = opts[:port]
|
34
|
+
end
|
35
|
+
|
36
|
+
def query(q)
|
37
|
+
cassandra_cmd = create_cassandra_cmd(q)
|
38
|
+
cmd = inspec.command(cassandra_cmd)
|
39
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
40
|
+
if cmd.exit_status != 0 || out =~ /Unable to connect to any servers/ || out.downcase =~ /^error:.*/
|
41
|
+
raise Inspec::Exceptions::ResourceFailed, "Cassandra query with errors: #{out}"
|
42
|
+
else
|
43
|
+
Lines.new(cmd.stdout.strip, "Cassandra query: #{q}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
"Cassandra DB Session"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def create_cassandra_cmd(q)
|
54
|
+
# TODO: simple escape, must be handled by a library
|
55
|
+
# that does this securely
|
56
|
+
escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
57
|
+
|
58
|
+
# construct the query
|
59
|
+
command = "cqlsh"
|
60
|
+
command += " #{@host}" unless @host.nil?
|
61
|
+
command += " #{@port}" unless @port.nil?
|
62
|
+
command += " -u #{@user}"
|
63
|
+
command += " -p #{@password}"
|
64
|
+
command += " --execute '#{escaped_query}'"
|
65
|
+
command
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -22,6 +22,18 @@ module Inspec::Resources
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# Class defined to check for members without case-sensitivity
|
26
|
+
class Members < Array
|
27
|
+
def initialize(group_members)
|
28
|
+
@group_members = group_members
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def include?(user)
|
33
|
+
!(@group_members.select { |group_member| group_member.casecmp?(user) }.empty?)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
class Groups < Inspec.resource(1)
|
26
38
|
include GroupManagementSelector
|
27
39
|
|
@@ -82,6 +94,7 @@ module Inspec::Resources
|
|
82
94
|
# its('gid') { should eq 0 }
|
83
95
|
# end
|
84
96
|
#
|
97
|
+
|
85
98
|
class Group < Inspec.resource(1)
|
86
99
|
include GroupManagementSelector
|
87
100
|
|
@@ -118,11 +131,13 @@ module Inspec::Resources
|
|
118
131
|
end
|
119
132
|
|
120
133
|
def members
|
121
|
-
flatten_entry(group_info, "members") || empty_value_for_members
|
134
|
+
members_list = flatten_entry(group_info, "members") || empty_value_for_members
|
135
|
+
inspec.os.windows? ? Members.new(members_list) : members_list
|
122
136
|
end
|
123
137
|
|
124
138
|
def members_array
|
125
|
-
flatten_entry(group_info, "members_array") || []
|
139
|
+
members_list = flatten_entry(group_info, "members_array") || []
|
140
|
+
inspec.os.windows? ? Members.new(members_list) : members_list
|
126
141
|
end
|
127
142
|
|
128
143
|
def local
|
@@ -150,7 +165,11 @@ module Inspec::Resources
|
|
150
165
|
def group_info
|
151
166
|
# we need a local copy for the block
|
152
167
|
group = @group.dup
|
153
|
-
|
168
|
+
if inspec.os.windows?
|
169
|
+
@groups_cache ||= inspec.groups.where { name.casecmp?(group) }
|
170
|
+
else
|
171
|
+
@groups_cache ||= inspec.groups.where { name == group }
|
172
|
+
end
|
154
173
|
end
|
155
174
|
|
156
175
|
def empty_value_for_members
|
@@ -42,6 +42,7 @@ module Inspec::Resources
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def query(sql)
|
45
|
+
raise Inspec::Exceptions::ResourceSkipped, "#{resource_exception_message}" if resource_skipped?
|
45
46
|
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
|
46
47
|
|
47
48
|
if @sqlcl_bin && inspec.command(@sqlcl_bin).exist?
|
@@ -78,7 +79,14 @@ module Inspec::Resources
|
|
78
79
|
# using a db_role
|
79
80
|
# su, using a db_role
|
80
81
|
def command_builder(format_options, query)
|
81
|
-
|
82
|
+
if @db_role.nil? || @su_user.nil?
|
83
|
+
verified_query = verify_query(query)
|
84
|
+
else
|
85
|
+
escaped_query = query.gsub(/\\\\/, "\\").gsub(/"/, '\\"')
|
86
|
+
escaped_query = escaped_query.gsub("$", '\\$') unless escaped_query.include? "\\$"
|
87
|
+
verified_query = verify_query(escaped_query)
|
88
|
+
end
|
89
|
+
|
82
90
|
sql_prefix, sql_postfix = "", ""
|
83
91
|
if inspec.os.windows?
|
84
92
|
sql_prefix = %{@'\n#{format_options}\n#{verified_query}\nEXIT\n'@ | }
|
@@ -87,11 +95,14 @@ module Inspec::Resources
|
|
87
95
|
end
|
88
96
|
|
89
97
|
if @db_role.nil?
|
90
|
-
|
98
|
+
%{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}}
|
91
99
|
elsif @su_user.nil?
|
92
|
-
|
100
|
+
%{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
|
93
101
|
else
|
94
|
-
|
102
|
+
# oracle_query_string is echoed to be able to extract the query output clearly
|
103
|
+
# su - su_user in certain versions of oracle returns a message
|
104
|
+
# Example of msg with query output: The Oracle base remains unchanged with value /oracle\n\nVALUE\n3\n
|
105
|
+
%{su - #{@su_user} -c "echo 'oracle_query_string'; env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
|
95
106
|
end
|
96
107
|
end
|
97
108
|
|
@@ -101,9 +112,15 @@ module Inspec::Resources
|
|
101
112
|
end
|
102
113
|
|
103
114
|
def parse_csv_result(stdout)
|
104
|
-
output = stdout.
|
115
|
+
output = stdout.split("oracle_query_string")[-1]
|
116
|
+
# comma_query_sub replaces the csv delimiter "," in the output.
|
117
|
+
# Handles CSV parsing of data like this (DROP,3) etc
|
118
|
+
output = output.sub(/\r/, "").strip.gsub(",", "comma_query_sub")
|
105
119
|
converter = ->(header) { header.downcase }
|
106
|
-
CSV.parse(output, headers: true, header_converters: converter).map
|
120
|
+
CSV.parse(output, headers: true, header_converters: converter).map do |row|
|
121
|
+
revised_row = row.entries.flatten.map { |entry| entry.gsub("comma_query_sub", ",") }
|
122
|
+
Hashie::Mash.new([revised_row].to_h)
|
123
|
+
end
|
107
124
|
end
|
108
125
|
end
|
109
126
|
end
|
@@ -204,7 +204,9 @@ module Inspec::Resources
|
|
204
204
|
alias group groupname
|
205
205
|
|
206
206
|
def groups
|
207
|
-
|
207
|
+
unless identity.nil?
|
208
|
+
inspec.os.windows? ? UserGroups.new(identity[:groups]) : identity[:groups]
|
209
|
+
end
|
208
210
|
end
|
209
211
|
|
210
212
|
def home
|
@@ -314,6 +316,18 @@ module Inspec::Resources
|
|
314
316
|
end
|
315
317
|
end
|
316
318
|
|
319
|
+
# Class defined to compare for groups without case-sensitivity
|
320
|
+
class UserGroups < Array
|
321
|
+
def initialize(user_groups)
|
322
|
+
@user_groups = user_groups
|
323
|
+
super
|
324
|
+
end
|
325
|
+
|
326
|
+
def include?(group)
|
327
|
+
!(@user_groups.select { |user_group| user_group.casecmp?(group) }.empty?)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
317
331
|
# This is an abstract class that every user provoider has to implement.
|
318
332
|
# A user provider implements a system abstracts and helps the InSpec resource
|
319
333
|
# hand-over system specific behavior to those providers
|
@@ -622,7 +636,7 @@ module Inspec::Resources
|
|
622
636
|
name, _domain = parse_windows_account(username)
|
623
637
|
return if collect_user_details.nil?
|
624
638
|
|
625
|
-
res = collect_user_details.select { |user| user[:username]
|
639
|
+
res = collect_user_details.select { |user| user[:username].casecmp? name }
|
626
640
|
res[0] unless res.empty?
|
627
641
|
end
|
628
642
|
|
@@ -77,7 +77,7 @@ module Inspec::Resources
|
|
77
77
|
|
78
78
|
def load_firewall_profile(profile_name)
|
79
79
|
<<-EOH
|
80
|
-
|
80
|
+
Get-TypeData -TypeName System.Array | Remove-TypeData # workaround for PS bug here: https://bit.ly/2SRMQ8M
|
81
81
|
$profile = Get-NetFirewallProfile -Name "#{profile_name}"
|
82
82
|
$count = @($profile | Get-NetFirewallRule).Count
|
83
83
|
([PSCustomObject]@{
|
data/lib/inspec/resources.rb
CHANGED
@@ -37,6 +37,9 @@ require "inspec/resources/chocolatey_package"
|
|
37
37
|
require "inspec/resources/command"
|
38
38
|
require "inspec/resources/cran"
|
39
39
|
require "inspec/resources/cpan"
|
40
|
+
require "inspec/resources/cassandradb_session"
|
41
|
+
require "inspec/resources/cassandradb_conf"
|
42
|
+
require "inspec/resources/cassandra"
|
40
43
|
require "inspec/resources/crontab"
|
41
44
|
require "inspec/resources/dh_params"
|
42
45
|
require "inspec/resources/directory"
|
data/lib/inspec/version.rb
CHANGED
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.
|
4
|
+
version: 4.49.0
|
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: 2021-
|
11
|
+
date: 2021-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-telemetry
|
@@ -505,6 +505,9 @@ files:
|
|
505
505
|
- lib/inspec/resources/bond.rb
|
506
506
|
- lib/inspec/resources/bridge.rb
|
507
507
|
- lib/inspec/resources/bsd_service.rb
|
508
|
+
- lib/inspec/resources/cassandra.rb
|
509
|
+
- lib/inspec/resources/cassandradb_conf.rb
|
510
|
+
- lib/inspec/resources/cassandradb_session.rb
|
508
511
|
- lib/inspec/resources/chocolatey_package.rb
|
509
512
|
- lib/inspec/resources/chrony_conf.rb
|
510
513
|
- lib/inspec/resources/command.rb
|