inspec_tools 2.0.7

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/LICENSE.md +15 -0
  3. data/README.md +373 -0
  4. data/Rakefile +96 -0
  5. data/exe/inspec_tools +14 -0
  6. data/lib/data/README.TXT +25 -0
  7. data/lib/data/U_CCI_List.xml +38403 -0
  8. data/lib/data/attributes.yml +23 -0
  9. data/lib/data/cci2html.xsl +136 -0
  10. data/lib/data/cis_to_nist_critical_controls +0 -0
  11. data/lib/data/cis_to_nist_mapping +0 -0
  12. data/lib/data/mapping.yml +17 -0
  13. data/lib/data/rubocop.yml +4 -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 +216 -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 +125 -0
  37. data/lib/inspec_tools/plugin.rb +15 -0
  38. data/lib/inspec_tools/plugin_cli.rb +275 -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 +156 -0
  42. data/lib/inspec_tools/xlsx_tool.rb +135 -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/cis_to_nist.rb +11 -0
  50. data/lib/utilities/csv_util.rb +14 -0
  51. data/lib/utilities/extract_pdf_text.rb +20 -0
  52. data/lib/utilities/inspec_util.rb +441 -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,216 @@
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 :security_override_guidance, String, tag: 'SecurityOverrideGuidance'
42
+ element :potential_impacts, String, tag: 'PotentialImpacts'
43
+ element :third_party_tools, String, tag: 'ThirdPartyTools'
44
+ element :mitigation_controls, String, tag: 'MitigationControl'
45
+ element :responsibility, String, tag: 'Responsibility'
46
+ element :ia_controls, String, tag: 'IAControls'
47
+ end
48
+
49
+ class Description
50
+ include HappyMapper
51
+ tag 'description'
52
+
53
+ content :details, DescriptionDetails
54
+
55
+ detail_tags = %i(vuln_discussion false_positives false_negatives documentable
56
+ mitigations severity_override_guidance potential_impacts
57
+ third_party_tools mitigation_controls responsibility ia_controls
58
+ security_override_guidance)
59
+
60
+ detail_tags.each do |name|
61
+ define_method name do
62
+ details.send(name)
63
+ end
64
+ end
65
+ end
66
+
67
+ class ReferenceInfo
68
+ include HappyMapper
69
+ tag 'reference'
70
+
71
+ attribute :href, String, tag: 'href'
72
+ element :dc_publisher, String, tag: 'publisher', namespace: 'dc'
73
+ element :dc_source, String, tag: 'source', namespace: 'dc'
74
+ element :dc_title, String, tag: 'title', namespace: 'dc'
75
+ element :dc_type, String, tag: 'type', namespace: 'dc'
76
+ element :dc_subject, String, tag: 'subject', namespace: 'dc'
77
+ element :dc_identifier, String, tag: 'identifier', namespace: 'dc'
78
+ end
79
+
80
+ class Rule
81
+ include HappyMapper
82
+ tag 'Rule'
83
+
84
+ attribute :id, String, tag: 'id'
85
+ attribute :severity, String, tag: 'severity'
86
+ element :version, String, tag: 'version'
87
+ element :title, String, tag: 'title'
88
+ has_one :description, Description, tag: 'description'
89
+ element :reference, ReferenceInfo, tag: 'reference'
90
+ has_many :idents, String, tag: 'ident'
91
+ element :fixtext, String, tag: 'fixtext'
92
+ has_one :fix, Fix, tag: 'fix'
93
+ has_one :check, Check, tag: 'check'
94
+ end
95
+
96
+ class Group
97
+ include HappyMapper
98
+ tag 'Group'
99
+
100
+ attribute :id, String, tag: 'id'
101
+ element :title, String, tag: 'title'
102
+ element :description, String, tag: 'description'
103
+ has_one :rule, Rule, tag: 'Rule'
104
+ end
105
+
106
+ class ReleaseDate
107
+ include HappyMapper
108
+ tag 'status'
109
+
110
+ attribute :release_date, String, tag: 'date'
111
+ end
112
+
113
+ class Notice
114
+ include HappyMapper
115
+ tag 'notice'
116
+ attribute :id, String, tag: 'id'
117
+ attribute :xml_lang, String, namespace: 'xml', tag: 'lang'
118
+ content :notice, String, tag: 'notice'
119
+ end
120
+
121
+ class Plaintext
122
+ include HappyMapper
123
+ tag 'plain-text'
124
+ attribute :id, String, tag: 'id'
125
+ content :plaintext, String
126
+ end
127
+
128
+ class Benchmark
129
+ include HappyMapper
130
+ tag 'Benchmark'
131
+
132
+ has_one :release_date, ReleaseDate, tag: 'status'
133
+ attribute :id, String, tag: 'id'
134
+ element :status, String, tag: 'status'
135
+ element :title, String, tag: 'title'
136
+ element :description, String, tag: 'description'
137
+ element :version, String, tag: 'version'
138
+ element :notice, Notice, tag: 'notice'
139
+ has_one :reference, ReferenceInfo, tag: 'reference'
140
+ element :plaintext, Plaintext, tag: 'plain-text'
141
+ has_many :group, Group, tag: 'Group'
142
+ end
143
+
144
+ class DescriptionDetailsType
145
+ class << self
146
+ def type
147
+ DescriptionDetails
148
+ end
149
+
150
+ def apply(value)
151
+ value = value.gsub('&', 'and')
152
+ DescriptionDetails.parse "<Details>#{value}</Details>"
153
+ rescue Nokogiri::XML::SyntaxError => e
154
+ if e.to_s.include?('StartTag')
155
+ report_invalid_start_tag(value, e)
156
+ else
157
+ report_disallowed_tags(value)
158
+ end
159
+ end
160
+
161
+ def apply?(value, _convert_to_type)
162
+ value.is_a?(String)
163
+ end
164
+
165
+ private
166
+
167
+ def report_invalid_start_tag(value, error)
168
+ puts error.to_s.colorize(:red)
169
+ column = error.column - '<Details>'.length - 2
170
+ puts "Error around #{value[column-10..column+10].colorize(:light_yellow)}"
171
+ exit(1)
172
+ end
173
+
174
+ def report_disallowed_tags(value)
175
+ allowed_tags = %w{VulnDiscussion FalsePositives FalseNegatives Documentable
176
+ Mitigations SeverityOverrideGuidance PotentialImpacts
177
+ PotentialImpacts ThirdPartyTools MitigationControl
178
+ Responsibility IAControl SecurityOverrideGuidance}
179
+
180
+ tags_found = value.scan(%r{(?<=<)([^\/]*?)((?= \/>)|(?=>))}).to_a
181
+
182
+ tags_found = tags_found.uniq.flatten.reject!(&:empty?)
183
+ offending_tags = tags_found - allowed_tags
184
+
185
+ if offending_tags.count > 1
186
+ puts "\n\nThe non-standard tags: #{offending_tags.to_s.colorize(:red)}" \
187
+ ' were found in: ' + "\n\n#{value}"
188
+ else
189
+ puts "\n\nThe non-standard tag: #{offending_tags.to_s.colorize(:red)}" \
190
+ ' was found in: ' + "\n\n#{value}"
191
+ end
192
+ puts "\n\nPlease:\n "
193
+ option_one = '(1) ' + '(best)'.colorize(:green) + ' Use the ' +
194
+ '`-r --replace-tags array` '.colorize(:light_yellow) +
195
+ '(case sensitive) option to replace the offending tags ' \
196
+ 'during processing of the XCCDF ' \
197
+ 'file to use the ' +
198
+ "`$#{offending_tags[0]}` " .colorize(:light_green) +
199
+ 'syntax in your InSpec profile.'
200
+ option_two = '(2) Update your XCCDF file to *not use* non-standard XCCDF ' \
201
+ 'elements within ' +
202
+ '`&lt;`,`&gt;`, `<` '.colorize(:red) +
203
+ 'or '.colorize(:default) +
204
+ '`>` '.colorize(:red) +
205
+ 'as "placeholders", and use something that doesn\'t confuse ' \
206
+ 'the XML parser, such as : ' +
207
+ "`$#{offending_tags[0]}`" .colorize(:light_green)
208
+ puts option_one
209
+ puts "\n"
210
+ puts option_two
211
+ end
212
+ end
213
+ HappyMapper::SupportedTypes.register DescriptionDetailsType
214
+ end
215
+ end
216
+ 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?