inspec-core 5.17.4 → 5.18.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/etc/deprecations.json +4 -0
- data/inspec-core.gemspec +1 -1
- data/lib/inspec/base_cli.rb +5 -0
- data/lib/inspec/cli.rb +62 -9
- data/lib/inspec/dependencies/dependency_set.rb +6 -2
- data/lib/inspec/dsl.rb +18 -5
- data/lib/inspec/errors.rb +2 -0
- data/lib/inspec/exceptions.rb +2 -0
- data/lib/inspec/fetcher/url.rb +1 -1
- data/lib/inspec/file_provider.rb +36 -0
- data/lib/inspec/iaf_file.rb +127 -0
- data/lib/inspec/profile.rb +17 -7
- data/lib/inspec/resources/aide_conf.rb +4 -0
- data/lib/inspec/resources/apache.rb +4 -0
- data/lib/inspec/resources/apache_conf.rb +4 -0
- data/lib/inspec/resources/apt.rb +6 -1
- data/lib/inspec/resources/audit_policy.rb +5 -0
- data/lib/inspec/resources/auditd_conf.rb +4 -0
- data/lib/inspec/resources/bash.rb +4 -0
- data/lib/inspec/resources/bond.rb +4 -0
- data/lib/inspec/resources/bridge.rb +4 -0
- data/lib/inspec/resources/cassandradb_conf.rb +5 -0
- data/lib/inspec/resources/cassandradb_session.rb +8 -3
- data/lib/inspec/resources/chocolatey_package.rb +4 -0
- data/lib/inspec/resources/chrony_conf.rb +4 -0
- data/lib/inspec/resources/command.rb +5 -0
- data/lib/inspec/resources/cpan.rb +4 -0
- data/lib/inspec/resources/cran.rb +4 -0
- data/lib/inspec/resources/cron.rb +5 -0
- data/lib/inspec/resources/csv.rb +6 -1
- data/lib/inspec/resources/dh_params.rb +4 -0
- data/lib/inspec/resources/docker_container.rb +4 -0
- data/lib/inspec/resources/docker_image.rb +4 -0
- data/lib/inspec/resources/docker_plugin.rb +4 -0
- data/lib/inspec/resources/docker_service.rb +4 -0
- data/lib/inspec/resources/etc_group.rb +4 -0
- data/lib/inspec/resources/etc_hosts_allow_deny.rb +5 -0
- data/lib/inspec/resources/file.rb +6 -1
- data/lib/inspec/resources/filesystem.rb +4 -0
- data/lib/inspec/resources/gem.rb +4 -0
- data/lib/inspec/resources/groups.rb +4 -0
- data/lib/inspec/resources/grub_conf.rb +4 -0
- data/lib/inspec/resources/host.rb +4 -0
- data/lib/inspec/resources/http.rb +4 -0
- data/lib/inspec/resources/ibmdb2_conf.rb +8 -0
- data/lib/inspec/resources/ibmdb2_session.rb +12 -3
- data/lib/inspec/resources/iis_app.rb +4 -0
- data/lib/inspec/resources/iis_app_pool.rb +4 -0
- data/lib/inspec/resources/iis_site.rb +4 -0
- data/lib/inspec/resources/inetd_conf.rb +4 -0
- data/lib/inspec/resources/interface.rb +4 -0
- data/lib/inspec/resources/ip6tables.rb +4 -0
- data/lib/inspec/resources/ipfilter.rb +4 -0
- data/lib/inspec/resources/ipnat.rb +4 -0
- data/lib/inspec/resources/iptables.rb +4 -0
- data/lib/inspec/resources/json.rb +4 -0
- data/lib/inspec/resources/kernel_module.rb +4 -0
- data/lib/inspec/resources/kernel_parameter.rb +4 -0
- data/lib/inspec/resources/key_rsa.rb +4 -0
- data/lib/inspec/resources/ksh.rb +4 -0
- data/lib/inspec/resources/limits_conf.rb +4 -0
- data/lib/inspec/resources/login_defs.rb +4 -0
- data/lib/inspec/resources/mongodb.rb +4 -0
- data/lib/inspec/resources/mongodb_conf.rb +5 -0
- data/lib/inspec/resources/mongodb_session.rb +6 -1
- data/lib/inspec/resources/mount.rb +4 -0
- data/lib/inspec/resources/mssql_session.rb +4 -0
- data/lib/inspec/resources/mssql_sys_conf.rb +7 -0
- data/lib/inspec/resources/mysql_conf.rb +4 -0
- data/lib/inspec/resources/mysql_session.rb +8 -1
- data/lib/inspec/resources/nginx.rb +6 -1
- data/lib/inspec/resources/nginx_conf.rb +4 -0
- data/lib/inspec/resources/noop.rb +4 -0
- data/lib/inspec/resources/npm.rb +4 -0
- data/lib/inspec/resources/ntp_conf.rb +4 -0
- data/lib/inspec/resources/oneget.rb +4 -0
- data/lib/inspec/resources/opa_api.rb +10 -0
- data/lib/inspec/resources/opa_cli.rb +14 -0
- data/lib/inspec/resources/oracledb_conf.rb +5 -0
- data/lib/inspec/resources/oracledb_listener_conf.rb +4 -0
- data/lib/inspec/resources/oracledb_session.rb +10 -0
- data/lib/inspec/resources/os.rb +4 -0
- data/lib/inspec/resources/os_env.rb +4 -0
- data/lib/inspec/resources/package.rb +4 -0
- data/lib/inspec/resources/parse_config.rb +10 -1
- data/lib/inspec/resources/pip.rb +4 -0
- data/lib/inspec/resources/platform.rb +4 -0
- data/lib/inspec/resources/postfix_conf.rb +4 -0
- data/lib/inspec/resources/postgres_conf.rb +4 -0
- data/lib/inspec/resources/postgres_session.rb +8 -4
- data/lib/inspec/resources/powershell.rb +4 -0
- data/lib/inspec/resources/processes.rb +6 -4
- data/lib/inspec/resources/rabbitmq_config.rb +4 -0
- data/lib/inspec/resources/registry_key.rb +4 -0
- data/lib/inspec/resources/security_identifier.rb +4 -0
- data/lib/inspec/resources/security_policy.rb +4 -0
- data/lib/inspec/resources/service.rb +4 -0
- data/lib/inspec/resources/ssh_config.rb +4 -0
- data/lib/inspec/resources/sybase_conf.rb +4 -0
- data/lib/inspec/resources/sybase_session.rb +4 -0
- data/lib/inspec/resources/sys_info.rb +4 -0
- data/lib/inspec/resources/timezone.rb +4 -0
- data/lib/inspec/resources/users.rb +4 -0
- data/lib/inspec/resources/vbscript.rb +5 -0
- data/lib/inspec/resources/virtualization.rb +4 -0
- data/lib/inspec/resources/windows_feature.rb +5 -1
- data/lib/inspec/resources/windows_firewall.rb +4 -0
- data/lib/inspec/resources/windows_firewall_rule.rb +4 -0
- data/lib/inspec/resources/windows_hotfix.rb +4 -0
- data/lib/inspec/resources/windows_task.rb +4 -0
- data/lib/inspec/resources/wmi.rb +4 -0
- data/lib/inspec/resources/x509_certificate.rb +59 -0
- data/lib/inspec/resources/yum.rb +4 -0
- data/lib/inspec/resources/zfs_dataset.rb +4 -0
- data/lib/inspec/resources/zfs_pool.rb +4 -0
- data/lib/inspec/rule.rb +1 -1
- data/lib/inspec/secrets/yaml.rb +7 -1
- data/lib/inspec/ui.rb +1 -0
- data/lib/inspec/utils/yaml_profile_summary.rb +34 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +4 -4
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +1 -1
- data/lib/plugins/{inspec-artifact/inspec-artifact.gemspec → inspec-sign/inspec-sign.gemspec} +2 -2
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +161 -0
- data/lib/plugins/{inspec-artifact/lib/inspec-artifact → inspec-sign/lib/inspec-sign}/cli.rb +14 -23
- data/lib/plugins/inspec-sign/lib/inspec-sign.rb +12 -0
- data/lib/source_readers/inspec.rb +8 -2
- metadata +10 -8
- data/lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb +0 -187
- data/lib/plugins/inspec-artifact/lib/inspec-artifact.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba97ee3e25e02fba9b85f797fa1a773d2e8fa7628112be422d187c0e46cfce40
|
4
|
+
data.tar.gz: a82f51e5c6ba3e1db8c4580f92a33d91bcc2e0c2a8339850e1f168c1569b8818
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb78893376f0b92b9cf33741f8fab471f66dd328fa1f28c87b05737da7f73266327eded07ca67f0b91a747625dfcb61011b42c06a25914d01f727b07a962456
|
7
|
+
data.tar.gz: 193aeef4576e2af4466a176b80e107cd45fe0c0c0f6db290d17696cec1eb7dbf6b58b555bf8c0df4b9bb4a9d5aa8d26f542993b5be1d600a296c3ec50e531d09
|
data/Gemfile
CHANGED
data/etc/deprecations.json
CHANGED
@@ -121,6 +121,10 @@
|
|
121
121
|
"cli_option_target_id":{
|
122
122
|
"action": "warn",
|
123
123
|
"prefix": "The --target-id option is deprecated in InSpec 5. Its value will be ignored."
|
124
|
+
},
|
125
|
+
"renamed_to_inspec_export":{
|
126
|
+
"action": "ignore",
|
127
|
+
"prefix": "The `inspec json` command is deprecated in InSpec 5 and replaced with `inspec export` command."
|
124
128
|
}
|
125
129
|
}
|
126
130
|
}
|
data/inspec-core.gemspec
CHANGED
data/lib/inspec/base_cli.rb
CHANGED
@@ -138,6 +138,8 @@ module Inspec
|
|
138
138
|
desc: "Provides path to Docker API endpoint (Docker)"
|
139
139
|
option :ssh_config_file, type: :array,
|
140
140
|
desc: "A list of paths to the ssh config file, e.g ~/.ssh/config or /etc/ssh/ssh_config"
|
141
|
+
option :podman_url, type: :string,
|
142
|
+
desc: "Provides path to Podman API endpoint"
|
141
143
|
end
|
142
144
|
|
143
145
|
def self.profile_options
|
@@ -323,6 +325,9 @@ module Inspec
|
|
323
325
|
|
324
326
|
def pretty_handle_exception(exception)
|
325
327
|
case exception
|
328
|
+
when Inspec::InvalidProfileSignature
|
329
|
+
$stderr.puts exception.message
|
330
|
+
Inspec::UI.new.exit(:bad_signature)
|
326
331
|
when Inspec::Error
|
327
332
|
$stderr.puts exception.message
|
328
333
|
exit(1)
|
data/lib/inspec/cli.rb
CHANGED
@@ -5,6 +5,7 @@ require "inspec/dist"
|
|
5
5
|
require "inspec/backend"
|
6
6
|
require "inspec/dependencies/cache"
|
7
7
|
require "inspec/utils/json_profile_summary"
|
8
|
+
require "inspec/utils/yaml_profile_summary"
|
8
9
|
|
9
10
|
module Inspec # TODO: move this somewhere "better"?
|
10
11
|
autoload :BaseCLI, "inspec/base_cli"
|
@@ -69,25 +70,77 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
69
70
|
desc: "A list of tags to filter controls and include only those. Ignore all other tests."
|
70
71
|
profile_options
|
71
72
|
def json(target)
|
72
|
-
|
73
|
+
# This deprecation warning is ignored currently.
|
74
|
+
Inspec.deprecate(:renamed_to_inspec_export)
|
75
|
+
export(target, true)
|
76
|
+
end
|
73
77
|
|
78
|
+
desc "export PATH", "read the profile in PATH and generate a summary in the given format."
|
79
|
+
option :what, type: :string,
|
80
|
+
desc: "What to export: profile (default), readme, metadata."
|
81
|
+
option :format, type: :string,
|
82
|
+
desc: "The output format to use: json, raw, yaml. If valid format is not provided then it will use the default for the given 'what'."
|
83
|
+
option :output, aliases: :o, type: :string,
|
84
|
+
desc: "Save the created output to a path"
|
85
|
+
option :controls, type: :array,
|
86
|
+
desc: "For --what=profile, a list of controls to include. Ignore all other tests."
|
87
|
+
option :tags, type: :array,
|
88
|
+
desc: "For --what=profile, a list of tags to filter controls and include only those. Ignore all other tests."
|
89
|
+
profile_options
|
90
|
+
def export(target, as_json = false)
|
74
91
|
o = config
|
75
92
|
diagnose(o)
|
76
93
|
o["log_location"] = $stderr
|
77
94
|
configure_logger(o)
|
78
95
|
|
96
|
+
# using dup to resolve "can't modify frozen String" error.
|
97
|
+
what = o[:what].dup || "profile"
|
98
|
+
what.downcase!
|
99
|
+
raise Inspec::Error.new("Unrecognized option '#{what}' for --what - expected one of profile, readme, or metadata.") unless %w{profile readme metadata}.include?(what)
|
100
|
+
|
101
|
+
default_format_for_what = {
|
102
|
+
"profile" => "yaml",
|
103
|
+
"metadata" => "raw",
|
104
|
+
"readme" => "raw",
|
105
|
+
}
|
106
|
+
valid_formats_for_what = {
|
107
|
+
"profile" => %w{yaml json},
|
108
|
+
"metadata" => %w{yaml raw}, # not going to argue
|
109
|
+
"readme" => ["raw"],
|
110
|
+
}
|
111
|
+
format = o[:format] || default_format_for_what[what]
|
112
|
+
# default is json if we were called as old json command
|
113
|
+
format = "json" if as_json
|
114
|
+
raise Inspec::Error.new("Invalid option '#{format}' for --format and --what combination") unless format && valid_formats_for_what[what].include?(format)
|
115
|
+
|
79
116
|
o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
|
80
117
|
o[:check_mode] = true
|
81
118
|
o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
|
82
|
-
|
83
119
|
profile = Inspec::Profile.for_target(target, o)
|
84
120
|
dst = o[:output].to_s
|
85
121
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
122
|
+
case what
|
123
|
+
when "profile"
|
124
|
+
if format == "json"
|
125
|
+
require "json" unless defined?(JSON)
|
126
|
+
# Write JSON
|
127
|
+
Inspec::Utils::JsonProfileSummary.produce_json(
|
128
|
+
info: profile.info,
|
129
|
+
write_path: dst
|
130
|
+
)
|
131
|
+
elsif format == "yaml"
|
132
|
+
Inspec::Utils::YamlProfileSummary.produce_yaml(
|
133
|
+
info: profile.info,
|
134
|
+
write_path: dst
|
135
|
+
)
|
136
|
+
end
|
137
|
+
when "readme"
|
138
|
+
out = dst.empty? ? $stdout : File.open(dst, "w")
|
139
|
+
out.write(profile.readme)
|
140
|
+
when "metadata"
|
141
|
+
out = dst.empty? ? $stdout : File.open(dst, "w")
|
142
|
+
out.write(profile.metadata_src)
|
143
|
+
end
|
91
144
|
rescue StandardError => e
|
92
145
|
pretty_handle_exception(e)
|
93
146
|
end
|
@@ -189,12 +242,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
189
242
|
desc: "Fallback to using local archives if fetching fails."
|
190
243
|
option :ignore_errors, type: :boolean, default: false,
|
191
244
|
desc: "Ignore profile warnings."
|
192
|
-
def archive(path)
|
245
|
+
def archive(path, log_level = nil)
|
193
246
|
o = config
|
194
247
|
diagnose(o)
|
195
248
|
|
196
249
|
o[:logger] = Logger.new($stdout)
|
197
|
-
o[:logger].level = get_log_level(o[:log_level])
|
250
|
+
o[:logger].level = get_log_level(log_level || o[:log_level])
|
198
251
|
o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
|
199
252
|
|
200
253
|
# Force vendoring with overwrite when archiving
|
@@ -25,7 +25,9 @@ module Inspec
|
|
25
25
|
def self.from_array(dependencies, cwd, cache, backend)
|
26
26
|
dep_list = {}
|
27
27
|
dependencies.each do |d|
|
28
|
-
|
28
|
+
# if depedent profile does not have a source version then only name is used in dependency hash
|
29
|
+
key_name = (d.source_version ? "#{d.name}-#{d.source_version}" : "#{d.name}") rescue "#{d.name}"
|
30
|
+
dep_list[key_name] = d
|
29
31
|
end
|
30
32
|
new(cwd, cache, dep_list, backend)
|
31
33
|
end
|
@@ -39,7 +41,9 @@ module Inspec
|
|
39
41
|
def self.flatten_dep_tree(dep_tree)
|
40
42
|
dep_list = {}
|
41
43
|
dep_tree.each do |d|
|
42
|
-
|
44
|
+
# if depedent profile does not have a source version then only name is used in dependency hash
|
45
|
+
key_name = (d.source_version ? "#{d.name}-#{d.source_version}" : "#{d.name}") rescue d.name
|
46
|
+
dep_list[key_name] = d
|
43
47
|
dep_list.merge!(flatten_dep_tree(d.dependencies))
|
44
48
|
end
|
45
49
|
dep_list
|
data/lib/inspec/dsl.rb
CHANGED
@@ -6,13 +6,13 @@ require "inspec/utils/deprecated_cloud_resources_list"
|
|
6
6
|
module Inspec::DSL
|
7
7
|
attr_accessor :backend
|
8
8
|
|
9
|
-
def require_controls(id, &block)
|
10
|
-
opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf, dependencies: @dependencies }
|
9
|
+
def require_controls(id, version = nil, &block)
|
10
|
+
opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf, dependencies: @dependencies, profile_version: version }
|
11
11
|
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
12
12
|
end
|
13
13
|
|
14
|
-
def include_controls(id, &block)
|
15
|
-
opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf, dependencies: @dependencies }
|
14
|
+
def include_controls(id, version = nil, &block)
|
15
|
+
opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf, dependencies: @dependencies, profile_version: version }
|
16
16
|
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
17
17
|
end
|
18
18
|
|
@@ -85,7 +85,20 @@ module Inspec::DSL
|
|
85
85
|
def self.load_spec_files_for_profile(bind_context, opts, &block)
|
86
86
|
dependencies = opts[:dependencies]
|
87
87
|
profile_id = opts[:profile_id]
|
88
|
-
|
88
|
+
profile_version = opts[:profile_version]
|
89
|
+
|
90
|
+
new_profile_id = nil
|
91
|
+
if profile_version
|
92
|
+
new_profile_id = "#{profile_id}-#{profile_version}"
|
93
|
+
else
|
94
|
+
dependencies.list.keys.each do |key|
|
95
|
+
# If dep profile does not contain a source version, key does not contain a version as well. In that case new_profile_id will be always nil and instead profile_id would be used to fetch profile from dependency list.
|
96
|
+
profile_id_key = key.split("-")
|
97
|
+
profile_id_key.pop
|
98
|
+
new_profile_id = key if profile_id_key.join("-") == profile_id
|
99
|
+
end
|
100
|
+
end
|
101
|
+
dep_entry = new_profile_id ? dependencies.list[new_profile_id] : dependencies.list[profile_id]
|
89
102
|
|
90
103
|
if dep_entry.nil?
|
91
104
|
raise <<~EOF
|
data/lib/inspec/errors.rb
CHANGED
data/lib/inspec/exceptions.rb
CHANGED
@@ -8,5 +8,7 @@ module Inspec
|
|
8
8
|
class ResourceFailed < StandardError; end
|
9
9
|
class ResourceSkipped < StandardError; end
|
10
10
|
class SecretsBackendNotFound < ArgumentError; end
|
11
|
+
class ProfileValidationKeyNotFound < ArgumentError; end
|
12
|
+
class ProfileSigningKeyNotFound < ArgumentError; end
|
11
13
|
end
|
12
14
|
end
|
data/lib/inspec/fetcher/url.rb
CHANGED
@@ -262,7 +262,7 @@ module Inspec::Fetcher
|
|
262
262
|
|
263
263
|
open(target, opts)
|
264
264
|
|
265
|
-
rescue SocketError, Errno::ECONNREFUSED, OpenURI::HTTPError => e
|
265
|
+
rescue SocketError, Net::OpenTimeout, Errno::ECONNREFUSED, OpenURI::HTTPError => e
|
266
266
|
raise Inspec::FetcherFailure, "Profile URL dependency #{target} could not be fetched: #{e.message}"
|
267
267
|
end
|
268
268
|
|
data/lib/inspec/file_provider.rb
CHANGED
@@ -2,6 +2,7 @@ require "rubygems/package" unless defined?(Gem::Package)
|
|
2
2
|
require "pathname" unless defined?(Pathname)
|
3
3
|
require "zlib" unless defined?(Zlib)
|
4
4
|
require "zip" unless defined?(Zip)
|
5
|
+
require "inspec/iaf_file"
|
5
6
|
|
6
7
|
module Inspec
|
7
8
|
class FileProvider
|
@@ -14,6 +15,13 @@ module Inspec
|
|
14
15
|
TarProvider.new(path)
|
15
16
|
elsif File.exist?(path) && path.end_with?(".zip")
|
16
17
|
ZipProvider.new(path)
|
18
|
+
elsif File.exist?(path) && path.end_with?(".iaf")
|
19
|
+
iaf_file = IafFile.new(path)
|
20
|
+
if iaf_file.valid?
|
21
|
+
IafProvider.new(path)
|
22
|
+
else
|
23
|
+
raise Inspec::InvalidProfileSignature, "Profile signature is invalid."
|
24
|
+
end
|
17
25
|
elsif File.exist?(path)
|
18
26
|
DirProvider.new(path)
|
19
27
|
else
|
@@ -216,6 +224,34 @@ module Inspec
|
|
216
224
|
end
|
217
225
|
end # class TarProvider
|
218
226
|
|
227
|
+
class IafProvider < TarProvider
|
228
|
+
attr_reader :files
|
229
|
+
|
230
|
+
def initialize(path)
|
231
|
+
f = File.open(path, "rb")
|
232
|
+
version = f.readline.strip!
|
233
|
+
if version == "INSPEC-PROFILE-1"
|
234
|
+
while f.readline != "\n" do end
|
235
|
+
content = f.read
|
236
|
+
f.close
|
237
|
+
elsif version == "INSPEC-PROFILE-2"
|
238
|
+
f.readline.strip!
|
239
|
+
content = f.read
|
240
|
+
f.close
|
241
|
+
content = content.slice(490, content.length).lstrip
|
242
|
+
else
|
243
|
+
raise Inspec::InvalidProfileSignature, "Unrecognized IAF version."
|
244
|
+
end
|
245
|
+
|
246
|
+
tmpfile = nil
|
247
|
+
Dir.mktmpdir do |workdir|
|
248
|
+
tmpfile = Pathname.new(workdir).join("temp_profile.tar.gz")
|
249
|
+
File.open(tmpfile, "wb") { |fl| fl.write(content) }
|
250
|
+
super(tmpfile)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end # class IafProvider
|
254
|
+
|
219
255
|
class RelativeFileProvider
|
220
256
|
BLACKLIST_FILES = [
|
221
257
|
"/pax_global_header",
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "base64" unless defined?(Base64)
|
2
|
+
require "openssl" unless defined?(OpenSSL)
|
3
|
+
require "set" unless defined?(Set)
|
4
|
+
require "uri" unless defined?(URI)
|
5
|
+
|
6
|
+
module Inspec
|
7
|
+
class IafFile
|
8
|
+
KEY_ALG = OpenSSL::PKey::RSA
|
9
|
+
INSPEC_PROFILE_VERSION_1 = "INSPEC-PROFILE-1".freeze
|
10
|
+
INSPEC_PROFILE_VERSION_2 = "INSPEC-PROFILE-2".freeze
|
11
|
+
|
12
|
+
ARTIFACT_DIGEST = OpenSSL::Digest::SHA512
|
13
|
+
ARTIFACT_DIGEST_NAME = "SHA512".freeze
|
14
|
+
|
15
|
+
VALID_PROFILE_VERSIONS = Set.new [INSPEC_PROFILE_VERSION_1, INSPEC_PROFILE_VERSION_2]
|
16
|
+
VALID_PROFILE_DIGESTS = Set.new [ARTIFACT_DIGEST_NAME]
|
17
|
+
|
18
|
+
def self.find_validation_key(keyname)
|
19
|
+
[
|
20
|
+
".",
|
21
|
+
File.join(Inspec.config_dir, "keys"),
|
22
|
+
File.join(Inspec.src_root, "etc", "keys"),
|
23
|
+
].each do |path|
|
24
|
+
filename = File.join(path, "#{keyname}.pem.pub")
|
25
|
+
return filename if File.exist?(filename)
|
26
|
+
rescue ArgumentError => e
|
27
|
+
puts e
|
28
|
+
raise Inspec::Exceptions::ProfileValidationKeyNotFound.new("Validation key #{keyname} not found")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Retry if we can fetch it from github
|
32
|
+
return find_validation_key(keyname) if fetch_validation_key_from_github(keyname)
|
33
|
+
|
34
|
+
raise Inspec::Exceptions::ProfileValidationKeyNotFound.new("Validation key #{keyname} not found")
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.find_signing_key(keyname)
|
38
|
+
[".", File.join(Inspec.config_dir, "keys")].each do |path|
|
39
|
+
filename = File.join(path, "#{keyname}.pem.key")
|
40
|
+
return filename if File.exist?(filename)
|
41
|
+
end
|
42
|
+
raise Inspec::Exceptions::ProfileSigningKeyNotFound.new("Signing key #{keyname} not found")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.fetch_validation_key_from_github(keyname)
|
46
|
+
URI.open("https://raw.githubusercontent.com/inspec/inspec/main/etc/keys/#{keyname}.pem.pub") do |r|
|
47
|
+
puts "Fetching validation key '#{keyname}' from github"
|
48
|
+
dir = File.join(Inspec.config_dir, "keys")
|
49
|
+
FileUtils.mkdir_p dir
|
50
|
+
key_file = File.join(dir, "#{keyname}.pem.pub")
|
51
|
+
File.open(key_file, "w") do |f|
|
52
|
+
r.each_line do |line|
|
53
|
+
f.puts line
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
true
|
58
|
+
rescue OpenURI::HTTPError
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :key_name, :version
|
63
|
+
|
64
|
+
def initialize(path)
|
65
|
+
@path = path
|
66
|
+
@key_name = nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid?
|
70
|
+
header = []
|
71
|
+
valid = true
|
72
|
+
f = File.open(@path, "rb")
|
73
|
+
@version = f.readline.strip!
|
74
|
+
if version == INSPEC_PROFILE_VERSION_1
|
75
|
+
header << version
|
76
|
+
header << f.readline.strip!
|
77
|
+
header << f.readline.strip!
|
78
|
+
|
79
|
+
file_sig = ""
|
80
|
+
# the signature is multi-line
|
81
|
+
while (line = f.readline) != "\n"
|
82
|
+
file_sig += line
|
83
|
+
end
|
84
|
+
header << file_sig.strip!
|
85
|
+
f.close
|
86
|
+
|
87
|
+
f = File.open(@path, "rb")
|
88
|
+
while f.readline != "\n" do end
|
89
|
+
content = f.read
|
90
|
+
f.close
|
91
|
+
elsif version == INSPEC_PROFILE_VERSION_2
|
92
|
+
header << version
|
93
|
+
header << f.readline.strip!
|
94
|
+
content = f.read
|
95
|
+
f.close
|
96
|
+
|
97
|
+
header_content = content.unpack("h*").pack("H*")
|
98
|
+
header << header_content.slice(0, 100).rstrip
|
99
|
+
header << header_content.slice(100, 20).rstrip
|
100
|
+
header << header_content.slice(120, 370).rstrip + "\n" # \n at the end is require in this field
|
101
|
+
content = content.slice(490, content.length).lstrip
|
102
|
+
else
|
103
|
+
valid = false
|
104
|
+
end
|
105
|
+
|
106
|
+
@key_name = header[2]
|
107
|
+
validation_key_path = Inspec::IafFile.find_validation_key(@key_name)
|
108
|
+
|
109
|
+
unless valid_header?(header)
|
110
|
+
valid = false
|
111
|
+
end
|
112
|
+
|
113
|
+
verification_key = KEY_ALG.new File.read validation_key_path
|
114
|
+
signature = Base64.decode64(header[4])
|
115
|
+
digest = ARTIFACT_DIGEST.new
|
116
|
+
unless verification_key.verify digest, signature, content
|
117
|
+
valid = false
|
118
|
+
end
|
119
|
+
|
120
|
+
valid
|
121
|
+
end
|
122
|
+
|
123
|
+
def valid_header?(header)
|
124
|
+
VALID_PROFILE_VERSIONS.member?(header[0]) && VALID_PROFILE_DIGESTS.member?(header[3])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/inspec/profile.rb
CHANGED
@@ -350,22 +350,24 @@ module Inspec
|
|
350
350
|
def load_libraries
|
351
351
|
return @runner_context if @libraries_loaded
|
352
352
|
|
353
|
-
locked_dependencies.dep_list.each_with_index do |(_name, dep),
|
353
|
+
locked_dependencies.dep_list.each_with_index do |(_name, dep), index|
|
354
354
|
d = dep.profile
|
355
355
|
# this will force a dependent profile load so we are only going to add
|
356
356
|
# this metadata if the parent profile is supported.
|
357
357
|
if @supports_platform && !d.supports_platform?
|
358
358
|
# since ruby 1.9 hashes are ordered so we can just use index values here
|
359
359
|
# TODO: NO! this is a violation of encapsulation to an extreme
|
360
|
-
metadata.dependencies[
|
361
|
-
|
362
|
-
|
363
|
-
|
360
|
+
if metadata.dependencies[index]
|
361
|
+
metadata.dependencies[index][:status] = "skipped"
|
362
|
+
msg = "Skipping profile: '#{d.name}' on unsupported platform: '#{d.backend.platform.name}/#{d.backend.platform.release}'."
|
363
|
+
metadata.dependencies[index][:status_message] = msg
|
364
|
+
metadata.dependencies[index][:skip_message] = msg # Repeat as skip_message for backward compatibility
|
365
|
+
end
|
364
366
|
next
|
365
|
-
elsif metadata.dependencies[
|
367
|
+
elsif metadata.dependencies[index]
|
366
368
|
# Currently wrapper profiles will load all dependencies, and then we
|
367
369
|
# load them again when we dive down. This needs to be re-done.
|
368
|
-
metadata.dependencies[
|
370
|
+
metadata.dependencies[index][:status] = "loaded"
|
369
371
|
end
|
370
372
|
|
371
373
|
# rubocop:disable Layout/ExtraSpacing
|
@@ -746,6 +748,14 @@ module Inspec
|
|
746
748
|
@source_reader.target.files
|
747
749
|
end
|
748
750
|
|
751
|
+
def readme
|
752
|
+
@source_reader.readme&.values&.first
|
753
|
+
end
|
754
|
+
|
755
|
+
def metadata_src
|
756
|
+
@source_reader.metadata_src
|
757
|
+
end
|
758
|
+
|
749
759
|
#
|
750
760
|
# TODO(ssd): Relative path handling really needs to be carefully
|
751
761
|
# thought through, especially with respect to relative paths in
|
data/lib/inspec/resources/apt.rb
CHANGED
@@ -39,10 +39,11 @@ module Inspec::Resources
|
|
39
39
|
EXAMPLE
|
40
40
|
|
41
41
|
def initialize(ppa_name)
|
42
|
+
@ppa_name = ppa_name
|
42
43
|
@deb_url = nil
|
43
44
|
# check if the os is ubuntu or debian
|
44
45
|
if inspec.os.debian?
|
45
|
-
@deb_url = determine_ppa_url(ppa_name)
|
46
|
+
@deb_url = determine_ppa_url(@ppa_name)
|
46
47
|
else
|
47
48
|
# this resource is only supported on ubuntu and debian
|
48
49
|
skip_resource "The `apt` resource is not supported on your OS yet."
|
@@ -61,6 +62,10 @@ module Inspec::Resources
|
|
61
62
|
actives.size == 1 && actives[0] = true
|
62
63
|
end
|
63
64
|
|
65
|
+
def resource_id
|
66
|
+
@deb_url || @ppa_name || "apt repository"
|
67
|
+
end
|
68
|
+
|
64
69
|
def to_s
|
65
70
|
"Apt Repository #{@deb_url}"
|
66
71
|
end
|
@@ -31,6 +31,11 @@ module Inspec::Resources
|
|
31
31
|
super(@conf_path)
|
32
32
|
end
|
33
33
|
|
34
|
+
# if system unables to determine the cassandra conf path the @conf_path can be nil so in that case sending "" string as resource_id
|
35
|
+
def resource_id
|
36
|
+
@conf_path || "cassandradb_conf"
|
37
|
+
end
|
38
|
+
|
34
39
|
private
|
35
40
|
|
36
41
|
def parse(content)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Inspec::Resources
|
2
2
|
class Lines
|
3
|
-
attr_reader :output
|
3
|
+
attr_reader :output, :exit_status
|
4
4
|
|
5
|
-
def initialize(raw, desc)
|
5
|
+
def initialize(raw, desc, exit_status)
|
6
6
|
@output = raw
|
7
7
|
@desc = desc
|
8
|
+
@exit_status = exit_status
|
8
9
|
end
|
9
10
|
|
10
11
|
def to_s
|
@@ -40,10 +41,14 @@ module Inspec::Resources
|
|
40
41
|
if cmd.exit_status != 0 || out =~ /Unable to connect to any servers/ || out.downcase =~ /^error:.*/
|
41
42
|
raise Inspec::Exceptions::ResourceFailed, "Cassandra query with errors: #{out}"
|
42
43
|
else
|
43
|
-
Lines.new(cmd.stdout.strip, "Cassandra query: #{q}")
|
44
|
+
Lines.new(cmd.stdout.strip, "Cassandra query: #{q}", cmd.exit_status)
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
def resource_id
|
49
|
+
"cassandradb_session:User:#{@user}:Host:#{host}"
|
50
|
+
end
|
51
|
+
|
47
52
|
def to_s
|
48
53
|
"Cassandra DB Session"
|
49
54
|
end
|