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
@@ -83,6 +83,11 @@ module Inspec::Resources
|
|
83
83
|
@parsed_subject = Hashie::Mash.new(Hash[@cert.subject.to_a.map { |k, v, _| [k, v] }])
|
84
84
|
end
|
85
85
|
|
86
|
+
# This property is equivalent to subject.emailAddress
|
87
|
+
def email
|
88
|
+
subject.emailAddress
|
89
|
+
end
|
90
|
+
|
86
91
|
def issuer_dn
|
87
92
|
return if @cert.nil?
|
88
93
|
|
@@ -104,6 +109,8 @@ module Inspec::Resources
|
|
104
109
|
@cert.public_key.n.num_bytes * 8
|
105
110
|
end
|
106
111
|
|
112
|
+
alias :keylength :key_length
|
113
|
+
|
107
114
|
def validity_in_days
|
108
115
|
(not_after - Time.now.utc) / 86400
|
109
116
|
end
|
@@ -138,6 +145,50 @@ module Inspec::Resources
|
|
138
145
|
@extensions
|
139
146
|
end
|
140
147
|
|
148
|
+
# check purpose of the certificate
|
149
|
+
def has_purpose?(purpose)
|
150
|
+
# If we have the filepath in our options we use the filepath to fetch the purposes.
|
151
|
+
# Else, we create a temporary file and write the content to that file.
|
152
|
+
# Then, use the temporary file to fetch the purposes.
|
153
|
+
# Todo: Check if this can be optimized or improved.
|
154
|
+
|
155
|
+
if @opts[:filepath]
|
156
|
+
cert_purpose = fetch_purpose(@opts[:filepath])
|
157
|
+
else
|
158
|
+
begin
|
159
|
+
f = File.open("temporary_certificate.pem", "w")
|
160
|
+
f.write(@cert.to_pem)
|
161
|
+
f.rewind
|
162
|
+
cert_purpose = fetch_purpose("temporary_certificate.pem")
|
163
|
+
ensure
|
164
|
+
f.close unless f.nil? || f.closed?
|
165
|
+
File.delete("temporary_certificate.pem") if File.exist? "temporary_certificate.pem"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
cert_purpose =~ /purpose/ ? true : false
|
169
|
+
end
|
170
|
+
|
171
|
+
def fetch_purpose(cert_file_or_path)
|
172
|
+
openssl_utility = check_openssl_or_error
|
173
|
+
|
174
|
+
# The below command is used to view the Certificate purposes
|
175
|
+
# The -in argument expects a certificate file or path to certificate file.
|
176
|
+
cert_purpose_cmd = "#{openssl_utility} x509 -noout -purpose -in #{cert_file_or_path}"
|
177
|
+
cert_purpose = inspec.command(cert_purpose_cmd)
|
178
|
+
|
179
|
+
raise Inspec::Exceptions::ResourceFailed, "Executing #{cert_purpose_cmd} failed: #{cert_purpose.stderr}" if cert_purpose.exit_status.to_i != 0
|
180
|
+
|
181
|
+
cert_purpose.stdout
|
182
|
+
end
|
183
|
+
|
184
|
+
def subject_alt_names
|
185
|
+
extensions["subjectAltName"]
|
186
|
+
end
|
187
|
+
|
188
|
+
def resource_id
|
189
|
+
@opts[:filepath] || subject.CN || "x509 Certificate"
|
190
|
+
end
|
191
|
+
|
141
192
|
def to_s
|
142
193
|
cert = @opts[:filepath]
|
143
194
|
cert ||= subject.CN
|
@@ -153,5 +204,13 @@ module Inspec::Resources
|
|
153
204
|
opts
|
154
205
|
end
|
155
206
|
end
|
207
|
+
|
208
|
+
def check_openssl_or_error
|
209
|
+
%w{/usr/sbin/openssl /usr/bin/openssl /sbin/openssl /bin/openssl openssl}.each do |cmd|
|
210
|
+
return cmd if inspec.command(cmd).exist?
|
211
|
+
end
|
212
|
+
|
213
|
+
raise Inspec::Exceptions::ResourceFailed, "Could not find `openssl` on your system."
|
214
|
+
end
|
156
215
|
end
|
157
216
|
end
|
data/lib/inspec/resources/yum.rb
CHANGED
data/lib/inspec/rule.rb
CHANGED
@@ -358,7 +358,7 @@ module Inspec
|
|
358
358
|
# YAML will automagically give us a Date or a Time.
|
359
359
|
# If transcoding YAML between languages (e.g. Go) the date might have also ended up as a String.
|
360
360
|
# A string that does not represent a valid time results in the date 0000-01-01.
|
361
|
-
if [Date, Time].include?(expiry.class) || (expiry.is_a?(String) && Time.
|
361
|
+
if [Date, Time].include?(expiry.class) || (expiry.is_a?(String) && Time.parse(expiry).year != 0)
|
362
362
|
expiry = expiry.to_time if expiry.is_a? Date
|
363
363
|
expiry = Time.parse(expiry) if expiry.is_a? String
|
364
364
|
if expiry < Time.now # If the waiver expired, return - no skip applied
|
data/lib/inspec/secrets/yaml.rb
CHANGED
@@ -16,7 +16,13 @@ module Secrets
|
|
16
16
|
|
17
17
|
# array of yaml file paths
|
18
18
|
def initialize(target)
|
19
|
-
|
19
|
+
# Ruby 3.1 treats YAML load as a dangerous operation by default, requiring us to declare date and time classes as permitted
|
20
|
+
# It's not a valid option in 3.0.x
|
21
|
+
if Gem.ruby_version >= Gem::Version.new("3.1.0")
|
22
|
+
@inputs = ::YAML.load_file(target, permitted_classes: [Date, Time])
|
23
|
+
else
|
24
|
+
@inputs = ::YAML.load_file(target)
|
25
|
+
end
|
20
26
|
|
21
27
|
if @inputs == false || !@inputs.is_a?(Hash)
|
22
28
|
Inspec::Log.warn("#{self.class} unable to parse #{target}: invalid YAML or contents is not a Hash")
|
data/lib/inspec/ui.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Inspec
|
4
|
+
module Utils
|
5
|
+
#
|
6
|
+
# Inspec::Utils::YamlProfileSummary takes in certain information to identify a
|
7
|
+
# profile and then produces a YAML-formatted summary of that profile. It can
|
8
|
+
# return the results to STDOUT or a file.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
module YamlProfileSummary
|
12
|
+
def self.produce_yaml(info:, write_path: "", suppress_output: false)
|
13
|
+
# add in inspec version
|
14
|
+
info[:generator] = {
|
15
|
+
name: "inspec",
|
16
|
+
version: Inspec::VERSION,
|
17
|
+
}
|
18
|
+
if write_path.empty?
|
19
|
+
puts info.to_yaml
|
20
|
+
else
|
21
|
+
unless suppress_output
|
22
|
+
if File.exist? write_path
|
23
|
+
Inspec::Log.info "----> updating #{write_path}"
|
24
|
+
else
|
25
|
+
Inspec::Log.info "----> creating #{write_path}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
full_write_path = File.expand_path(write_path)
|
29
|
+
File.write(full_write_path, info.to_yaml)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/inspec/version.rb
CHANGED
@@ -7,21 +7,21 @@
|
|
7
7
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
8
8
|
<style type="text/css">
|
9
9
|
/* Must inline all CSS files, this is a single-file output that may be airgapped */
|
10
|
-
<%= ERB.new(File.read(css_path),
|
10
|
+
<%= ERB.new(File.read(css_path), eoutvar: "_css").result(binding) %>
|
11
11
|
</style>
|
12
12
|
<script type="text/javascript">
|
13
13
|
// <![CDATA[
|
14
14
|
/* Must inline all JavaScript files, this is a single-file output that may be airgapped */
|
15
|
-
<%= ERB.new(File.read(js_path),
|
15
|
+
<%= ERB.new(File.read(js_path), eoutvar: "_js").result(binding) %>
|
16
16
|
// ]]>
|
17
17
|
</script>
|
18
18
|
</head>
|
19
19
|
<body onload="pageLoaded()">
|
20
|
-
<%= ERB.new(File.read(template_path + "/selector.html.erb"),
|
20
|
+
<%= ERB.new(File.read(template_path + "/selector.html.erb"), eoutvar: "_select").result(binding) %>
|
21
21
|
<div class="inspec-report">
|
22
22
|
<h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
|
23
23
|
<% run_data.profiles.each do |profile| %>
|
24
|
-
<%= ERB.new(File.read(template_path + "/profile.html.erb"),
|
24
|
+
<%= ERB.new(File.read(template_path + "/profile.html.erb"), eoutvar: "_prof").result(binding) %>
|
25
25
|
<% end %>
|
26
26
|
|
27
27
|
<div class="inspec-summary">
|
@@ -74,7 +74,7 @@
|
|
74
74
|
</table>
|
75
75
|
|
76
76
|
<% control.results.each do |result| %>
|
77
|
-
<%= ERB.new(File.read(template_path + "/result.html.erb"),
|
77
|
+
<%= ERB.new(File.read(template_path + "/result.html.erb"), eoutvar: "_rslt").result(binding) %>
|
78
78
|
<% end %>
|
79
79
|
|
80
80
|
</div>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
<% if profile.status == "loaded" %>
|
20
20
|
<% profile.controls.each do |control| %>
|
21
|
-
<%= ERB.new(File.read(template_path + "/control.html.erb"),
|
21
|
+
<%= ERB.new(File.read(template_path + "/control.html.erb"), eoutvar: "_ctl").result(binding) %>
|
22
22
|
<% end %>
|
23
23
|
<% end %>
|
24
24
|
</div>
|
data/lib/plugins/{inspec-artifact/inspec-artifact.gemspec → inspec-sign/inspec-sign.gemspec}
RENAMED
@@ -2,8 +2,8 @@
|
|
2
2
|
# These specs are used in plugin list and search command
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
|
-
spec.name = "inspec-
|
5
|
+
spec.name = "inspec-sign"
|
6
6
|
spec.summary = ""
|
7
7
|
spec.description = "Plugin to generate asymmetrical keys that you can use to encrypt profiles"
|
8
8
|
spec.license = "Apache-2.0"
|
9
|
-
end
|
9
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require "base64" unless defined?(Base64)
|
2
|
+
require "openssl" unless defined?(OpenSSL)
|
3
|
+
require "pathname" unless defined?(Pathname)
|
4
|
+
require "set" unless defined?(Set)
|
5
|
+
require "tempfile" unless defined?(Tempfile)
|
6
|
+
require "yaml"
|
7
|
+
require "inspec/dist"
|
8
|
+
require "inspec/utils/json_profile_summary"
|
9
|
+
require "inspec/iaf_file"
|
10
|
+
|
11
|
+
module InspecPlugins
|
12
|
+
module Sign
|
13
|
+
class Base
|
14
|
+
include Inspec::Dist
|
15
|
+
|
16
|
+
KEY_BITS = 2048
|
17
|
+
KEY_ALG = OpenSSL::PKey::RSA
|
18
|
+
|
19
|
+
INSPEC_PROFILE_VERSION_1 = "INSPEC-PROFILE-1".freeze
|
20
|
+
INSPEC_REPORT_VERSION_1 = "INSPEC-REPORT-1".freeze
|
21
|
+
|
22
|
+
INSPEC_PROFILE_VERSION_2 = "INSPEC-PROFILE-2".freeze
|
23
|
+
ARTIFACT_DIGEST = OpenSSL::Digest::SHA512
|
24
|
+
ARTIFACT_DIGEST_NAME = "SHA512".freeze
|
25
|
+
|
26
|
+
VALID_PROFILE_VERSIONS = Set.new [INSPEC_PROFILE_VERSION_1, INSPEC_PROFILE_VERSION_2]
|
27
|
+
VALID_PROFILE_DIGESTS = Set.new [ARTIFACT_DIGEST_NAME]
|
28
|
+
|
29
|
+
SIGNED_PROFILE_SUFFIX = "iaf".freeze
|
30
|
+
SIGNED_REPORT_SUFFIX = "iar".freeze
|
31
|
+
|
32
|
+
def self.keygen(options)
|
33
|
+
key = KEY_ALG.new KEY_BITS
|
34
|
+
|
35
|
+
path = File.join(Inspec.config_dir, "keys")
|
36
|
+
FileUtils.mkdir_p(path)
|
37
|
+
|
38
|
+
puts "Generating signing key in #{path}/#{options["keyname"]}.pem.key"
|
39
|
+
open "#{path}/#{options["keyname"]}.pem.key", "w" do |io|
|
40
|
+
io.write key.to_pem
|
41
|
+
end
|
42
|
+
puts "Generating validation key in #{path}/#{options["keyname"]}.pem.pub"
|
43
|
+
open "#{path}/#{options["keyname"]}.pem.pub", "w" do |io|
|
44
|
+
io.write key.public_key.to_pem
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.profile_sign(profile_path, options)
|
49
|
+
artifact = new
|
50
|
+
|
51
|
+
# Writes the profile content id in the inspec.yml
|
52
|
+
if options[:profile_content_id] && !options[:profile_content_id].strip.empty?
|
53
|
+
artifact.write_profile_content_id(profile_path, options[:profile_content_id])
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "Signing #{profile_path} with key #{options["keyname"]}"
|
57
|
+
keypath = Inspec::IafFile.find_signing_key(options["keyname"])
|
58
|
+
|
59
|
+
# Read name and version from metadata and use them to form the filename
|
60
|
+
profile_md = artifact.read_profile_metadata(profile_path)
|
61
|
+
|
62
|
+
artifact_filename = "#{profile_md["name"]}-#{profile_md["version"]}.#{SIGNED_PROFILE_SUFFIX}"
|
63
|
+
|
64
|
+
# Generating tar.gz file using archive method of Inspec Cli
|
65
|
+
Inspec::InspecCLI.new.archive(profile_path, "error")
|
66
|
+
tarfile = "#{profile_md["name"]}-#{profile_md["version"]}.tar.gz"
|
67
|
+
tar_content = IO.binread(tarfile)
|
68
|
+
FileUtils.rm(tarfile)
|
69
|
+
|
70
|
+
# Generate the signature
|
71
|
+
signing_key = KEY_ALG.new File.read keypath
|
72
|
+
sha = ARTIFACT_DIGEST.new
|
73
|
+
signature = signing_key.sign sha, tar_content
|
74
|
+
# convert the signature to Base64
|
75
|
+
signature_base64 = Base64.encode64(signature)
|
76
|
+
|
77
|
+
content = (format("%-100s", options[:keyname]) +
|
78
|
+
format("%-20s", ARTIFACT_DIGEST_NAME) +
|
79
|
+
format("%-370s", signature_base64)).gsub(" ", "\0").unpack("H*").pack("h*") + "#{tar_content}"
|
80
|
+
|
81
|
+
File.open(artifact_filename, "wb") do |f|
|
82
|
+
f.puts INSPEC_PROFILE_VERSION_2
|
83
|
+
f.puts "Use \"inspec export\" to view this file"
|
84
|
+
f.write(content)
|
85
|
+
end
|
86
|
+
puts "Successfully generated #{artifact_filename}"
|
87
|
+
rescue Inspec::Exceptions::ProfileValidationKeyNotFound => e
|
88
|
+
$stderr.puts e.message
|
89
|
+
Inspec::UI.new.exit(:usage_error)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.profile_verify(signed_profile_path)
|
93
|
+
file_to_verify = signed_profile_path
|
94
|
+
puts "Verifying #{file_to_verify}"
|
95
|
+
|
96
|
+
iaf_file = Inspec::IafFile.new(file_to_verify)
|
97
|
+
if iaf_file.valid?
|
98
|
+
puts "Detected format version '#{iaf_file.version}'"
|
99
|
+
puts "Attempting to verify using key '#{iaf_file.key_name}'"
|
100
|
+
puts "Profile is valid."
|
101
|
+
Inspec::UI.new.exit(:normal)
|
102
|
+
else
|
103
|
+
puts "Detected format version '#{iaf_file.version}'"
|
104
|
+
puts "Attempting to verify using key '#{iaf_file.key_name}'" if iaf_file.key_name
|
105
|
+
puts "Profile is invalid"
|
106
|
+
Inspec::UI.new.exit(:bad_signature)
|
107
|
+
end
|
108
|
+
rescue Inspec::Exceptions::ProfileValidationKeyNotFound => e
|
109
|
+
$stderr.puts e.message
|
110
|
+
Inspec::UI.new.exit(:usage_error)
|
111
|
+
end
|
112
|
+
|
113
|
+
def read_profile_metadata(profile_path)
|
114
|
+
begin
|
115
|
+
p = Pathname.new(profile_path)
|
116
|
+
p = p.join("inspec.yml")
|
117
|
+
unless p.exist?
|
118
|
+
raise "#{profile_path} doesn't appear to be a valid #{PRODUCT_NAME} profile"
|
119
|
+
end
|
120
|
+
|
121
|
+
yaml = YAML.load_file(p.to_s)
|
122
|
+
yaml = yaml.to_hash
|
123
|
+
|
124
|
+
unless yaml.key? "name"
|
125
|
+
raise "Profile is invalid, name is not defined"
|
126
|
+
end
|
127
|
+
|
128
|
+
unless yaml.key? "version"
|
129
|
+
raise "Profile is invalid, version is not defined"
|
130
|
+
end
|
131
|
+
rescue => e
|
132
|
+
# rewrap it and pass it up to the CLI
|
133
|
+
$stderr.puts "Error reading profile metadata file #{e.message}"
|
134
|
+
Inspec::UI.new.exit(:usage_error)
|
135
|
+
end
|
136
|
+
|
137
|
+
yaml
|
138
|
+
end
|
139
|
+
|
140
|
+
def write_profile_content_id(profile_path, profile_content_id)
|
141
|
+
p = Pathname.new(profile_path)
|
142
|
+
p = p.join("inspec.yml")
|
143
|
+
yaml = YAML.load_file(p.to_s)
|
144
|
+
existing_profile_content_id = yaml["profile_content_id"]
|
145
|
+
|
146
|
+
unless existing_profile_content_id.nil?
|
147
|
+
ui = Inspec::UI.new
|
148
|
+
ui.error("Cannot use --profile-content-id when profile_content_id already exists in metadata file.")
|
149
|
+
ui.exit(:usage_error)
|
150
|
+
end
|
151
|
+
|
152
|
+
lines = IO.readlines(p)
|
153
|
+
lines << "\nprofile_content_id: #{profile_content_id}\n"
|
154
|
+
|
155
|
+
File.open("#{p}", "w" ) do |f|
|
156
|
+
f.puts lines
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -70,46 +70,37 @@ require "inspec/dist"
|
|
70
70
|
# To extract the raw content from a .iaf:
|
71
71
|
# sed '1,/^$/d' foo.iaf
|
72
72
|
|
73
|
+
# inspec artifact is renamed to inspec sign
|
74
|
+
|
73
75
|
module InspecPlugins
|
74
|
-
module
|
76
|
+
module Sign
|
75
77
|
class CLI < Inspec.plugin(2, :cli_command)
|
76
78
|
include Inspec::Dist
|
77
79
|
|
78
|
-
subcommand_desc "
|
80
|
+
subcommand_desc "sign SUBCOMMAND", "Manage #{PRODUCT_NAME} profile signing."
|
79
81
|
|
80
|
-
desc "generate", "Generate a RSA key pair for signing and verification"
|
82
|
+
desc "generate-keys", "Generate a RSA key pair for signing and verification"
|
81
83
|
option :keyname, type: :string, required: true,
|
82
84
|
desc: "Desriptive name of key"
|
83
85
|
option :keydir, type: :string, default: "./",
|
84
86
|
desc: "Directory to search for keys"
|
85
87
|
def generate_keys
|
86
88
|
puts "Generating keys"
|
87
|
-
InspecPlugins::
|
89
|
+
InspecPlugins::Sign::Base.keygen(options)
|
88
90
|
end
|
89
91
|
|
90
|
-
desc "
|
91
|
-
option :profile, type: :string, required: true,
|
92
|
-
desc: "Path to profile directory"
|
92
|
+
desc "profile PATH", "sign the profile in PATH and generate .iaf artifact."
|
93
93
|
option :keyname, type: :string, required: true,
|
94
94
|
desc: "Desriptive name of key"
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
desc "verify-profile", "Verify a signed .iaf artifact"
|
100
|
-
option :infile, type: :string, required: true,
|
101
|
-
desc: ".iaf file to verify"
|
102
|
-
def verify_profile
|
103
|
-
InspecPlugins::Artifact::Base.profile_verify(options)
|
95
|
+
option :profile_content_id, type: :string,
|
96
|
+
desc: "UUID of the profile. This will write the profile_content_id in the metadata file if it does not already exist in the metadata file."
|
97
|
+
def profile(profile_path)
|
98
|
+
InspecPlugins::Sign::Base.profile_sign(profile_path, options)
|
104
99
|
end
|
105
100
|
|
106
|
-
desc "
|
107
|
-
|
108
|
-
|
109
|
-
option :destdir, type: :string, required: true,
|
110
|
-
desc: "Installation directory"
|
111
|
-
def install_profile
|
112
|
-
InspecPlugins::Artifact::Base.profile_install(options)
|
101
|
+
desc "verify PATH", "Verify a signed profile .iaf artifact at given path."
|
102
|
+
def verify(signed_profile_path)
|
103
|
+
InspecPlugins::Sign::Base.profile_verify(signed_profile_path)
|
113
104
|
end
|
114
105
|
end
|
115
106
|
end
|
@@ -12,7 +12,7 @@ module SourceReaders
|
|
12
12
|
nil
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_reader :metadata, :tests, :libraries, :data_files, :target
|
15
|
+
attr_reader :metadata, :metadata_src, :tests, :libraries, :data_files, :target, :readme
|
16
16
|
|
17
17
|
# This create a new instance of an InSpec profile source reader
|
18
18
|
#
|
@@ -24,14 +24,16 @@ module SourceReaders
|
|
24
24
|
@tests = load_tests
|
25
25
|
@libraries = load_libs
|
26
26
|
@data_files = load_data_files
|
27
|
+
@readme = load_readme
|
27
28
|
end
|
28
29
|
|
29
30
|
private
|
30
31
|
|
31
32
|
def load_metadata(metadata_source)
|
33
|
+
@metadata_src = @target.read(metadata_source)
|
32
34
|
Inspec::Metadata.from_ref(
|
33
35
|
metadata_source,
|
34
|
-
@
|
36
|
+
@metadata_src,
|
35
37
|
nil
|
36
38
|
)
|
37
39
|
rescue Psych::SyntaxError => e
|
@@ -62,5 +64,9 @@ module SourceReaders
|
|
62
64
|
def load_data_files
|
63
65
|
load_all(%r{^files/})
|
64
66
|
end
|
67
|
+
|
68
|
+
def load_readme
|
69
|
+
load_all(/README.md/)
|
70
|
+
end
|
65
71
|
end
|
66
72
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.18.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chef InSpec Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-telemetry
|
@@ -370,14 +370,14 @@ dependencies:
|
|
370
370
|
requirements:
|
371
371
|
- - "~>"
|
372
372
|
- !ruby/object:Gem::Version
|
373
|
-
version: '3.
|
373
|
+
version: '3.10'
|
374
374
|
type: :runtime
|
375
375
|
prerelease: false
|
376
376
|
version_requirements: !ruby/object:Gem::Requirement
|
377
377
|
requirements:
|
378
378
|
- - "~>"
|
379
379
|
- !ruby/object:Gem::Version
|
380
|
-
version: '3.
|
380
|
+
version: '3.10'
|
381
381
|
description: InSpec provides a framework for creating end-to-end infrastructure tests.
|
382
382
|
You can use it for integration or even compliance testing. Create fully portable
|
383
383
|
test profiles and use them in your workflow to ensure stability and security. Integrate
|
@@ -444,6 +444,7 @@ files:
|
|
444
444
|
- lib/inspec/formatters/json_rspec.rb
|
445
445
|
- lib/inspec/formatters/show_progress.rb
|
446
446
|
- lib/inspec/globals.rb
|
447
|
+
- lib/inspec/iaf_file.rb
|
447
448
|
- lib/inspec/impact.rb
|
448
449
|
- lib/inspec/input.rb
|
449
450
|
- lib/inspec/input_dsl_helpers.rb
|
@@ -715,13 +716,10 @@ files:
|
|
715
716
|
- lib/inspec/utils/telemetry/data_series.rb
|
716
717
|
- lib/inspec/utils/telemetry/global_methods.rb
|
717
718
|
- lib/inspec/utils/telemetry/run_context_probe.rb
|
719
|
+
- lib/inspec/utils/yaml_profile_summary.rb
|
718
720
|
- lib/inspec/version.rb
|
719
721
|
- lib/matchers/matchers.rb
|
720
722
|
- lib/plugins/README.md
|
721
|
-
- lib/plugins/inspec-artifact/inspec-artifact.gemspec
|
722
|
-
- lib/plugins/inspec-artifact/lib/inspec-artifact.rb
|
723
|
-
- lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb
|
724
|
-
- lib/plugins/inspec-artifact/lib/inspec-artifact/cli.rb
|
725
723
|
- lib/plugins/inspec-compliance/README.md
|
726
724
|
- lib/plugins/inspec-compliance/inspec-compliance.gemspec
|
727
725
|
- lib/plugins/inspec-compliance/lib/inspec-compliance.rb
|
@@ -805,6 +803,10 @@ files:
|
|
805
803
|
- lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb
|
806
804
|
- lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb
|
807
805
|
- lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb
|
806
|
+
- lib/plugins/inspec-sign/inspec-sign.gemspec
|
807
|
+
- lib/plugins/inspec-sign/lib/inspec-sign.rb
|
808
|
+
- lib/plugins/inspec-sign/lib/inspec-sign/base.rb
|
809
|
+
- lib/plugins/inspec-sign/lib/inspec-sign/cli.rb
|
808
810
|
- lib/plugins/inspec-streaming-reporter-progress-bar/README.md
|
809
811
|
- lib/plugins/inspec-streaming-reporter-progress-bar/inspec-streaming-reporter-progress-bar.gemspec
|
810
812
|
- lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb
|