lib/linux_admin/scap.rb in linux_admin-0.20.2 vs lib/linux_admin/scap.rb in linux_admin-1.0.0

- old
+ new

@@ -1,85 +1,67 @@ require 'nokogiri' module LinuxAdmin class Scap - PROFILE_ID = "linux-admin-scap" + PROFILE_ID = "xccdf_org.ssgproject.content_profile_linux-admin-scap".freeze SSG_XML_PATH = Pathname.new("/usr/share/xml/scap/ssg/content/") + attr_reader :platform + def self.openscap_available? require 'openscap' true rescue LoadError false end - def self.ssg_available? - xccdf_file && oval_file + def self.ssg_available?(platform) + ds_file(platform).exist? end + def self.ds_file(platform) + SSG_XML_PATH.join("ssg-#{platform}-ds.xml") + end + + def initialize(platform) + @platform = platform + end + def lockdown(*args) raise "OpenSCAP not available" unless self.class.openscap_available? - raise "SCAP Security Guide not available" unless self.class.ssg_available? + raise "SCAP Security Guide not available" unless self.class.ssg_available?(platform) values = args.last.kind_of?(Hash) ? args.pop : {} rules = args raise "No SCAP rules provided" if rules.empty? - with_xml_files(rules, values) do |xccdf_file_path| - lockdown_profile(xccdf_file_path, PROFILE_ID) + with_ds_file(rules, values) do |path| + lockdown_profile(path, PROFILE_ID) end end - def lockdown_profile(xccdf_file_path, profile_id) + def lockdown_profile(ds_path, profile_id) raise "OpenSCAP not available" unless self.class.openscap_available? - session = OpenSCAP::Xccdf::Session.new(xccdf_file_path) + session = OpenSCAP::Xccdf::Session.new(ds_path) session.load session.profile = profile_id session.evaluate session.remediate ensure session.destroy if session end private - def self.xccdf_file - local_ssg_file("xccdf") - end - - def self.oval_file - local_ssg_file("oval") - end - - def self.local_ssg_file(type) - Dir.glob(SSG_XML_PATH.join("ssg-*-#{type}.xml")).detect { |f| f =~ /ssg-\w+-#{type}.xml/ } - end - - def tempdir - @tempdir ||= Pathname.new(Dir.tmpdir) - end - - def xccdf_file - @xccdf_file ||= self.class.xccdf_file - end - - def oval_file - @oval_file ||= self.class.oval_file - end - - def with_xml_files(rules, values) - FileUtils.cp(oval_file, tempdir) - - Tempfile.create("scap_xccdf") do |f| - write_xccdf_xml(f, profile_xml(PROFILE_ID, rules, values)) + def with_ds_file(rules, values) + Tempfile.create("scap_ds") do |f| + write_ds_xml(f, profile_xml(PROFILE_ID, rules, values)) f.close yield f.path end - ensure - FileUtils.rm_f(tempdir.join(File.basename(oval_file))) end def profile_xml(profile_id, rules, values) builder = Nokogiri::XML::Builder.new do |xml| xml.Profile(:id => profile_id) do @@ -90,15 +72,18 @@ end end builder.doc.root.to_xml end - def write_xccdf_xml(io, profile_xml) - File.open(xccdf_file) do |f| + def write_ds_xml(io, profile_xml) + File.open(self.class.ds_file(platform)) do |f| doc = Nokogiri::XML(f) - model = doc.at_css("model") - model.add_next_sibling("\n#{profile_xml}") + model_xml_element(doc).add_next_sibling("\n#{profile_xml}") io.write(doc.root.to_xml) end + end + + def model_xml_element(doc) + doc.css("//nist_list|model", "nist_list" => "http://checklists.nist.gov/xccdf/1.2").detect { |model| model.namespace.prefix.nil? } end end end