inspec_tools 0.0.0.1.ENOTAG

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +662 -0
  3. data/LICENSE.md +15 -0
  4. data/README.md +329 -0
  5. data/Rakefile +30 -0
  6. data/exe/inspec_tools +14 -0
  7. data/lib/data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx +0 -0
  8. data/lib/data/NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx +0 -0
  9. data/lib/data/README.TXT +25 -0
  10. data/lib/data/U_CCI_List.xml +38403 -0
  11. data/lib/data/attributes.yml +23 -0
  12. data/lib/data/cci2html.xsl +136 -0
  13. data/lib/data/mapping.yml +17 -0
  14. data/lib/data/stig.csv +1 -0
  15. data/lib/data/threshold.yaml +83 -0
  16. data/lib/exceptions/impact_input_error.rb +6 -0
  17. data/lib/exceptions/severity_input_error.rb +6 -0
  18. data/lib/happy_mapper_tools/benchmark.rb +161 -0
  19. data/lib/happy_mapper_tools/cci_attributes.rb +66 -0
  20. data/lib/happy_mapper_tools/stig_attributes.rb +196 -0
  21. data/lib/happy_mapper_tools/stig_checklist.rb +99 -0
  22. data/lib/inspec_tools.rb +17 -0
  23. data/lib/inspec_tools/ckl.rb +20 -0
  24. data/lib/inspec_tools/cli.rb +31 -0
  25. data/lib/inspec_tools/csv.rb +101 -0
  26. data/lib/inspec_tools/help.rb +9 -0
  27. data/lib/inspec_tools/help/compliance.md +7 -0
  28. data/lib/inspec_tools/help/csv2inspec.md +5 -0
  29. data/lib/inspec_tools/help/inspec2ckl.md +5 -0
  30. data/lib/inspec_tools/help/inspec2csv.md +5 -0
  31. data/lib/inspec_tools/help/inspec2xccdf.md +5 -0
  32. data/lib/inspec_tools/help/pdf2inspec.md +6 -0
  33. data/lib/inspec_tools/help/summary.md +5 -0
  34. data/lib/inspec_tools/help/xccdf2inspec.md +5 -0
  35. data/lib/inspec_tools/inspec.rb +331 -0
  36. data/lib/inspec_tools/pdf.rb +136 -0
  37. data/lib/inspec_tools/plugin.rb +15 -0
  38. data/lib/inspec_tools/plugin_cli.rb +278 -0
  39. data/lib/inspec_tools/summary.rb +126 -0
  40. data/lib/inspec_tools/version.rb +8 -0
  41. data/lib/inspec_tools/xccdf.rb +155 -0
  42. data/lib/inspec_tools/xlsx_tool.rb +148 -0
  43. data/lib/inspec_tools_plugin.rb +7 -0
  44. data/lib/overrides/false_class.rb +5 -0
  45. data/lib/overrides/nil_class.rb +5 -0
  46. data/lib/overrides/object.rb +5 -0
  47. data/lib/overrides/string.rb +5 -0
  48. data/lib/overrides/true_class.rb +5 -0
  49. data/lib/utilities/csv_util.rb +14 -0
  50. data/lib/utilities/extract_nist_cis_mapping.rb +57 -0
  51. data/lib/utilities/extract_pdf_text.rb +20 -0
  52. data/lib/utilities/inspec_util.rb +435 -0
  53. data/lib/utilities/parser.rb +373 -0
  54. data/lib/utilities/text_cleaner.rb +69 -0
  55. metadata +359 -0
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+ # rubocop:disable Naming/ClassAndModuleCamelCase
7
+
8
+ module HappyMapperTools
9
+ module CCIAttributes
10
+ class Reference
11
+ include HappyMapper
12
+ tag 'reference'
13
+
14
+ attribute :creator, String, tag: 'creator'
15
+ attribute :title, String, tag: 'title'
16
+ attribute :version, String, tag: 'version'
17
+ attribute :location, String, tag: 'location'
18
+ attribute :index, String, tag: 'index'
19
+ end
20
+
21
+ class CCI_Item
22
+ include HappyMapper
23
+ tag 'cci_item'
24
+
25
+ attribute :id, String, tag: 'id'
26
+ element :status, String, tag: 'status'
27
+ element :publishdate, String, tag: 'publishdate'
28
+ element :contributor, String, tag: 'contributor'
29
+ element :definition, String, tag: 'definition'
30
+ element :type, String, tag: 'type'
31
+ has_many :references, Reference, xpath: 'xmlns:references'
32
+ end
33
+
34
+ class Metadata
35
+ include HappyMapper
36
+ tag 'metadata'
37
+
38
+ element :version, String, tag: 'version'
39
+ element :publishdate, String, tag: 'publishdate'
40
+ end
41
+
42
+ class CCI_List
43
+ include HappyMapper
44
+ tag 'cci_list'
45
+
46
+ attribute :xsi, String, tag: 'xsi', namespace: 'xmlns'
47
+ attribute :schemaLocation, String, tag: 'schemaLocation', namespace: 'xmlns'
48
+ has_one :metadata, Metadata, tag: 'metadata'
49
+ has_many :cci_items, CCI_Item, xpath: 'xmlns:cci_items'
50
+
51
+ def fetch_nists(ccis)
52
+ ccis = [ccis] unless ccis.is_a?(Array)
53
+
54
+ # some of the XCCDF files were having CCE- tags show up which
55
+ # we don't support, not sure if this is a typo on their part or
56
+ # we need to see about supporting CCE tags but ... for now
57
+ filtered_ccis = ccis.select { |f| /CCI-/.match(f) }
58
+ filtered_ccis.map do |cci|
59
+ cci_items.find { |item| item.id == cci }.references.max_by(&:version).index
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # rubocop:enable Naming/ClassAndModuleCamelCase
@@ -0,0 +1,196 @@
1
+ # encoding: utf-8
2
+
3
+ module HappyMapperTools
4
+ module StigAttributes
5
+ require 'happymapper'
6
+ require 'nokogiri'
7
+ require 'colorize'
8
+
9
+ class ContentRef
10
+ include HappyMapper
11
+ tag 'check-content-ref'
12
+ attribute :name, String, tag: 'name'
13
+ attribute :href, String, tag: 'href'
14
+ end
15
+
16
+ class Check
17
+ include HappyMapper
18
+ tag 'check'
19
+
20
+ element :content_ref, ContentRef, tag: 'check-content-ref'
21
+ element :content, String, tag: 'check-content'
22
+ end
23
+
24
+ class Fix
25
+ include HappyMapper
26
+ tag 'fix'
27
+
28
+ attribute :id, String, tag: 'id'
29
+ end
30
+
31
+ class DescriptionDetails
32
+ include HappyMapper
33
+ tag 'Details'
34
+
35
+ element :vuln_discussion, String, tag: 'VulnDiscussion'
36
+ element :false_positives, String, tag: 'FalsePositives'
37
+ element :false_negatives, String, tag: 'FalseNegatives'
38
+ element :documentable, Boolean, tag: 'Documentable'
39
+ element :mitigations, String, tag: 'Mitigations'
40
+ element :severity_override_guidance, String, tag: 'SeverityOverrideGuidance'
41
+ element :potential_impacts, String, tag: 'PotentialImpacts'
42
+ element :third_party_tools, String, tag: 'ThirdPartyTools'
43
+ element :mitigation_controls, String, tag: 'MitigationControl'
44
+ element :responsibility, String, tag: 'Responsibility'
45
+ element :ia_controls, String, tag: 'IAControls'
46
+ end
47
+
48
+ class Description
49
+ include HappyMapper
50
+ tag 'description'
51
+
52
+ content :details, DescriptionDetails
53
+
54
+ detail_tags = %i(vuln_discussion false_positives false_negatives documentable
55
+ mitigations severity_override_guidance potential_impacts
56
+ third_party_tools mitigation_controls responsibility ia_controls)
57
+
58
+ detail_tags.each do |name|
59
+ define_method name do
60
+ details.send(name)
61
+ end
62
+ end
63
+ end
64
+
65
+ class ReferenceInfo
66
+ include HappyMapper
67
+ tag 'reference'
68
+
69
+ attribute :href, String, tag: 'href'
70
+ element :dc_publisher, String, tag: 'publisher', namespace: 'dc'
71
+ element :dc_source, String, tag: 'source', namespace: 'dc'
72
+ element :dc_title, String, tag: 'title', namespace: 'dc'
73
+ element :dc_type, String, tag: 'type', namespace: 'dc'
74
+ element :dc_subject, String, tag: 'subject', namespace: 'dc'
75
+ element :dc_identifier, String, tag: 'identifier', namespace: 'dc'
76
+ end
77
+
78
+ class Rule
79
+ include HappyMapper
80
+ tag 'Rule'
81
+
82
+ attribute :id, String, tag: 'id'
83
+ attribute :severity, String, tag: 'severity'
84
+ element :version, String, tag: 'version'
85
+ element :title, String, tag: 'title'
86
+ has_one :description, Description, tag: 'description'
87
+ element :reference, ReferenceInfo, tag: 'reference'
88
+ has_many :idents, String, tag: 'ident'
89
+ element :fixtext, String, tag: 'fixtext'
90
+ has_one :fix, Fix, tag: 'fix'
91
+ has_one :check, Check, tag: 'check'
92
+ end
93
+
94
+ class Group
95
+ include HappyMapper
96
+ tag 'Group'
97
+
98
+ attribute :id, String, tag: 'id'
99
+ element :title, String, tag: 'title'
100
+ element :description, String, tag: 'description'
101
+ has_one :rule, Rule, tag: 'Rule'
102
+ end
103
+
104
+ class ReleaseDate
105
+ include HappyMapper
106
+ tag 'status'
107
+
108
+ attribute :release_date, String, tag: 'date'
109
+ end
110
+
111
+ class Notice
112
+ include HappyMapper
113
+ tag 'notice'
114
+ attribute :id, String, tag: 'id'
115
+ attribute :xml_lang, String, namespace: 'xml', tag: 'lang'
116
+ content :notice, String, tag: 'notice'
117
+ end
118
+
119
+ class Plaintext
120
+ include HappyMapper
121
+ tag 'plain-text'
122
+ attribute :id, String, tag: 'id'
123
+ content :plaintext, String
124
+ end
125
+
126
+ class Benchmark
127
+ include HappyMapper
128
+ tag 'Benchmark'
129
+
130
+ has_one :release_date, ReleaseDate, tag: 'status'
131
+ attribute :id, String, tag: 'id'
132
+ element :status, String, tag: 'status'
133
+ element :title, String, tag: 'title'
134
+ element :description, String, tag: 'description'
135
+ element :version, String, tag: 'version'
136
+ element :notice, Notice, tag: 'notice'
137
+ has_one :reference, ReferenceInfo, tag: 'reference'
138
+ element :plaintext, Plaintext, tag: 'plain-text'
139
+ has_many :group, Group, tag: 'Group'
140
+ end
141
+
142
+ class DescriptionDetailsType
143
+ def self.type
144
+ DescriptionDetails
145
+ end
146
+
147
+ def self.apply(value) # rubocop:disable Metrics/AbcSize
148
+ value = value.gsub('&', 'and')
149
+ DescriptionDetails.parse "<Details>#{value}</Details>"
150
+ rescue Nokogiri::XML::SyntaxError
151
+ allowed_tags = %w{VulnDiscussion FalsePositives FalseNegatives Documentable
152
+ Mitigations SeverityOverrideGuidance PotentialImpacts
153
+ PotentialImpacts ThirdPartyTools MitigationControl
154
+ Responsibility IAControls}
155
+
156
+ tags_found = value.scan(%r{(?<=<)([^\/]*?)((?= \/>)|(?=>))}).to_a
157
+
158
+ tags_found = tags_found.uniq.flatten.reject!(&:empty?)
159
+ offending_tags = tags_found - allowed_tags
160
+
161
+ if offending_tags.count > 1
162
+ puts "\n\nThe non-standard tags: #{offending_tags.to_s.colorize(:red)}" \
163
+ ' were found in: ' + "\n\n#{value}"
164
+ else
165
+ puts "\n\nThe non-standard tag: #{offending_tags.to_s.colorize(:red)}" \
166
+ ' was found in: ' + "\n\n#{value}"
167
+ end
168
+ puts "\n\nPlease:\n "
169
+ option_one = '(1) ' + '(best)'.colorize(:green) + ' Use the ' +
170
+ '`-r --replace-tags array` '.colorize(:light_yellow) +
171
+ '(case sensitive) option to replace the offending tags ' \
172
+ 'during processing of the XCCDF ' \
173
+ 'file to use the ' +
174
+ "`$#{offending_tags[0]}` " .colorize(:light_green) +
175
+ 'syntax in your InSpec profile.'
176
+ option_two = '(2) Update your XCCDF file to *not use* non-standard XCCDF ' \
177
+ 'elements within ' +
178
+ '`&lt;`,`&gt;`, `<` '.colorize(:red) +
179
+ 'or '.colorize(:default) +
180
+ '`>` '.colorize(:red) +
181
+ 'as "placeholders", and use something that doesn\'t confuse ' \
182
+ 'the XML parser, such as : ' +
183
+ "`$#{offending_tags[0]}`" .colorize(:light_green)
184
+ puts option_one
185
+ puts "\n"
186
+ puts option_two
187
+ # exit
188
+ end
189
+
190
+ def self.apply?(value, _convert_to_type)
191
+ value.is_a?(String)
192
+ end
193
+ end
194
+ HappyMapper::SupportedTypes.register DescriptionDetailsType
195
+ end
196
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+ module HappyMapperTools
7
+ module StigChecklist
8
+ # see: https://github.com/dam5s/happymapper
9
+ # Class Asset maps from the 'Asset' from Checklist XML file using HappyMapper
10
+ class Asset
11
+ include HappyMapper
12
+ tag 'ASSET'
13
+ element :role, String, tag: 'ROLE'
14
+ element :type, String, tag: 'ASSET_TYPE'
15
+ element :host_name, String, tag: 'HOST_NAME'
16
+ element :host_ip, String, tag: 'HOST_IP'
17
+ element :host_mac, String, tag: 'HOST_MAC'
18
+ element :host_guid, String, tag: 'HOST_GUID'
19
+ element :host_fqdn, String, tag: 'HOST_FQDN'
20
+ element :tech_area, String, tag: 'TECH_AREA'
21
+ element :target_key, String, tag: 'TARGET_KEY'
22
+ element :web_or_database, String, tag: 'WEB_OR_DATABASE'
23
+ element :web_db_site, String, tag: 'WEB_DB_SITE'
24
+ element :web_db_instance, String, tag: 'WEB_DB_INSTANCE'
25
+ end
26
+
27
+ # Class Asset maps from the 'SI_DATA' from Checklist XML file using HappyMapper
28
+ class SiData
29
+ include HappyMapper
30
+ tag 'SI_DATA'
31
+ element :name, String, tag: 'SID_NAME'
32
+ element :data, String, tag: 'SID_DATA'
33
+ end
34
+
35
+ # Class Asset maps from the 'STIG_INFO' from Checklist XML file using HappyMapper
36
+ class StigInfo
37
+ include HappyMapper
38
+ tag 'STIG_INFO'
39
+ has_many :si_data, SiData, tag: 'SI_DATA'
40
+ end
41
+
42
+ # Class Asset maps from the 'STIG_DATA' from Checklist XML file using HappyMapper
43
+ class StigData
44
+ include HappyMapper
45
+
46
+ def initialize(attrib = nil, data = nil)
47
+ self.attrib = attrib
48
+ self.data = data
49
+ end
50
+
51
+ tag 'STIG_DATA'
52
+ has_one :attrib, String, tag: 'VULN_ATTRIBUTE'
53
+ has_one :data, String, tag: 'ATTRIBUTE_DATA'
54
+ end
55
+
56
+ # Class Asset maps from the 'VULN' from Checklist XML file using HappyMapper
57
+ class Vuln
58
+ include HappyMapper
59
+ tag 'VULN'
60
+ has_many :stig_data, StigData, tag: 'STIG_DATA'
61
+ has_one :status, String, tag: 'STATUS'
62
+ has_one :finding_details, String, tag: 'FINDING_DETAILS'
63
+ has_one :comments, String, tag: 'COMMENTS'
64
+ has_one :severity_override, String, tag: 'SEVERITY_OVERRIDE'
65
+ has_one :severity_justification, String, tag: 'SEVERITY_JUSTIFICATION'
66
+ end
67
+
68
+ # Class Asset maps from the 'iSTIG' from Checklist XML file using HappyMapper
69
+ class IStig
70
+ include HappyMapper
71
+ tag 'iSTIG'
72
+ has_one :stig_info, StigInfo, tag: 'STIG_INFO'
73
+ has_many :vuln, Vuln, tag: 'VULN'
74
+ end
75
+
76
+ # Class Asset maps from the 'STIGS' from Checklist XML file using HappyMapper
77
+ class Stigs
78
+ include HappyMapper
79
+ tag 'STIGS'
80
+ has_one :istig, IStig, tag: 'iSTIG'
81
+ end
82
+
83
+ class Checklist
84
+ include HappyMapper
85
+ tag 'CHECKLIST'
86
+ has_one :asset, Asset, tag: 'ASSET'
87
+ has_one :stig, Stigs, tag: 'STIGS'
88
+
89
+ def where(attrib, data)
90
+ stig.istig.vuln.each do |vuln|
91
+ if vuln.stig_data.any? { |element| element.attrib == attrib && element.data == data }
92
+ # TODO: Handle multiple objects that match the condition
93
+ return vuln
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift(File.expand_path(__dir__))
2
+ require 'inspec_tools/version'
3
+ require 'rubygems'
4
+
5
+ module InspecTools
6
+ autoload :Help, 'inspec_tools/help'
7
+ autoload :Command, 'inspec_tools/command'
8
+ autoload :CLI, 'inspec_tools/cli'
9
+ autoload :XCCDF, 'inspec_tools/xccdf'
10
+ autoload :PDF, 'inspec_tools/pdf'
11
+ autoload :CSV, 'inspec_tools/csv'
12
+ autoload :CKL, 'inspec_tools/ckl'
13
+ autoload :Inspec, 'inspec_tools/inspec'
14
+ autoload :Summary, 'inspec_tools/summary'
15
+ autoload :Threshold, 'inspec_tools/threshold'
16
+ autoload :XLSXTool, 'inspec_tools/xlsx_tool'
17
+ end
@@ -0,0 +1,20 @@
1
+ module InspecTools
2
+ # Methods for converting from CKL to various formats
3
+ class CKL
4
+ def initialize(ckl)
5
+ @ckl = ckl
6
+ end
7
+
8
+ def to_csv
9
+ # TODO: to_csv
10
+ end
11
+
12
+ def to_xccdf
13
+ # TODO: to_xccdf
14
+ end
15
+
16
+ def to_inspec
17
+ # TODO: to_inspec
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ require 'inspec-objects'
5
+ require 'inspec'
6
+ require_relative './plugin_cli.rb'
7
+
8
+ # This tells the ruby cli app to use the same argument parsing as the plugin
9
+ module InspecTools
10
+ CLI = InspecPlugins::InspecToolsPlugin::CliCommand
11
+ end
12
+
13
+ #=====================================================================#
14
+ # Pre-Flight Code
15
+ #=====================================================================#
16
+ help_commands = ['-h', '--help', 'help']
17
+ log_commands = ['-l', '--log-directory']
18
+ version_commands = ['-v', '--version', 'version']
19
+
20
+ #---------------------------------------------------------------------#
21
+ # Adjustments for non-required version commands
22
+ #---------------------------------------------------------------------#
23
+ unless (version_commands & ARGV).empty?
24
+ puts InspecTools::VERSION
25
+ exit 0
26
+ end
27
+
28
+ #---------------------------------------------------------------------#
29
+ # Adjustments for non-required log-directory
30
+ #---------------------------------------------------------------------#
31
+ ARGV.push("--log-directory=#{Dir.pwd}/logs") if (log_commands & ARGV).empty? && (help_commands & ARGV).empty?
@@ -0,0 +1,101 @@
1
+ require 'csv'
2
+ require 'nokogiri'
3
+ require 'word_wrap'
4
+ require 'yaml'
5
+ require 'digest'
6
+
7
+ require_relative '../utilities/inspec_util'
8
+
9
+ # rubocop:disable Metrics/AbcSize
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ # rubocop:disable Metrics/CyclomaticComplexity
12
+
13
+ module InspecTools
14
+ # Methods for converting from CSV to various formats
15
+ class CSVTool
16
+ def initialize(csv, mapping, name, verbose = false)
17
+ @name = name
18
+ @csv = csv
19
+ @mapping = mapping
20
+ @verbose = verbose
21
+ @csv.shift if @mapping['skip_csv_header']
22
+ end
23
+
24
+ def to_ckl
25
+ # TODO
26
+ end
27
+
28
+ def to_xccdf
29
+ # TODO
30
+ end
31
+
32
+ def to_inspec
33
+ @controls = []
34
+ @cci_xml = nil
35
+ @profile = {}
36
+ read_cci_xml
37
+ insert_json_metadata
38
+ parse_controls
39
+ @profile['controls'] = @controls
40
+ @profile['sha256'] = Digest::SHA256.hexdigest @profile.to_s
41
+ @profile
42
+ end
43
+
44
+ private
45
+
46
+ def insert_json_metadata
47
+ @profile['name'] = @name
48
+ @profile['title'] = 'InSpec Profile'
49
+ @profile['maintainer'] = 'The Authors'
50
+ @profile['copyright'] = 'The Authors'
51
+ @profile['copyright_email'] = 'you@example.com'
52
+ @profile['license'] = 'Apache-2.0'
53
+ @profile['summary'] = 'An InSpec Compliance Profile'
54
+ @profile['version'] = '0.1.0'
55
+ @profile['supports'] = []
56
+ @profile['attributes'] = []
57
+ @profile['generator'] = {
58
+ 'name': 'inspec_tools',
59
+ 'version': VERSION
60
+ }
61
+ end
62
+
63
+ def read_cci_xml
64
+ cci_list_path = File.join(File.dirname(__FILE__), '../data/U_CCI_List.xml')
65
+ @cci_xml = Nokogiri::XML(File.open(cci_list_path))
66
+ @cci_xml.remove_namespaces!
67
+ rescue StandardError => e
68
+ puts "Exception: #{e.message}"
69
+ end
70
+
71
+ def get_nist_reference(cci_number)
72
+ item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_number}']")[0] unless @cci_xml.nil?
73
+ unless item_node.nil?
74
+ nist_ref = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
75
+ nist_ver = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@version').text
76
+ end
77
+ [nist_ref, nist_ver]
78
+ end
79
+
80
+ def parse_controls
81
+ @csv.each do |row|
82
+ print '.'
83
+ control = {}
84
+ control['id'] = row[@mapping['control.id']] unless @mapping['control.id'].nil? || row[@mapping['control.id']].nil?
85
+ control['title'] = row[@mapping['control.title']] unless @mapping['control.title'].nil? || row[@mapping['control.title']].nil?
86
+ control['desc'] = row[@mapping['control.desc']] unless @mapping['control.desc'].nil? || row[@mapping['control.desc']].nil?
87
+ control['tags'] = {}
88
+ nist, nist_rev = get_nist_reference(row[@mapping['control.tags']['cci']]) unless @mapping['control.tags']['cci'].nil? || row[@mapping['control.tags']['cci']].nil?
89
+ control['tags']['nist'] = [nist, 'Rev_' + nist_rev] unless nist.nil? || nist_rev.nil?
90
+ @mapping['control.tags'].each do |tag|
91
+ control['tags'][tag.first.to_s] = row[tag.last] unless row[tag.last].nil?
92
+ end
93
+ unless @mapping['control.tags']['severity'].nil? || row[@mapping['control.tags']['severity']].nil?
94
+ control['impact'] = Utils::InspecUtil.get_impact(row[@mapping['control.tags']['severity']])
95
+ control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
96
+ end
97
+ @controls << control
98
+ end
99
+ end
100
+ end
101
+ end