class HeimdallTools::XCCDFResultsMapper
Public Class Methods
new(scap_xml, _name = nil)
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 32 def initialize(scap_xml, _name = nil) @scap_xml = scap_xml read_cci_xml begin data = xml_to_hash(scap_xml) @results = data['Benchmark']['TestResult'] @benchmarks = data['Benchmark'] @groups = data['Benchmark']['Group'] rescue StandardError => e raise "Invalid SCAP Client XCCDF output XML file provided Exception: #{e}" end end
Public Instance Methods
cci_nist_tag(cci_refs)
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 71 def cci_nist_tag(cci_refs) nist_tags = [] cci_refs.each do |cci_ref| item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_ref}']")[0] unless @cci_xml.nil? unless item_node.nil? nist_ref = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text end nist_tags << nist_ref end nist_tags end
collapse_duplicates(controls)
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 103 def collapse_duplicates(controls) unique_controls = [] controls.map { |x| x['id'] }.uniq.each do |id| collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] } unique_control = controls.find { |x| x['id'].eql?(id) } unique_control['results'] = collapsed_results.flatten unique_controls << unique_control end unique_controls end
finding(issue, count)
click to toggle source
change for pass/fail based on output Benchmark.rule Pass/Fail are the only two options included in the output file
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 47 def finding(issue, count) finding = {} finding['status'] = issue['rule-result'][count]['result'].to_s if finding['status'] == 'pass' finding['status'] = 'passed' end if finding['status'] == 'fail' finding['status'] = 'failed' end finding['code_desc'] = NA_STRING finding['run_time'] = NA_FLOAT finding['start_time'] = issue['start-time'] finding['message'] = NA_STRING finding['resource_class'] = NA_STRING [finding] end
get_impact(severity)
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 83 def get_impact(severity) IMPACT_MAPPING[severity.to_sym] end
parse_refs(refs)
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 87 def parse_refs(refs) refs.map { |ref| ref['text'] if ref['text'].match?(CCI_REGEX) }.reject!(&:nil?) end
read_cci_xml()
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 64 def read_cci_xml @cci_xml = Nokogiri::XML(File.open(U_CCI_LIST)) @cci_xml.remove_namespaces! rescue StandardError => e puts "Exception: #{e.message}" end
satisfies_parse(satisf)
click to toggle source
Clean up output by removing the Satsifies block and the end of the description
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 92 def satisfies_parse(satisf) temp_satisf = satisf.match('Satisfies: ([^;]*)<\/VulnDiscussion>') return temp_satisf[1].split(',') unless temp_satisf.nil? NA_ARRAY end
to_hdf()
click to toggle source
# File lib/heimdall_tools/xccdf_results_mapper.rb, line 115 def to_hdf controls = [] @groups.each_with_index do |group, i| @item = {} @item['id'] = group['Rule']['id'].split('.').last.split('_').drop(2).first.split('r').first.split('S')[1] @item['title'] = group['Rule']['title'].to_s @item['desc'] = group['Rule']['description'].to_s.split('Satisfies').first @item['descriptions'] = [] @item['descriptions'] << desc_tags(group['Rule']['description'], 'default') @item['descriptions'] << desc_tags('NA', 'rationale') @item['descriptions'] << desc_tags(group['Rule']['check']['check-content-ref']['name'], 'check') @item['descriptions'] << desc_tags(group['Rule']['fixtext']['text'], 'fix') @item['impact'] = get_impact(group['Rule']['severity']) @item['refs'] = NA_ARRAY @item['tags'] = {} @item['tags']['severity'] = nil @item['tags']['gtitle'] = group['title'] @item['tags']['satisfies'] = satisfies_parse(group['Rule']['description']) @item['tags']['gid'] = group['Rule']['id'].split('.').last.split('_').drop(2).first.split('r').first @item['tags']['legacy_id'] = group['Rule']['ident'][2]['text'] @item['tags']['rid'] = group['Rule']['ident'][1]['text'] @item['tags']['stig_id'] = @benchmarks['id'] @item['tags']['fix_id'] = group['Rule']['fix']['id'] @item['tags']['cci'] = parse_refs(group['Rule']['ident']) @item['tags']['nist'] = cci_nist_tag(@item['tags']['cci']) @item['code'] = NA_STRING @item['source_location'] = NA_HASH # results were in another location and using the top block "Benchmark" as a starting point caused odd issues. This works for now for the results. @item['results'] = finding(@results, i) controls << @item end controls = collapse_duplicates(controls) results = HeimdallDataFormat.new(profile_name: @benchmarks['id'], version: @benchmarks['style'], duration: NA_FLOAT, title: @benchmarks['title'], maintainer: @benchmarks['reference']['publisher'], summary: @benchmarks['description'], license: @benchmarks['notice']['id'], copyright: @benchmarks['metadata']['creator'], copyright_email: 'disa.stig_spt@mail.mil', controls: controls) results.to_hdf end