inspec-core 4.50.3 → 4.56.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +7 -11
- data/inspec-core.gemspec +2 -2
- data/lib/bundles/inspec-supermarket/README.md +21 -2
- data/lib/bundles/inspec-supermarket/cli.rb +20 -3
- data/lib/bundles/inspec-supermarket/target.rb +3 -2
- data/lib/inspec/base_cli.rb +8 -0
- data/lib/inspec/config.rb +5 -1
- data/lib/inspec/dependencies/requirement.rb +2 -1
- data/lib/inspec/formatters/base.rb +8 -6
- data/lib/inspec/library_eval_context.rb +2 -0
- data/lib/inspec/plugin/v1/registry.rb +1 -1
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +10 -0
- data/lib/inspec/profile_context.rb +1 -6
- data/lib/inspec/reporters/automate.rb +1 -1
- data/lib/inspec/reporters/json.rb +1 -1
- data/lib/inspec/resources/auditd.rb +5 -4
- data/lib/inspec/resources/bash.rb +2 -0
- data/lib/inspec/resources/file.rb +38 -0
- data/lib/inspec/resources/firewalld.rb +83 -9
- data/lib/inspec/resources/grub_conf.rb +1 -1
- data/lib/inspec/resources/http.rb +31 -2
- data/lib/inspec/resources/ibmdb2_session.rb +2 -2
- data/lib/inspec/resources/iptables.rb +18 -2
- data/lib/inspec/resources/kernel_parameters.rb +58 -0
- data/lib/inspec/resources/mssql_session.rb +11 -3
- data/lib/inspec/resources/oracledb_session.rb +10 -4
- data/lib/inspec/resources/package.rb +74 -1
- data/lib/inspec/resources/packages.rb +21 -0
- data/lib/inspec/resources/postgres_session.rb +4 -2
- data/lib/inspec/resources/registry_key.rb +30 -0
- data/lib/inspec/resources/selinux.rb +6 -1
- data/lib/inspec/resources/service.rb +58 -9
- data/lib/inspec/resources/ssl.rb +7 -0
- data/lib/inspec/resources/timezone.rb +65 -0
- data/lib/inspec/resources.rb +2 -0
- data/lib/inspec/runner_rspec.rb +30 -0
- data/lib/inspec/utils/filter.rb +46 -2
- data/lib/inspec/utils/run_data_filters.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +1 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +4 -3
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58efdb5e3457dcb1bf97227b98e1f723c672c7eadc995ef3f07b1f2a910c47db
|
4
|
+
data.tar.gz: 0f789e778551423ccfdacc52dbcda63c597b3e8d83b00739aa36becc52502213
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96f3692d1e3dee025002b7e661a635a33cf8ae353e164e2931a6d139d2711c1c94162e69fdc9db52a28fe3a1eb85319f7b08ae27e0f68528603c0e9096a758e2
|
7
|
+
data.tar.gz: dc1ec6f7322e4cbac56cb1cfe6f6761f44b455c77d069b414c3ec759695ce9ff260deee62c9a0a3184f0a800d31e5fdad8c791bd04fc40bc4d0fafc1fe87f84e
|
data/Gemfile
CHANGED
@@ -11,11 +11,6 @@ gem "inspec-bin", path: "./inspec-bin"
|
|
11
11
|
|
12
12
|
gem "ffi", ">= 1.9.14", "!= 1.13.0", "!= 1.14.2"
|
13
13
|
|
14
|
-
if Gem.ruby_version.to_s.start_with?("2.5")
|
15
|
-
# 16.7.23 required ruby 2.6+
|
16
|
-
gem "chef-utils", "< 16.7.23" # TODO: remove when we drop ruby 2.5
|
17
|
-
end
|
18
|
-
|
19
14
|
# inspec tests depend text output that changed in the 3.10 release
|
20
15
|
# but our runtime dep is still 3.9+
|
21
16
|
gem "rspec", ">= 3.10"
|
@@ -30,11 +25,7 @@ end
|
|
30
25
|
group :test do
|
31
26
|
gem "chefstyle", "~> 2.0.3"
|
32
27
|
gem "concurrent-ruby", "~> 1.0"
|
33
|
-
|
34
|
-
gem "html-proofer", "= 3.19.1" , platforms: :ruby # do not attempt to run proofer on windows
|
35
|
-
else
|
36
|
-
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
|
37
|
-
end
|
28
|
+
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
|
38
29
|
gem "json_schemer", ">= 0.2.1", "< 0.2.19"
|
39
30
|
gem "m"
|
40
31
|
gem "minitest-sprint", "~> 1.0"
|
@@ -45,7 +36,8 @@ group :test do
|
|
45
36
|
gem "pry", "~> 0.10"
|
46
37
|
gem "rake", ">= 10"
|
47
38
|
gem "ruby-progressbar", "~> 1.8"
|
48
|
-
gem "simplecov", "~> 0.
|
39
|
+
gem "simplecov", "~> 0.21"
|
40
|
+
gem "simplecov_json_formatter"
|
49
41
|
gem "webmock", "~> 3.0"
|
50
42
|
end
|
51
43
|
|
@@ -66,3 +58,7 @@ if Gem.ruby_version >= Gem::Version.new("2.7.0")
|
|
66
58
|
gem "git"
|
67
59
|
end
|
68
60
|
end
|
61
|
+
|
62
|
+
if Gem.ruby_version < Gem::Version.new("2.7.0")
|
63
|
+
gem "activesupport", "6.1.4.4"
|
64
|
+
end
|
data/inspec-core.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.license = "Apache-2.0"
|
14
14
|
spec.require_paths = ["lib"]
|
15
15
|
|
16
|
-
spec.required_ruby_version = ">= 2.
|
16
|
+
spec.required_ruby_version = ">= 2.6"
|
17
17
|
|
18
18
|
# the gemfile and gemspec are necessary for appbundler so don't remove it
|
19
19
|
spec.files =
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_dependency "thor", ">= 0.20", "< 2.0"
|
29
29
|
spec.add_dependency "method_source", ">= 0.8", "< 2.0"
|
30
30
|
spec.add_dependency "rubyzip", ">= 1.2.2", "< 3.0"
|
31
|
-
spec.add_dependency "rspec", ">= 3.9", "
|
31
|
+
spec.add_dependency "rspec", ">= 3.9", "<= 3.11"
|
32
32
|
spec.add_dependency "rspec-its", "~> 1.2"
|
33
33
|
spec.add_dependency "pry", "~> 0.13"
|
34
34
|
spec.add_dependency "hashie", ">= 3.4", "< 5.0"
|
@@ -8,8 +8,27 @@ To use the CLI, this InSpec add-on adds the following commands:
|
|
8
8
|
|
9
9
|
Compliance profiles from Supermarket can be executed in two ways:
|
10
10
|
|
11
|
-
- via supermarket exec:
|
12
|
-
|
11
|
+
- via supermarket exec:
|
12
|
+
|
13
|
+
**Public Supermarket**
|
14
|
+
|
15
|
+
`inspec supermarket exec nathenharvey/tmp-compliance-profile`
|
16
|
+
|
17
|
+
**Private Supermarket**
|
18
|
+
|
19
|
+
`inspec supermarket exec nathenharvey/tmp-compliance-profile --supermarket_url="PRIVATE_SUPERMARKET_URL"`
|
20
|
+
|
21
|
+
|
22
|
+
- via supermarket scheme:
|
23
|
+
|
24
|
+
**Public Supermarket**
|
25
|
+
|
26
|
+
`inspec exec supermarket://nathenharvey/tmp-compliance-profile`
|
27
|
+
|
28
|
+
**Private Supermarket**
|
29
|
+
|
30
|
+
`inspec exec supermarket://nathenharvey/tmp-compliance-profile --supermarket_url="PRIVATE_SUPERMARKET_URL"`
|
31
|
+
|
13
32
|
|
14
33
|
## Usage
|
15
34
|
|
@@ -15,10 +15,18 @@ module Supermarket
|
|
15
15
|
end
|
16
16
|
|
17
17
|
desc "profiles", "list all available profiles in Chef Supermarket"
|
18
|
+
supermarket_options
|
18
19
|
def profiles
|
19
|
-
|
20
|
-
|
20
|
+
o = config
|
21
|
+
diagnose(o)
|
22
|
+
configure_logger(o)
|
21
23
|
|
24
|
+
# display profiles in format user/profile
|
25
|
+
supermarket_profiles = if o["supermarket_url"]
|
26
|
+
Supermarket::API.profiles(o["supermarket_url"])
|
27
|
+
else
|
28
|
+
Supermarket::API.profiles
|
29
|
+
end
|
22
30
|
headline("Available profiles:")
|
23
31
|
supermarket_profiles.each do |p|
|
24
32
|
li("#{p["tool_name"]} #{mark_text(p["tool_owner"] + "/" + p["slug"])}")
|
@@ -45,9 +53,18 @@ module Supermarket
|
|
45
53
|
end
|
46
54
|
|
47
55
|
desc "info PROFILE", "display Supermarket profile details"
|
56
|
+
supermarket_options
|
48
57
|
def info(profile)
|
58
|
+
o = config
|
59
|
+
diagnose(o)
|
60
|
+
configure_logger(o)
|
61
|
+
|
49
62
|
# check that the profile is available
|
50
|
-
supermarket_profiles =
|
63
|
+
supermarket_profiles = if o["supermarket_url"]
|
64
|
+
Supermarket::API.profiles(o["supermarket_url"])
|
65
|
+
else
|
66
|
+
Supermarket::API.profiles
|
67
|
+
end
|
51
68
|
found = supermarket_profiles.select do |p|
|
52
69
|
profile == "#{p["tool_owner"]}/#{p["slug"]}"
|
53
70
|
end
|
@@ -9,10 +9,11 @@ module Supermarket
|
|
9
9
|
priority 500
|
10
10
|
|
11
11
|
def self.resolve(target, opts = {})
|
12
|
+
supermarket_url = opts["supermarket_url"] || Supermarket::API::SUPERMARKET_URL
|
12
13
|
supermarket_uri, supermarket_server = if target.is_a?(String) && URI(target).scheme == "supermarket"
|
13
|
-
[target,
|
14
|
+
[target, supermarket_url]
|
14
15
|
elsif target.respond_to?(:key?) && target.key?(:supermarket)
|
15
|
-
supermarket_server = target[:supermarket_url] ||
|
16
|
+
supermarket_server = target[:supermarket_url] || supermarket_url
|
16
17
|
["supermarket://#{target[:supermarket]}", supermarket_server]
|
17
18
|
end
|
18
19
|
return nil unless supermarket_uri
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -126,6 +126,8 @@ module Inspec
|
|
126
126
|
desc: "Specify a shell type for winrm (eg. 'elevated' or 'powershell')"
|
127
127
|
option :docker_url, type: :string,
|
128
128
|
desc: "Provides path to Docker API endpoint (Docker)"
|
129
|
+
option :ssh_config_file, type: :array,
|
130
|
+
desc: "A list of paths to the ssh config file, e.g ~/.ssh/config or /etc/ssh/ssh_config"
|
129
131
|
end
|
130
132
|
|
131
133
|
def self.profile_options
|
@@ -135,9 +137,15 @@ module Inspec
|
|
135
137
|
desc: "Use the given path for caching dependencies. (default: ~/.inspec/cache)"
|
136
138
|
end
|
137
139
|
|
140
|
+
def self.supermarket_options
|
141
|
+
option :supermarket_url, type: :string,
|
142
|
+
desc: "Specify the URL of a private Chef Supermarket."
|
143
|
+
end
|
144
|
+
|
138
145
|
def self.exec_options
|
139
146
|
target_options
|
140
147
|
profile_options
|
148
|
+
supermarket_options
|
141
149
|
option :controls, type: :array,
|
142
150
|
desc: "A list of control names to run, or a list of /regexes/ to match against control names. Ignore all other tests."
|
143
151
|
option :tags, type: :array,
|
data/lib/inspec/config.rb
CHANGED
@@ -367,7 +367,11 @@ module Inspec
|
|
367
367
|
.find_activators(plugin_type: :reporter)\
|
368
368
|
.map(&:activator_name).map(&:to_s)
|
369
369
|
|
370
|
-
|
370
|
+
streaming_reporters = Inspec::Plugin::V2::Registry.instance\
|
371
|
+
.find_activators(plugin_type: :streaming_reporter)\
|
372
|
+
.map(&:activator_name).map(&:to_s)
|
373
|
+
|
374
|
+
valid_types = rspec_built_in_formatters + inspec_reporters_that_are_not_yet_plugins + plugin_reporters + streaming_reporters
|
371
375
|
|
372
376
|
reporters.each do |reporter_name, reporter_config|
|
373
377
|
raise NotImplementedError, "'#{reporter_name}' is not a valid reporter type." unless valid_types.include?(reporter_name)
|
@@ -102,7 +102,8 @@ module Inspec
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def fetcher
|
105
|
-
@
|
105
|
+
@runner_options ||= (Inspec::Config.cached || {})
|
106
|
+
@fetcher ||= Inspec::CachedFetcher.new(opts, @cache, @runner_options)
|
106
107
|
end
|
107
108
|
|
108
109
|
# load dependencies of the dependency
|
@@ -70,6 +70,7 @@ module Inspec::Formatters
|
|
70
70
|
name: platform(:name),
|
71
71
|
release: platform(:release),
|
72
72
|
target: backend_target,
|
73
|
+
target_id: platform(:uuid),
|
73
74
|
}
|
74
75
|
end
|
75
76
|
|
@@ -205,12 +206,13 @@ module Inspec::Formatters
|
|
205
206
|
def platform(field)
|
206
207
|
return nil if @backend.nil?
|
207
208
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
209
|
+
@backend.platform[field]
|
210
|
+
rescue Train::PlatformUuidDetectionFailed
|
211
|
+
Inspec::Log.warn("Could not find platform target_id.")
|
212
|
+
nil
|
213
|
+
rescue Train::Error => e
|
214
|
+
Inspec::Log.warn(e.message)
|
215
|
+
nil
|
214
216
|
end
|
215
217
|
|
216
218
|
def backend_target
|
@@ -11,7 +11,7 @@ class PluginRegistry
|
|
11
11
|
# @return [Plugin] plugin instance if it can be resolved, nil otherwise
|
12
12
|
def resolve(target, opts = {})
|
13
13
|
modules.each do |m|
|
14
|
-
res = if Inspec::Fetcher::Url
|
14
|
+
res = if ["Inspec::Fetcher::Url", "Supermarket::Fetcher"].include? m.to_s
|
15
15
|
m.resolve(target, opts)
|
16
16
|
else
|
17
17
|
m.resolve(target)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Inspec::Plugin::V2::PluginType
|
2
|
+
class StreamingReporter < Inspec::Plugin::V2::PluginBase # TBD Superclass may need to change
|
3
|
+
register_plugin_type(:streaming_reporter)
|
4
|
+
|
5
|
+
#====================================================================#
|
6
|
+
# StreamingReporter plugin type API
|
7
|
+
#====================================================================#
|
8
|
+
# Implementation classes must implement these methods.
|
9
|
+
end
|
10
|
+
end
|
@@ -68,6 +68,7 @@ module Inspec
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def reload_dsl
|
71
|
+
@resource_registry.merge!(Inspec::Resource.new_registry)
|
71
72
|
@control_eval_context = nil
|
72
73
|
end
|
73
74
|
|
@@ -263,9 +264,3 @@ module Inspec
|
|
263
264
|
end # DomainSpecificLunacy
|
264
265
|
end # ProfileContext
|
265
266
|
end
|
266
|
-
|
267
|
-
if RUBY_VERSION < "2.5"
|
268
|
-
class Module
|
269
|
-
public :define_method
|
270
|
-
end
|
271
|
-
end
|
@@ -21,7 +21,7 @@ module Inspec::Reporters
|
|
21
21
|
final_report[:type] = "inspec_report"
|
22
22
|
|
23
23
|
final_report[:end_time] = Time.now.utc.strftime("%FT%TZ")
|
24
|
-
final_report[:node_uuid] = @config["node_uuid"] || @config["target_id"]
|
24
|
+
final_report[:node_uuid] = report[:platform][:target_id] || @config["node_uuid"] || @config["target_id"]
|
25
25
|
raise Inspec::ReporterError, "Cannot find a UUID for your node. Please specify one via json-config." if final_report[:node_uuid].nil?
|
26
26
|
|
27
27
|
final_report[:report_uuid] = @config["report_uuid"] || uuid_from_string(final_report[:end_time] + final_report[:node_uuid])
|
@@ -28,12 +28,13 @@ module Inspec::Resources
|
|
28
28
|
EXAMPLE
|
29
29
|
|
30
30
|
def initialize
|
31
|
-
|
31
|
+
@auditctl_cmd_str = inspec.os.name.eql?("alpine") ? "/usr/sbin/auditctl" : "/sbin/auditctl"
|
32
|
+
unless inspec.command(@auditctl_cmd_str).exist?
|
32
33
|
raise Inspec::Exceptions::ResourceFailed,
|
33
|
-
"Command
|
34
|
+
"Command `#{@auditctl_cmd_str}` does not exist"
|
34
35
|
end
|
35
36
|
|
36
|
-
auditctl_cmd = "
|
37
|
+
auditctl_cmd = "#{@auditctl_cmd_str} -l"
|
37
38
|
result = inspec.command(auditctl_cmd)
|
38
39
|
|
39
40
|
if result.exit_status != 0
|
@@ -68,7 +69,7 @@ module Inspec::Resources
|
|
68
69
|
filter.install_filter_methods_on_resource(self, :params)
|
69
70
|
|
70
71
|
def status(name = nil)
|
71
|
-
@status_content ||= inspec.command("
|
72
|
+
@status_content ||= inspec.command("#{@auditctl_cmd_str} -s").stdout.chomp
|
72
73
|
|
73
74
|
# See: https://github.com/inspec/inspec/issues/3113
|
74
75
|
if @status_content =~ /^AUDIT_STATUS/
|
@@ -61,6 +61,24 @@ module Inspec::Resources
|
|
61
61
|
res.force_encoding("utf-8")
|
62
62
|
end
|
63
63
|
|
64
|
+
# returns hash containing list of users/groups and their file permissions.
|
65
|
+
def user_permissions
|
66
|
+
return {} unless exist?
|
67
|
+
|
68
|
+
return skip_reource"`user_permissions` is not supported on your OS yet." unless inspec.os.windows?
|
69
|
+
|
70
|
+
@perms_provider.user_permissions(file)
|
71
|
+
end
|
72
|
+
|
73
|
+
# returns true if inheritance is enabled on file or folder
|
74
|
+
def inherited?
|
75
|
+
return false unless exist?
|
76
|
+
|
77
|
+
return skip_resource "`inherited?` is not supported on your OS yet." unless inspec.os.windows?
|
78
|
+
|
79
|
+
@perms_provider.inherited?(file)
|
80
|
+
end
|
81
|
+
|
64
82
|
def contain(*_)
|
65
83
|
raise "Contain is not supported. Please use standard RSpec matchers."
|
66
84
|
end
|
@@ -244,6 +262,26 @@ module Inspec::Resources
|
|
244
262
|
end
|
245
263
|
|
246
264
|
class WindowsFilePermissions < FilePermissions
|
265
|
+
|
266
|
+
def user_permissions(file)
|
267
|
+
script = <<-EOH
|
268
|
+
$Acl = Get-Acl -Path #{file.path}
|
269
|
+
$Result = foreach ($Access in $acl.Access) {
|
270
|
+
[PSCustomObject]@{
|
271
|
+
$Access.IdentityReference.Value = $Access.FileSystemRights.ToString()
|
272
|
+
}
|
273
|
+
}
|
274
|
+
$Result | ConvertTo-Json
|
275
|
+
EOH
|
276
|
+
result = inspec.powershell(script)
|
277
|
+
JSON.load(result.stdout).inject(&:merge) unless result.stdout.empty?
|
278
|
+
end
|
279
|
+
|
280
|
+
def inherited?(file)
|
281
|
+
cmd = inspec.command("(Get-Acl -Path #{file.path}).access| Where-Object {$_.IsInherited -eq $true} | measure | % { $_.Count }")
|
282
|
+
cmd.stdout.chomp == "0" ? false : true
|
283
|
+
end
|
284
|
+
|
247
285
|
def check_file_permission_by_mask(_file, _access_type, _usergroup, _specific_user)
|
248
286
|
raise "`check_file_permission_by_mask` is not supported on Windows"
|
249
287
|
end
|
@@ -32,6 +32,17 @@ module Inspec::Resources
|
|
32
32
|
.register_column(:interfaces, field: "interfaces")
|
33
33
|
.register_column(:sources, field: "sources")
|
34
34
|
.register_column(:services, field: "services")
|
35
|
+
.register_column(:target, field: "target")
|
36
|
+
.register_column(:ports, field: "ports")
|
37
|
+
.register_column(:protocols, field: "protocols")
|
38
|
+
.register_column(:forward_ports, field: "forward_ports")
|
39
|
+
.register_column(:source_ports, field: "source_ports")
|
40
|
+
.register_column(:icmp_blocks, field: "icmp_blocks")
|
41
|
+
.register_column(:rich_rules, field: "rich_rules")
|
42
|
+
.register_custom_matcher(:icmp_block_inversion?) { |x| x.params[0]["icmp_block_inversion"] }
|
43
|
+
.register_custom_matcher(:has_icmp_block_inversion_enabled?) { |x| x.params[0]["icmp_block_inversion"] }
|
44
|
+
.register_custom_matcher(:masquerade?) { |x| x.params[0]["masquerade"] }
|
45
|
+
.register_custom_matcher(:has_masquerade_enabled?) { |x| x.params[0]["masquerade"] }
|
35
46
|
|
36
47
|
filter.install_filter_methods_on_resource(self, :params)
|
37
48
|
|
@@ -64,28 +75,28 @@ module Inspec::Resources
|
|
64
75
|
end
|
65
76
|
|
66
77
|
def has_service_enabled_in_zone?(query_service, query_zone = default_zone)
|
67
|
-
firewalld_command("--zone=#{query_zone} --query-service=#{query_service}") == "yes"
|
78
|
+
firewalld_command("--permanent --zone=#{query_zone} --query-service=#{query_service}") == "yes"
|
68
79
|
end
|
69
80
|
|
70
81
|
def service_ports_enabled_in_zone(query_service, query_zone = default_zone)
|
71
82
|
# return: String of ports open
|
72
83
|
# example: ['22/tcp', '4722/tcp']
|
73
|
-
firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-ports
|
84
|
+
firewalld_command("--permanent --zone=#{query_zone} --service=#{query_service} --get-ports").split(" ")
|
74
85
|
end
|
75
86
|
|
76
87
|
def service_protocols_enabled_in_zone(query_service, query_zone = default_zone)
|
77
|
-
# return: String of
|
88
|
+
# return: String of protocols open
|
78
89
|
# example: ['icmp', 'ipv4', 'igmp']
|
79
|
-
firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-protocols
|
90
|
+
firewalld_command("--permanent --zone=#{query_zone} --service=#{query_service} --get-protocols").split(" ")
|
80
91
|
end
|
81
92
|
|
82
93
|
def has_port_enabled_in_zone?(query_port, query_zone = default_zone)
|
83
|
-
firewalld_command("--zone=#{query_zone} --query-port=#{query_port}") == "yes"
|
94
|
+
firewalld_command("--permanent --zone=#{query_zone} --query-port=#{query_port}") == "yes"
|
84
95
|
end
|
85
96
|
|
86
97
|
def has_rule_enabled?(rule, query_zone = default_zone)
|
87
98
|
rule = "rule #{rule}" unless rule.start_with?("rule")
|
88
|
-
firewalld_command("--zone=#{query_zone} --query-rich-rule='#{rule}'") == "yes"
|
99
|
+
firewalld_command("--permanent --zone=#{query_zone} --query-rich-rule='#{rule}'") == "yes"
|
89
100
|
end
|
90
101
|
|
91
102
|
def to_s
|
@@ -120,19 +131,82 @@ module Inspec::Resources
|
|
120
131
|
"interfaces" => line.split(":")[1].split(" "),
|
121
132
|
"services" => services_bound(zone),
|
122
133
|
"sources" => sources_bound(zone),
|
134
|
+
"target" => target_bound(zone),
|
135
|
+
"icmp_block_inversion" => icmp_block_inversion_bound?(zone),
|
136
|
+
"ports" => ports_bound(zone),
|
137
|
+
"protocols" => protocols_bound(zone),
|
138
|
+
"masquerade" => masquerade_bound?(zone),
|
139
|
+
"forward_ports" => forward_ports_bound(zone),
|
140
|
+
"source_ports" => source_ports_bound(zone),
|
141
|
+
"icmp_blocks" => icmp_blocks_bound(zone),
|
142
|
+
"rich_rules" => rich_rules_bound(zone),
|
123
143
|
}
|
124
144
|
end
|
125
145
|
|
146
|
+
def target_bound(query_zone)
|
147
|
+
# result: a target bound for the zone
|
148
|
+
# example: 'DROP'
|
149
|
+
firewalld_command("--permanent --zone=#{query_zone} --get-target").strip
|
150
|
+
end
|
151
|
+
|
152
|
+
def icmp_block_inversion_bound?(query_zone)
|
153
|
+
# result: true/false whether inversion of icmp blocks has been enabled for a zone
|
154
|
+
# example: true
|
155
|
+
firewalld_command("--permanent --zone=#{query_zone} --query-icmp-block-inversion") == "yes"
|
156
|
+
end
|
157
|
+
|
158
|
+
def ports_bound(query_zone)
|
159
|
+
# result: a list of ports bound for a zone
|
160
|
+
# example: ['80/tcp', '443/tcp']
|
161
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-ports").split(" ")
|
162
|
+
end
|
163
|
+
|
164
|
+
def protocols_bound(query_zone)
|
165
|
+
# result: a list of protocols added for a zone
|
166
|
+
# example: ['icmp', 'ipv4', 'igmp']
|
167
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-protocols").split(" ")
|
168
|
+
end
|
169
|
+
|
170
|
+
def masquerade_bound?(query_zone)
|
171
|
+
# result: true/false whether IPv4 masquerading has been enabled for a zone
|
172
|
+
# example: true
|
173
|
+
firewalld_command("--permanent --zone=#{query_zone} --query-masquerade") == "yes"
|
174
|
+
end
|
175
|
+
|
176
|
+
def forward_ports_bound(query_zone)
|
177
|
+
# result: a list of IPv4 forward ports bound to a zone
|
178
|
+
# example: ['port=80:proto=tcp:toport=88', 'port=12345:proto=tcp:toport=54321:toaddr=192.168.1.3']
|
179
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-forward-ports").split("\n")
|
180
|
+
end
|
181
|
+
|
182
|
+
def source_ports_bound(query_zone)
|
183
|
+
# result: a list of source ports bound to a zone
|
184
|
+
# example: ['80/tcp', '8080/tcp']
|
185
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-source-ports").split(" ")
|
186
|
+
end
|
187
|
+
|
188
|
+
def icmp_blocks_bound(query_zone)
|
189
|
+
# result: a list of internet ICMP type blocks bound to a zone
|
190
|
+
# example: ['echo-request', 'echo-reply']
|
191
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-icmp-blocks").split(" ")
|
192
|
+
end
|
193
|
+
|
194
|
+
def rich_rules_bound(query_zone)
|
195
|
+
# result: a list of rich language rules bound to a zone
|
196
|
+
# example: ['rule protocol value="ah" accept', 'rule service name="ftp" log limit value="1/m" audit accept']
|
197
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-rich-rules").split("\n")
|
198
|
+
end
|
199
|
+
|
126
200
|
def sources_bound(query_zone)
|
127
201
|
# result: a list containing either an ip address or ip address with a mask, or a ipset or an ipset with the ipset prefix.
|
128
202
|
# example: ['192.168.0.4', '192.168.0.0/16', '2111:DB28:ABC:12::', '2111:db89:ab3d:0112::0/64']
|
129
|
-
firewalld_command("--zone=#{query_zone} --list-sources").split(" ")
|
203
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-sources").split(" ")
|
130
204
|
end
|
131
205
|
|
132
206
|
def services_bound(query_zone)
|
133
207
|
# result: a list of services bound to a zone.
|
134
208
|
# example: ['ssh', 'dhcpv6-client']
|
135
|
-
firewalld_command("--zone=#{query_zone} --list-services").split(" ")
|
209
|
+
firewalld_command("--permanent --zone=#{query_zone} --list-services").split(" ")
|
136
210
|
end
|
137
211
|
|
138
212
|
def firewalld_command(command)
|
@@ -145,4 +219,4 @@ module Inspec::Resources
|
|
145
219
|
result.stdout.strip
|
146
220
|
end
|
147
221
|
end
|
148
|
-
end
|
222
|
+
end
|
@@ -162,7 +162,7 @@ module Inspec::Resources
|
|
162
162
|
|
163
163
|
current_kernel = file_line.split(" ", 2)[1]
|
164
164
|
lines.drop(index + 1).each do |kernel_line|
|
165
|
-
if kernel_line =~
|
165
|
+
if kernel_line =~ /(?:^\s*\w+)/ && !(kernel_line =~ /^title.*/)
|
166
166
|
option_type = kernel_line.split(" ")[0]
|
167
167
|
line_options = kernel_line.split(" ").drop(1)
|
168
168
|
if (menu_entry == conf["default"].to_i && @kernel == "default") || current_kernel == @kernel
|
@@ -121,6 +121,10 @@ module Inspec::Resources
|
|
121
121
|
def max_redirects
|
122
122
|
opts.fetch(:max_redirects, nil)
|
123
123
|
end
|
124
|
+
|
125
|
+
def proxy
|
126
|
+
opts.fetch(:proxy, nil)
|
127
|
+
end
|
124
128
|
end
|
125
129
|
|
126
130
|
class Local < Base
|
@@ -141,12 +145,18 @@ module Inspec::Resources
|
|
141
145
|
def response
|
142
146
|
return @response if @response
|
143
147
|
|
148
|
+
Faraday.ignore_env_proxy = true if proxy == "disable"
|
149
|
+
|
144
150
|
conn = Faraday.new(url: url, headers: request_headers, params: params, ssl: { verify: ssl_verify? }) do |builder|
|
145
151
|
builder.request :url_encoded
|
146
152
|
builder.use FaradayMiddleware::FollowRedirects, limit: max_redirects unless max_redirects.nil?
|
147
153
|
builder.adapter Faraday.default_adapter
|
148
154
|
end
|
149
155
|
|
156
|
+
unless proxy == "disable" || proxy.nil?
|
157
|
+
conn.proxy = proxy
|
158
|
+
end
|
159
|
+
|
150
160
|
# set basic authentication
|
151
161
|
conn.basic_auth username, password unless username.nil? || password.nil?
|
152
162
|
|
@@ -252,6 +262,14 @@ module Inspec::Resources
|
|
252
262
|
cmd << "-X #{http_method}"
|
253
263
|
end
|
254
264
|
|
265
|
+
cmd << "--noproxy '*'" if proxy == "disable"
|
266
|
+
unless proxy == "disable" || proxy.nil?
|
267
|
+
if proxy.is_a?(Hash)
|
268
|
+
cmd << "--proxy #{proxy[:uri]} --proxy-user #{proxy[:user]}:#{proxy[:password]}"
|
269
|
+
else
|
270
|
+
cmd << "--proxy #{proxy}"
|
271
|
+
end
|
272
|
+
end
|
255
273
|
cmd << "--connect-timeout #{open_timeout}"
|
256
274
|
cmd << "--max-time #{open_timeout + read_timeout}"
|
257
275
|
cmd << "--user \'#{username}:#{password}\'" unless username.nil? || password.nil?
|
@@ -292,6 +310,17 @@ module Inspec::Resources
|
|
292
310
|
else
|
293
311
|
cmd << "'#{url}?#{params.map { |e| e.join("=") }.join("&")}'"
|
294
312
|
end
|
313
|
+
|
314
|
+
proxy_script = ""
|
315
|
+
unless proxy == "disable" || proxy.nil?
|
316
|
+
cmd << "-Proxy #{proxy[:uri]}"
|
317
|
+
cmd << "-ProxyCredential $proxyCreds"
|
318
|
+
proxy_script = <<-EOH
|
319
|
+
$secPasswd = ConvertTo-SecureString "#{proxy[:password]}" -AsPlainText -Force
|
320
|
+
$proxyCreds = New-Object System.Management.Automation.PSCredential -ArgumentList "#{proxy[:user]}",$secPasswd
|
321
|
+
EOH
|
322
|
+
end
|
323
|
+
|
295
324
|
command = cmd.join(" ")
|
296
325
|
body = "\'#{request_body}\'"
|
297
326
|
script = <<-EOH
|
@@ -302,10 +331,10 @@ module Inspec::Resources
|
|
302
331
|
foreach ($property in $Body.PSObject.Properties) {
|
303
332
|
$HashTable[$property.Name] = $property.Value
|
304
333
|
}
|
305
|
-
$response = #{command} -Body $HashTable
|
334
|
+
$response = #{command} -Body $HashTable -UseBasicParsing
|
306
335
|
$response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error
|
307
336
|
EOH
|
308
|
-
script.strip
|
337
|
+
proxy_script.strip + "\n" + script.strip
|
309
338
|
end
|
310
339
|
end
|
311
340
|
end
|
@@ -46,12 +46,12 @@ module Inspec::Resources
|
|
46
46
|
|
47
47
|
# check if following specific error is there. Sourcing the db2profile to resolve the error.
|
48
48
|
if cmd.exit_status != 0 && out =~ /SQL10007N Message "-1390" could not be retrieved. Reason code: "3"/
|
49
|
-
cmd = inspec.command(". ~/sqllib/db2profile\; #{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} connect to #{@db_name}\; #{@db2_executable_file_path} #{q}\;")
|
49
|
+
cmd = inspec.command(". ~/sqllib/db2profile\; #{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} connect to #{@db_name}\; #{@db2_executable_file_path} \"#{q}\"\;")
|
50
50
|
out = cmd.stdout + "\n" + cmd.stderr
|
51
51
|
end
|
52
52
|
elsif inspec.os.platform?("windows")
|
53
53
|
# set-item command set the powershell to run the db2 commands.
|
54
|
-
cmd = inspec.command("set-item -path env:DB2CLP -value \"**$$**\"\; db2 connect to #{@db_name}\; db2 #{q}\;")
|
54
|
+
cmd = inspec.command("set-item -path env:DB2CLP -value \"**$$**\"\; db2 connect to #{@db_name}\; db2 \"#{q}\"\;")
|
55
55
|
out = cmd.stdout + "\n" + cmd.stderr
|
56
56
|
end
|
57
57
|
|