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