inspec-core 5.17.4 → 5.18.14
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.
- 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
|