require 'digest' require_relative '../utilities/inspec_util' require_relative '../utilities/extract_pdf_text' require_relative '../utilities/parser' require_relative '../utilities/text_cleaner' require_relative '../utilities/cis_to_nist' module InspecTools class PDF def initialize(pdf, profile_name, debug = false) raise ArgumentError if pdf.nil? @pdf = pdf @name = profile_name @debug = debug end def to_inspec @controls = [] @csv_handle = nil @cci_xml = nil @nist_mapping = Utils::CisToNist.get_mapping('cis_to_nist_critical_controls') @pdf_text = '' @clean_text = '' @transformed_data = '' @profile = {} read_pdf @title ||= extract_title clean_pdf_text transform_data insert_json_metadata @profile['controls'] = parse_controls @profile['sha256'] = Digest::SHA256.hexdigest @profile.to_s @profile end def to_csv # TODO: to_csv end def to_xccdf # TODO: to_xccdf end def to_ckl # TODO: to_ckl end private # converts passed in data into InSpec format def parse_controls controls = [] @transformed_data.each do |contr| nist = find_nist(contr[:cis]) unless contr[:cis] == 'No CIS Control' control = {} control['id'] = "M-#{contr[:title].split[0]}" control['title'] = contr[:title] control['desc'] = contr[:descr] control['impact'] = Utils::InspecUtil.get_impact('medium') control['tags'] = {} control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact']) control['tags']['ref'] = contr[:ref] unless contr[:ref].nil? control['tags']['applicability'] = contr[:applicability] unless contr[:applicability].nil? control['tags']['cis_id'] = contr[:title].split[0] unless contr[:title].nil? control['tags']['cis_control'] = [contr[:cis], @nist_mapping[0][:cis_ver]] unless contr[:cis].nil? # tag cis_control: [5, 6.1] ##6.1 is the version control['tags']['cis_level'] = contr[:level] unless contr[:level].nil? control['tags']['nist'] = nist unless nist.nil? # tag nist: [AC-3, 4] ##4 is the version control['tags']['check'] = contr[:check] unless contr[:check].nil? control['tags']['fix'] = contr[:fix] unless contr[:fix].nil? control['tags']['Default Value'] = contr[:default] unless contr[:default].nil? controls << control end controls end def insert_json_metadata @profile['name'] = @name @profile['title'] = @title @profile['maintainer'] = 'The Authors' @profile['copyright'] = 'The Authors' @profile['copyright_email'] = 'you@example.com' @profile['license'] = 'Apache-2.0' @profile['summary'] = 'An InSpec Compliance Profile' @profile['version'] = '0.1.0' @profile['supports'] = [] @profile['attributes'] = [] @profile['generator'] = { name: 'inspec_tools', version: VERSION } end def extract_title @pdf_text.match(/([^\n]*)\n/).captures[0] end def read_pdf @pdf_text = Util::ExtractPdfText.new(@pdf).extracted_text write_pdf_text if @debug end def clean_pdf_text @clean_text = Util::TextCleaner.new.clean_data(@pdf_text) write_clean_text if @debug end def transform_data @transformed_data = Util::PrepareData.new(@clean_text).transformed_data end def write_pdf_text File.write('pdf_text', @pdf_text) end def write_clean_text File.write('debug_text', @clean_text) end end end