class InspecTools::XCCDF

Public Class Methods

new(xccdf, use_vuln_id, replace_tags = nil) click to toggle source
# File lib/inspec_tools/xccdf.rb, line 10
def initialize(xccdf, use_vuln_id, replace_tags = nil)
  @xccdf = xccdf
  @xccdf = replace_tags_in_xccdf(replace_tags, @xccdf) unless replace_tags.nil?
  cci_list_path = File.join(File.dirname(__FILE__), '../data/U_CCI_List.xml')
  @cci_items = HappyMapperTools::CCIAttributes::CCI_List.parse(File.read(cci_list_path))
  register_after_parse_callbacks
  @benchmark = HappyMapperTools::StigAttributes::Benchmark.parse(@xccdf)
  @use_vuln_id = use_vuln_id
end

Public Instance Methods

inject_metadata(metadata = '{}') click to toggle source
# File lib/inspec_tools/xccdf.rb, line 79
def inject_metadata(metadata = '{}')
  json_metadata = JSON.parse(metadata)
  json_metadata.each do |key, value|
    @profile[key] = value
  end
end
published() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 75
def published
  @benchmark.release_date.release_date
end
publisher() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 71
def publisher
  @benchmark.reference.dc_publisher
end
to_attributes() click to toggle source

extracts non-InSpec attributes

TODO there may be more attributes we want to extract, see data/attributes.yml for example

# File lib/inspec_tools/xccdf.rb, line 41
def to_attributes
  @attribute = {}

  @attribute['benchmark.title'] = @benchmark.title
  @attribute['benchmark.id'] = @benchmark.id
  @attribute['benchmark.description'] = @benchmark.description
  @attribute['benchmark.version'] = @benchmark.version

  @attribute['benchmark.status'] = @benchmark.status
  @attribute['benchmark.status.date'] = @benchmark.release_date.release_date

  @attribute['benchmark.notice.id'] = @benchmark.notice.id

  @attribute['benchmark.plaintext'] = @benchmark.plaintext.plaintext
  @attribute['benchmark.plaintext.id'] = @benchmark.plaintext.id

  @attribute['reference.href'] = @benchmark.reference.href
  @attribute['reference.dc.publisher'] = @benchmark.reference.dc_publisher
  @attribute['reference.dc.source'] = @benchmark.reference.dc_source
  @attribute['reference.dc.title'] = @benchmark.group[0].rule.reference.dc_title if !@benchmark.group[0].nil?
  @attribute['reference.dc.subject'] = @benchmark.group[0].rule.reference.dc_subject if !@benchmark.group[0].nil?
  @attribute['reference.dc.type'] = @benchmark.group[0].rule.reference.dc_type if !@benchmark.group[0].nil?
  @attribute['reference.dc.identifier'] = @benchmark.group[0].rule.reference.dc_identifier if !@benchmark.group[0].nil?

  @attribute['content_ref.name'] = @benchmark.group[0].rule.check.content_ref.name if !@benchmark.group[0].nil?
  @attribute['content_ref.href'] = @benchmark.group[0].rule.check.content_ref.href if !@benchmark.group[0].nil?

  @attribute
end
to_ckl() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 20
def to_ckl
  # TODO: to_ckl
end
to_csv() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 24
def to_csv
  # TODO: to_csv
end
to_inspec() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 28
def to_inspec
  @profile = {}
  @controls = []
  insert_json_metadata
  insert_controls
  @profile['sha256'] = Digest::SHA256.hexdigest @profile.to_s
  @profile
end

Private Instance Methods

