inspec-core 4.50.3 → 4.56.19

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -11
  3. data/inspec-core.gemspec +2 -2
  4. data/lib/bundles/inspec-supermarket/README.md +21 -2
  5. data/lib/bundles/inspec-supermarket/cli.rb +20 -3
  6. data/lib/bundles/inspec-supermarket/target.rb +3 -2
  7. data/lib/inspec/base_cli.rb +8 -0
  8. data/lib/inspec/config.rb +5 -1
  9. data/lib/inspec/dependencies/requirement.rb +2 -1
  10. data/lib/inspec/formatters/base.rb +8 -6
  11. data/lib/inspec/library_eval_context.rb +2 -0
  12. data/lib/inspec/plugin/v1/registry.rb +1 -1
  13. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +10 -0
  14. data/lib/inspec/profile_context.rb +1 -6
  15. data/lib/inspec/reporters/automate.rb +1 -1
  16. data/lib/inspec/reporters/json.rb +1 -1
  17. data/lib/inspec/resources/auditd.rb +5 -4
  18. data/lib/inspec/resources/bash.rb +2 -0
  19. data/lib/inspec/resources/file.rb +38 -0
  20. data/lib/inspec/resources/firewalld.rb +83 -9
  21. data/lib/inspec/resources/grub_conf.rb +1 -1
  22. data/lib/inspec/resources/http.rb +31 -2
  23. data/lib/inspec/resources/ibmdb2_session.rb +2 -2
  24. data/lib/inspec/resources/iptables.rb +18 -2
  25. data/lib/inspec/resources/kernel_parameters.rb +58 -0
  26. data/lib/inspec/resources/mssql_session.rb +11 -3
  27. data/lib/inspec/resources/oracledb_session.rb +10 -4
  28. data/lib/inspec/resources/package.rb +74 -1
  29. data/lib/inspec/resources/packages.rb +21 -0
  30. data/lib/inspec/resources/postgres_session.rb +4 -2
  31. data/lib/inspec/resources/registry_key.rb +30 -0
  32. data/lib/inspec/resources/selinux.rb +6 -1
  33. data/lib/inspec/resources/service.rb +58 -9
  34. data/lib/inspec/resources/ssl.rb +7 -0
  35. data/lib/inspec/resources/timezone.rb +65 -0
  36. data/lib/inspec/resources.rb +2 -0
  37. data/lib/inspec/runner_rspec.rb +30 -0
  38. data/lib/inspec/utils/filter.rb +46 -2
  39. data/lib/inspec/utils/run_data_filters.rb +1 -1
  40. data/lib/inspec/version.rb +1 -1
  41. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +1 -1
  42. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +4 -3
  43. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 506be4d9918c8af46f6b3784e8a18550cee990ad73c7c731bb1afea7197c5370
4
- data.tar.gz: b48fa274325e96ac07185653b2eeb997ed5ea6fa39f570b0400706331a3b4d52
3
+ metadata.gz: 58efdb5e3457dcb1bf97227b98e1f723c672c7eadc995ef3f07b1f2a910c47db
4
+ data.tar.gz: 0f789e778551423ccfdacc52dbcda63c597b3e8d83b00739aa36becc52502213
5
5
  SHA512:
6
- metadata.gz: 4eb19bed92e35c49395e513e263f3afdb3f59abcf873b88f0c7dc07775a64c4e6aea3db57f069b19be73e9aa92de106db95ecb4b60fc3fc4c5b080f4fc97df6c
7
- data.tar.gz: e8eac56320e4c0e36078bdcef95dde1b6ec710d7bfdba1bbd4f8301ee0f5799c5a913f96edc5c31ba78c2dcc3647e671454b30ac430729943a0dca071191aa63
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
- if Gem.ruby_version.to_s.start_with?("2.5")
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.18"
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.5"
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", "< 3.11"
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: `inspec supermarket exec nathenharvey/tmp-compliance-profile`
12
- - via supermarket scheme: `inspec exec supermarket://nathenharvey/tmp-compliance-profile`
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
- # display profiles in format user/profile
20
- supermarket_profiles = Supermarket::API.profiles
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 = Supermarket::API.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, Supermarket::API::SUPERMARKET_URL]
14
+ [target, supermarket_url]
14
15
  elsif target.respond_to?(:key?) && target.key?(:supermarket)
15
- supermarket_server = target[:supermarket_url] || Supermarket::API::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
@@ -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
- valid_types = rspec_built_in_formatters + inspec_reporters_that_are_not_yet_plugins + plugin_reporters
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
- @fetcher ||= Inspec::CachedFetcher.new(opts, @cache)
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
- begin
209
- @backend.platform[field]
210
- rescue Train::Error => e
211
- Inspec::Log.warn(e.message)
212
- nil
213
- end
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
@@ -30,6 +30,8 @@ module Inspec
30
30
 
31
31
  c3 = Class.new do
32
32
  include Inspec::DSL::RequireOverride
33
+ include Inspec::Resources
34
+
33
35
  def initialize(require_loader)
34
36
  @require_loader = require_loader
35
37
  @inspec_binding = nil
@@ -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 == m
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])
@@ -29,7 +29,7 @@ module Inspec::Reporters
29
29
  {
30
30
  name: run_data[:platform][:name],
31
31
  release: run_data[:platform][:release],
32
- target_id: @config["target_id"],
32
+ target_id: run_data[:platform][:target_id] || @config["target_id"],
33
33
  }.reject { |_k, v| v.nil? }
34
34
  end
35
35
 
@@ -28,12 +28,13 @@ module Inspec::Resources
28
28
  EXAMPLE
29
29
 
30
30
  def initialize
31
- unless inspec.command("/sbin/auditctl").exist?
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 `/sbin/auditctl` does not exist"
34
+ "Command `#{@auditctl_cmd_str}` does not exist"
34
35
  end
35
36
 
36
- auditctl_cmd = "/sbin/auditctl -l"
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("/sbin/auditctl -s").stdout.chomp
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/
@@ -5,6 +5,8 @@ module Inspec::Resources
5
5
  class Bash < Cmd
6
6
  name "bash"
7
7
  supports platform: "unix"
8
+ supports platform: "esx"
9
+
8
10
  desc "Run a command or script in BASH."
9
11
  example <<~EXAMPLE
10
12
  describe bash('ls -al /') do
@@ -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 --permanent").split(" ")
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 protocoals open
88
+ # return: String of protocols open
78
89
  # example: ['icmp', 'ipv4', 'igmp']
79
- firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-protocols --permanent").split(" ")
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 =~ /^\s.*/
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