lib/utilities/inspec_util.rb in inspec_tools-1.2.2 vs lib/utilities/inspec_util.rb in inspec_tools-1.3.0
- old
+ new
@@ -1,8 +1,10 @@
require 'inspec/objects'
require 'word_wrap'
require 'pp'
+require 'uri'
+require 'net/http'
# rubocop:disable Metrics/ClassLength
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
@@ -92,23 +94,27 @@
data[c_id][:status] = []
data[c_id][:message] = []
if control.key?('results')
control['results'].each do |result|
data[c_id][:status].push(result['status'])
- data[c_id][:message].push(result['skip_message']) if result['status'] == 'skipped'
+ data[c_id][:message].push("SKIPPED -- Test: #{result['code_desc']}\nMessage: #{result['skip_message']}\n") if result['status'] == 'skipped'
data[c_id][:message].push("FAILED -- Test: #{result['code_desc']}\nMessage: #{result['message']}\n") if result['status'] == 'failed'
data[c_id][:message].push("PASS -- #{result['code_desc']}\n") if result['status'] == 'passed'
end
end
if data[c_id][:impact].to_f.zero?
- data[c_id][:message] = control['desc']
+ data[c_id][:message].unshift("NOT_APPLICABLE -- Description: #{control['desc']}\n\n")
end
end
end
data
end
+ def self.get_platform(json)
+ json['profiles'].find { |profile| !profile[:platform].nil? }
+ end
+
def self.to_dotted_hash(hash, recursive_key = '')
hash.each_with_object({}) do |(k, v), ret|
key = recursive_key + k.to_s
if v.is_a? Hash
ret.merge! to_dotted_hash(v, key + '.')
@@ -125,11 +131,12 @@
elsif status_list.include?('skipped')
result = 'Not_Reviewed'
elsif status_list.include?('passed')
result = 'NotAFinding'
else
- result = 'Not_Tested'
+ # result = 'Not_Tested' ## STIGViewer does not allow Not_Tested as a possible status.
+ result = 'Not_Reviewed'
end
if control[:impact].to_f.zero?
result = 'Not_Applicable'
end
result
@@ -137,11 +144,11 @@
def self.control_finding_details(control, control_clk_status)
result = "One or more of the automated tests failed or was inconclusive for the control \n\n #{control[:message].sort.join}" if control_clk_status == 'Open'
result = "All Automated tests passed for the control \n\n #{control[:message].join}" if control_clk_status == 'NotAFinding'
result = "Automated test skipped due to known accepted condition in the control : \n\n#{control[:message].join}" if control_clk_status == 'Not_Reviewed'
- result = "Justification: \n #{control[:message].split.join(' ')}" if control_clk_status == 'Not_Applicable'
+ result = "Justification: \n #{control[:message].join}" if control_clk_status == 'Not_Applicable'
result = 'No test available for this control' if control_clk_status == 'Not_Tested'
result
end
# @!method get_impact(severity)
@@ -168,13 +175,18 @@
else severity
end
end
def self.unpack_inspec_json(directory, inspec_json, separated, output_format)
+ if directory == 'id'
+ directory = inspec_json['name']
+ end
controls = generate_controls(inspec_json)
unpack_profile(directory || 'profile', controls, separated, output_format || 'json')
create_inspec_yml(directory || 'profile', inspec_json)
+ create_license(directory || 'profile', inspec_json)
+ create_readme_md(directory || 'profile', inspec_json)
end
private_class_method def self.wrap(str, width = WIDTH)
str.gsub!("desc \"\n ", 'desc "')
str.gsub!(/\\r/, "\n")
@@ -193,10 +205,11 @@
control.desc = json_control['desc']
end
control.id = json_control['id']
control.title = json_control['title']
control.impact = get_impact(json_control['impact'])
+ control.add_tag(Inspec::Tag.new('severity', json_control['tags']['severity']))
control.add_tag(Inspec::Tag.new('gtitle', json_control['tags']['gtitle']))
control.add_tag(Inspec::Tag.new('satisfies', json_control['tags']['satisfies'])) if json_control['tags']['satisfies']
control.add_tag(Inspec::Tag.new('gid', json_control['tags']['gid']))
control.add_tag(Inspec::Tag.new('rid', json_control['tags']['rid']))
control.add_tag(Inspec::Tag.new('stig_id', json_control['tags']['stig_id']))
@@ -224,29 +237,66 @@
# @!method print_benchmark_info(info)
# writes benchmark info to profile inspec.yml file
#
private_class_method def self.create_inspec_yml(directory, inspec_json)
benchmark_info =
- "name: #{inspec_json['name']}
- title: #{inspec_json['title']}
- maintainer: #{inspec_json['maintainer']}
- copyright: #{inspec_json['copyright']}
- copyright_email: #{inspec_json['copyright_email']}
- license: #{inspec_json['license']}
- summary: #{inspec_json['summary']}
- version: #{inspec_json['version']}"
+ "name: #{inspec_json['name']}\n" \
+ "title: #{inspec_json['title']}\n" \
+ "maintainer: #{inspec_json['maintainer']}\n" \
+ "copyright: #{inspec_json['copyright']}\n" \
+ "copyright_email: #{inspec_json['copyright_email']}\n" \
+ "license: #{inspec_json['license']}\n" \
+ "summary: #{inspec_json['summary']}\n" \
+ "version: #{inspec_json['version']}\n"
myfile = File.new("#{directory}/inspec.yml", 'w')
myfile.puts benchmark_info
end
+ private_class_method def self.create_license(directory, inspec_json)
+ license_content = ''
+ if !inspec_json['license'].nil?
+ begin
+ response = Net::HTTP.get_response(URI(inspec_json['license']))
+ if response.code == '200'
+ license_content = response.body
+ else
+ license_content = inspec_json['license']
+ end
+ rescue StandardError => e
+ license_content = inspec_json['license']
+ end
+ end
+
+ myfile = File.new("#{directory}/LICENSE", 'w')
+ myfile.puts license_content
+ end
+
+ private_class_method def self.create_readme_md(directory, inspec_json)
+ readme_contents =
+ "\# #{inspec_json['title']}\n" \
+ "#{inspec_json['summary']}\n" \
+ "---\n" \
+ "Name: #{inspec_json['name']}\n" \
+ "Author: #{inspec_json['maintainer']}\n" \
+ "Status: #{inspec_json['status']}\n" \
+ "Copyright: #{inspec_json['copyright']}\n" \
+ "Copyright Email: #{inspec_json['copyright_email']}\n" \
+ "Version: #{inspec_json['version']}\n" \
+ "#{inspec_json['plaintext']}\n" \
+ "Reference: #{inspec_json['reference_href']}\n" \
+ "Reference by: #{inspec_json['reference_publisher']}\n" \
+ "Reference source: #{inspec_json['reference_source']}\n"
+
+ myfile = File.new("#{directory}/README.md", 'w')
+ myfile.puts readme_contents
+ end
+
private_class_method def self.unpack_profile(directory, controls, separated, output_format)
FileUtils.rm_rf(directory) if Dir.exist?(directory)
Dir.mkdir directory unless Dir.exist?(directory)
Dir.mkdir "#{directory}/controls" unless Dir.exist?("#{directory}/controls")
Dir.mkdir "#{directory}/libraries" unless Dir.exist?("#{directory}/libraries")
- myfile = File.new("#{directory}/README.md", 'w')
- myfile.puts "# Example InSpec Profile\n\nthis example shows the implementation of an InSpec profile."
if separated
if output_format == 'ruby'
controls.each do |control|
file_name = control.id.to_s
myfile = File.new("#{directory}/controls/#{file_name}.rb", 'w')