insert_controls() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 125
def insert_controls
  @benchmark.group.each do |group|
    control = {}
    control['id'] = @use_vuln_id ? group.id : group.rule.id.split('r').first
    control['title'] = group.rule.title
    control['desc'] = group.rule.description.vuln_discussion.split('Satisfies: ')[0]
    control['impact'] = Utils::InspecUtil.get_impact(group.rule.severity)
    control['tags'] = {}
    control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
    control['tags']['gtitle'] = group.title
    control['tags']['satisfies'] = group.rule.description.vuln_discussion.split('Satisfies: ')[1].split(',').map(&:strip) if group.rule.description.vuln_discussion.split('Satisfies: ').length > 1
    control['tags']['gid'] = group.id
    control['tags']['rid'] = group.rule.id
    control['tags']['stig_id'] = group.rule.version
    control['tags']['fix_id'] = group.rule.fix.id
    control['tags']['cci'] = group.rule.idents.select(&:cci).map(&:ident)
    legacy_tags = group.rule.idents.select(&:legacy)
    control['tags']['legacy'] = legacy_tags.map(&:ident) unless legacy_tags.empty?
    control['tags']['nist'] = @cci_items.fetch_nists(control['tags']['cci'])
    control['tags']['false_negatives'] = group.rule.description.false_negatives if group.rule.description.false_negatives != ''
    control['tags']['false_positives'] = group.rule.description.false_positives if group.rule.description.false_positives != ''
    control['tags']['documentable'] = group.rule.description.documentable if group.rule.description.documentable != ''
    control['tags']['mitigations'] = group.rule.description.false_negatives if group.rule.description.mitigations != ''
    control['tags']['severity_override_guidance'] = group.rule.description.severity_override_guidance if group.rule.description.severity_override_guidance != ''
    control['tags']['security_override_guidance'] = group.rule.description.security_override_guidance if group.rule.description.security_override_guidance != ''
    control['tags']['potential_impacts'] = group.rule.description.potential_impacts if group.rule.description.potential_impacts != ''
    control['tags']['third_party_tools'] = group.rule.description.third_party_tools if group.rule.description.third_party_tools != ''
    control['tags']['mitigation_controls'] = group.rule.description.mitigation_controls if group.rule.description.mitigation_controls != ''
    control['tags']['responsibility'] = group.rule.description.responsibility if group.rule.description.responsibility != ''
    control['tags']['ia_controls'] = group.rule.description.ia_controls if group.rule.description.ia_controls != ''
    control['tags']['check'] = group.rule.check.content
    control['tags']['fix'] = group.rule.fixtext
    @controls << control
  end
  @profile['controls'] = @controls
end
insert_json_metadata() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 103
def insert_json_metadata
  @profile['name'] = @benchmark.id
  @profile['title'] = @benchmark.title
  @profile['maintainer'] = 'The Authors' if @profile['maintainer'].nil?
  @profile['copyright'] = 'The Authors' if @profile['copyright'].nil?
  @profile['copyright_email'] = 'you@example.com' if @profile['copyright_email'].nil?
  @profile['license'] = 'Apache-2.0' if @profile['license'].nil?
  @profile['summary'] = "\"#{@benchmark.description.gsub('\\', '\\\\\\').gsub('"', '\"')}\""
  @profile['version'] = '0.1.0' if @profile['version'].nil?
  @profile['supports'] = []
  @profile['attributes'] = []
  @profile['generator'] = {
    name: 'inspec_tools',
    version: VERSION
  }
  @profile['plaintext'] = @benchmark.plaintext.plaintext
  @profile['status'] = "#{@benchmark.status} on #{@benchmark.release_date.release_date}"
  @profile['reference_href'] = @benchmark.reference.href
  @profile['reference_publisher'] = @benchmark.reference.dc_publisher
  @profile['reference_source'] = @benchmark.reference.dc_source
end
register_after_parse_callbacks() click to toggle source
# File lib/inspec_tools/xccdf.rb, line 88
def register_after_parse_callbacks
  # Determine if the parsed Ident is refrencing a legacy ID number.
  HappyMapperTools::StigAttributes::Ident.after_parse do |object|
    object.cci = object.system.eql?('http://cyber.mil/cci')
    object.legacy = !object.cci
  end
end
replace_tags_in_xccdf(replace_tags, xccdf_xml) click to toggle source
# File lib/inspec_tools/xccdf.rb, line 96
def replace_tags_in_xccdf(replace_tags, xccdf_xml)
  replace_tags.each do |tag|
    xccdf_xml = xccdf_xml.gsub(/(&lt;|<)#{tag}(&gt;|>)/, "$#{tag}")
  end
  xccdf_xml
end