inspec_tools 0.0.0.1.ENOTAG → 1.2.0
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +12 -657
- data/Guardfile +4 -0
- data/README.md +65 -132
- data/Rakefile +0 -6
- data/exe/inspec_tools +1 -1
- data/lib/data/README.TXT +1 -1
- data/lib/data/debug_text +5941 -0
- data/lib/happy_mapper_tools/cci_attributes.rb +22 -12
- data/lib/happy_mapper_tools/stig_checklist.rb +1 -6
- data/lib/inspec_tools.rb +2 -1
- data/lib/inspec_tools/cli.rb +140 -24
- data/lib/inspec_tools/command.rb +50 -0
- data/lib/inspec_tools/csv.rb +4 -6
- data/lib/inspec_tools/help/summary.md +2 -2
- data/lib/inspec_tools/inspec.rb +34 -133
- data/lib/inspec_tools/pdf.rb +2 -3
- data/lib/inspec_tools/summary.rb +2 -2
- data/lib/inspec_tools/version.rb +1 -6
- data/lib/inspec_tools/xccdf.rb +8 -22
- data/lib/utilities/inspec_util.rb +59 -208
- data/test/unit/inspec_tools/csv_test.rb +30 -0
- data/test/unit/inspec_tools/inspec_test.rb +54 -0
- data/test/unit/inspec_tools/pdf_test.rb +24 -0
- data/test/unit/inspec_tools/summary_test.rb +42 -0
- data/test/unit/inspec_tools/xccdf_test.rb +50 -0
- data/test/unit/inspec_tools_test.rb +7 -0
- data/test/unit/test_helper.rb +5 -0
- data/test/unit/utils/inspec_util_test.rb +43 -0
- metadata +70 -125
- data/lib/data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx +0 -0
- data/lib/exceptions/impact_input_error.rb +0 -6
- data/lib/exceptions/severity_input_error.rb +0 -6
- data/lib/inspec_tools/plugin.rb +0 -15
- data/lib/inspec_tools/plugin_cli.rb +0 -278
- data/lib/inspec_tools/xlsx_tool.rb +0 -148
- data/lib/inspec_tools_plugin.rb +0 -7
- data/lib/overrides/false_class.rb +0 -5
- data/lib/overrides/nil_class.rb +0 -5
- data/lib/overrides/object.rb +0 -5
- data/lib/overrides/string.rb +0 -5
- data/lib/overrides/true_class.rb +0 -5
data/lib/inspec_tools/pdf.rb
CHANGED
@@ -65,7 +65,6 @@ module InspecTools
|
|
65
65
|
control['desc'] = contr[:descr]
|
66
66
|
control['impact'] = Utils::InspecUtil.get_impact('medium')
|
67
67
|
control['tags'] = {}
|
68
|
-
control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
|
69
68
|
control['tags']['ref'] = contr[:ref] unless contr[:ref].nil?
|
70
69
|
control['tags']['applicability'] = contr[:applicability] unless contr[:applicability].nil?
|
71
70
|
control['tags']['cis_id'] = contr[:title].split(' ')[0] unless contr[:title].nil?
|
@@ -92,8 +91,8 @@ module InspecTools
|
|
92
91
|
@profile['supports'] = []
|
93
92
|
@profile['attributes'] = []
|
94
93
|
@profile['generator'] = {
|
95
|
-
'name': '
|
96
|
-
'version':
|
94
|
+
'name': 'inspec',
|
95
|
+
'version': Gem.loaded_specs['inspec'].version
|
97
96
|
}
|
98
97
|
end
|
99
98
|
|
data/lib/inspec_tools/summary.rb
CHANGED
@@ -26,7 +26,7 @@ module InspecTools
|
|
26
26
|
@summary = {}
|
27
27
|
@data.keys.each do |control_id|
|
28
28
|
current_control = @data[control_id]
|
29
|
-
current_control[:compliance_status] = Utils::InspecUtil.control_status(current_control
|
29
|
+
current_control[:compliance_status] = Utils::InspecUtil.control_status(current_control)
|
30
30
|
current_control[:finding_details] = Utils::InspecUtil.control_finding_details(current_control, current_control[:compliance_status])
|
31
31
|
end
|
32
32
|
compute_summary
|
@@ -48,7 +48,7 @@ module InspecTools
|
|
48
48
|
@summary[:buckets][:passed] = select_by_status(@data, 'NotAFinding')
|
49
49
|
@summary[:buckets][:no_impact] = select_by_status(@data, 'Not_Applicable')
|
50
50
|
@summary[:buckets][:skipped] = select_by_status(@data, 'Not_Reviewed')
|
51
|
-
@summary[:buckets][:error] = select_by_status(@data, '
|
51
|
+
@summary[:buckets][:error] = select_by_status(@data, 'Not_Tested')
|
52
52
|
|
53
53
|
@summary[:status] = {}
|
54
54
|
@summary[:status][:failed] = tally_by_impact(@summary[:buckets][:failed])
|
data/lib/inspec_tools/version.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require 'git-version-bump'
|
2
|
-
|
3
1
|
module InspecTools
|
4
|
-
|
5
|
-
# Lite tags are tags that are used by GitHub releases that do not contain
|
6
|
-
# annotations
|
7
|
-
VERSION = GVB.version(false, true)
|
2
|
+
VERSION = '1.2.0'.freeze
|
8
3
|
end
|
data/lib/inspec_tools/xccdf.rb
CHANGED
@@ -3,7 +3,6 @@ require_relative '../happy_mapper_tools/cci_attributes'
|
|
3
3
|
require_relative '../utilities/inspec_util'
|
4
4
|
|
5
5
|
require 'digest'
|
6
|
-
require 'json'
|
7
6
|
|
8
7
|
module InspecTools
|
9
8
|
# rubocop:disable Metrics/ClassLength
|
@@ -80,13 +79,6 @@ module InspecTools
|
|
80
79
|
@benchmark.release_date.release_date
|
81
80
|
end
|
82
81
|
|
83
|
-
def inject_metadata(metadata = '{}')
|
84
|
-
json_metadata = JSON.parse(metadata)
|
85
|
-
json_metadata.each do |key, value|
|
86
|
-
@profile[key] = value
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
82
|
private
|
91
83
|
|
92
84
|
def replace_tags_in_xccdf(replace_tags, xccdf_xml)
|
@@ -97,25 +89,20 @@ module InspecTools
|
|
97
89
|
end
|
98
90
|
|
99
91
|
def insert_json_metadata
|
100
|
-
@profile['name'] = @benchmark.
|
92
|
+
@profile['name'] = @benchmark.title
|
101
93
|
@profile['title'] = @benchmark.title
|
102
|
-
@profile['maintainer'] = 'The Authors'
|
103
|
-
@profile['copyright'] = 'The Authors'
|
104
|
-
@profile['copyright_email'] = 'you@example.com'
|
105
|
-
@profile['license'] = 'Apache-2.0'
|
94
|
+
@profile['maintainer'] = 'The Authors'
|
95
|
+
@profile['copyright'] = 'The Authors'
|
96
|
+
@profile['copyright_email'] = 'you@example.com'
|
97
|
+
@profile['license'] = 'Apache-2.0'
|
106
98
|
@profile['summary'] = "\"#{@benchmark.description.gsub('\\', '\\\\\\').gsub('"', '\"')}\""
|
107
|
-
@profile['version'] = '0.1.0'
|
99
|
+
@profile['version'] = '0.1.0'
|
108
100
|
@profile['supports'] = []
|
109
101
|
@profile['attributes'] = []
|
110
102
|
@profile['generator'] = {
|
111
|
-
'name': '
|
112
|
-
'version':
|
103
|
+
'name': 'inspec',
|
104
|
+
'version': Gem.loaded_specs['inspec'].version
|
113
105
|
}
|
114
|
-
@profile['plaintext'] = @benchmark.plaintext.plaintext
|
115
|
-
@profile['status'] = "#{@benchmark.status} on #{@benchmark.release_date.release_date}"
|
116
|
-
@profile['reference_href'] = @benchmark.reference.href
|
117
|
-
@profile['reference_publisher'] = @benchmark.reference.dc_publisher
|
118
|
-
@profile['reference_source'] = @benchmark.reference.dc_source
|
119
106
|
end
|
120
107
|
|
121
108
|
def insert_controls
|
@@ -126,7 +113,6 @@ module InspecTools
|
|
126
113
|
control['desc'] = group.rule.description.vuln_discussion.split('Satisfies: ')[0]
|
127
114
|
control['impact'] = Utils::InspecUtil.get_impact(group.rule.severity)
|
128
115
|
control['tags'] = {}
|
129
|
-
control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
|
130
116
|
control['tags']['gtitle'] = group.title
|
131
117
|
control['tags']['satisfies'] = group.rule.description.vuln_discussion.split('Satisfies: ')[1].split(',').map(&:strip) if group.rule.description.vuln_discussion.split('Satisfies: ').length > 1
|
132
118
|
control['tags']['gid'] = group.id
|
@@ -1,34 +1,18 @@
|
|
1
|
-
require 'inspec
|
1
|
+
require 'inspec/objects'
|
2
2
|
require 'word_wrap'
|
3
3
|
require 'pp'
|
4
|
-
require 'uri'
|
5
|
-
require 'net/http'
|
6
|
-
require 'fileutils'
|
7
|
-
require 'exceptions/impact_input_error'
|
8
|
-
require 'exceptions/severity_input_error'
|
9
|
-
require 'overrides/false_class'
|
10
|
-
require 'overrides/true_class'
|
11
|
-
require 'overrides/nil_class'
|
12
|
-
require 'overrides/object'
|
13
|
-
require 'overrides/string'
|
14
4
|
|
15
5
|
# rubocop:disable Metrics/ClassLength
|
16
6
|
# rubocop:disable Metrics/AbcSize
|
17
7
|
# rubocop:disable Metrics/PerceivedComplexity
|
18
8
|
# rubocop:disable Metrics/CyclomaticComplexity
|
9
|
+
# rubocop:disable Metrics/BlockLength
|
19
10
|
# rubocop:disable Metrics/MethodLength
|
20
11
|
|
21
12
|
module Utils
|
22
13
|
class InspecUtil
|
23
14
|
DATA_NOT_FOUND_MESSAGE = 'N/A'.freeze
|
24
15
|
WIDTH = 80
|
25
|
-
IMPACT_SCORES = {
|
26
|
-
'none' => 0.0,
|
27
|
-
'low' => 0.1,
|
28
|
-
'medium' => 0.4,
|
29
|
-
'high' => 0.7,
|
30
|
-
'critical' => 0.9
|
31
|
-
}.freeze
|
32
16
|
|
33
17
|
def self.parse_data_for_xccdf(json)
|
34
18
|
data = {}
|
@@ -45,7 +29,7 @@ module Utils
|
|
45
29
|
end
|
46
30
|
c_data = {}
|
47
31
|
|
48
|
-
controls.each do |control|
|
32
|
+
controls.each do |control| # rubocop:disable Metrics/BlockLength
|
49
33
|
c_id = control['id'].to_sym
|
50
34
|
c_data[c_id] = {}
|
51
35
|
c_data[c_id]['id'] = control['id'] || DATA_NOT_FOUND_MESSAGE
|
@@ -87,11 +71,9 @@ module Utils
|
|
87
71
|
profile['controls'].each do |control|
|
88
72
|
c_id = control['id'].to_sym
|
89
73
|
data[c_id] = {}
|
90
|
-
|
91
74
|
data[c_id][:vuln_num] = control['id'] unless control['id'].nil?
|
92
75
|
data[c_id][:rule_title] = control['title'] unless control['title'].nil?
|
93
76
|
data[c_id][:vuln_discuss] = control['desc'] unless control['desc'].nil?
|
94
|
-
|
95
77
|
unless control['tags'].nil?
|
96
78
|
data[c_id][:severity] = control['tags']['severity'] unless control['tags']['severity'].nil?
|
97
79
|
data[c_id][:gid] = control['tags']['gid'] unless control['tags']['gid'].nil?
|
@@ -100,45 +82,31 @@ module Utils
|
|
100
82
|
data[c_id][:rule_ver] = control['tags']['stig_id'] unless control['tags']['stig_id'].nil?
|
101
83
|
data[c_id][:cci_ref] = control['tags']['cci'] unless control['tags']['cci'].nil?
|
102
84
|
data[c_id][:nist] = control['tags']['nist'].join(' ') unless control['tags']['nist'].nil?
|
85
|
+
data[c_id][:check_content] = control['tags']['check'] unless control['tags']['check'].nil?
|
86
|
+
data[c_id][:fix_text] = control['tags']['fix'] unless control['tags']['fix'].nil?
|
103
87
|
end
|
104
|
-
|
105
|
-
if control['descriptions'].respond_to?(:find)
|
106
|
-
data[c_id][:check_content] = control['descriptions'].find { |c| c['label'] == 'fix' }&.dig('data')
|
107
|
-
data[c_id][:fix_text] = control['descriptions'].find { |c| c['label'] == 'check' }&.dig('data')
|
108
|
-
end
|
109
|
-
|
110
88
|
data[c_id][:impact] = control['impact'].to_s unless control['impact'].nil?
|
111
89
|
data[c_id][:profile_name] = profile['name'].to_s unless profile['name'].nil?
|
112
90
|
data[c_id][:profile_shasum] = profile['sha256'].to_s unless profile['sha256'].nil?
|
113
91
|
|
114
92
|
data[c_id][:status] = []
|
115
93
|
data[c_id][:message] = []
|
116
|
-
|
117
94
|
if control.key?('results')
|
118
95
|
control['results'].each do |result|
|
119
|
-
if !result['backtrace'].nil?
|
120
|
-
result['status'] = 'error'
|
121
|
-
end
|
122
96
|
data[c_id][:status].push(result['status'])
|
123
|
-
data[c_id][:message].push(
|
97
|
+
data[c_id][:message].push(result['skip_message']) if result['status'] == 'skipped'
|
124
98
|
data[c_id][:message].push("FAILED -- Test: #{result['code_desc']}\nMessage: #{result['message']}\n") if result['status'] == 'failed'
|
125
99
|
data[c_id][:message].push("PASS -- #{result['code_desc']}\n") if result['status'] == 'passed'
|
126
|
-
data[c_id][:message].push("PROFILE_ERROR -- Test: #{result['code_desc']}\nMessage: #{result['backtrace']}\n") if result['status'] == 'error'
|
127
100
|
end
|
128
101
|
end
|
129
|
-
|
130
102
|
if data[c_id][:impact].to_f.zero?
|
131
|
-
data[c_id][:message]
|
103
|
+
data[c_id][:message] = control['desc']
|
132
104
|
end
|
133
105
|
end
|
134
106
|
end
|
135
107
|
data
|
136
108
|
end
|
137
109
|
|
138
|
-
def self.get_platform(json)
|
139
|
-
json['profiles'].find { |profile| !profile[:platform].nil? }
|
140
|
-
end
|
141
|
-
|
142
110
|
def self.to_dotted_hash(hash, recursive_key = '')
|
143
111
|
hash.each_with_object({}) do |(k, v), ret|
|
144
112
|
key = recursive_key + k.to_s
|
@@ -150,28 +118,29 @@ module Utils
|
|
150
118
|
end
|
151
119
|
end
|
152
120
|
|
153
|
-
def self.control_status(control
|
121
|
+
def self.control_status(control)
|
154
122
|
status_list = control[:status].uniq
|
155
|
-
if
|
156
|
-
'
|
157
|
-
elsif status_list.include?('
|
158
|
-
'
|
123
|
+
if status_list.include?('failed')
|
124
|
+
result = 'Open'
|
125
|
+
elsif status_list.include?('skipped')
|
126
|
+
result = 'Not_Reviewed'
|
159
127
|
elsif status_list.include?('passed')
|
160
|
-
'NotAFinding'
|
161
|
-
elsif status_list.include?('error') && for_summary
|
162
|
-
'Profile_Error'
|
128
|
+
result = 'NotAFinding'
|
163
129
|
else
|
164
|
-
|
165
|
-
|
130
|
+
result = 'Not_Tested'
|
131
|
+
end
|
132
|
+
if control[:impact].to_f.zero?
|
133
|
+
result = 'Not_Applicable'
|
166
134
|
end
|
135
|
+
result
|
167
136
|
end
|
168
137
|
|
169
138
|
def self.control_finding_details(control, control_clk_status)
|
170
139
|
result = "One or more of the automated tests failed or was inconclusive for the control \n\n #{control[:message].sort.join}" if control_clk_status == 'Open'
|
171
140
|
result = "All Automated tests passed for the control \n\n #{control[:message].join}" if control_clk_status == 'NotAFinding'
|
172
141
|
result = "Automated test skipped due to known accepted condition in the control : \n\n#{control[:message].join}" if control_clk_status == 'Not_Reviewed'
|
173
|
-
result = "Justification: \n #{control[:message].join}" if control_clk_status == 'Not_Applicable'
|
174
|
-
result = 'No test available
|
142
|
+
result = "Justification: \n #{control[:message].split.join(' ')}" if control_clk_status == 'Not_Applicable'
|
143
|
+
result = 'No test available for this control' if control_clk_status == 'Not_Tested'
|
175
144
|
result
|
176
145
|
end
|
177
146
|
|
@@ -191,81 +160,19 @@ module Utils
|
|
191
160
|
# @todo Allow for the user to pass in a hash for the desired mapping of text
|
192
161
|
# values to numbers or to override our hard coded values.
|
193
162
|
#
|
194
|
-
def self.get_impact(severity
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
'1.0 or one of the approved keywords.'
|
201
|
-
end
|
202
|
-
|
203
|
-
private_class_method def self.float_to_impact(severity, use_cvss_terms)
|
204
|
-
unless severity.between?(0, 1)
|
205
|
-
raise SeverityInputError, "'#{severity}' is not a valid severity value. It should be a Float between 0.0 and " \
|
206
|
-
'1.0 or one of the approved keywords.'
|
207
|
-
end
|
208
|
-
|
209
|
-
if severity <= 0.01
|
210
|
-
0.0 # Informative
|
211
|
-
elsif severity < 0.4
|
212
|
-
0.3 # Low Impact
|
213
|
-
elsif severity < 0.7
|
214
|
-
0.5 # Medium Impact
|
215
|
-
elsif severity < 0.9 || use_cvss_terms
|
216
|
-
0.7 # High Impact
|
217
|
-
else
|
218
|
-
1.0 # Critical Controls
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
private_class_method def self.string_to_impact(severity, use_cvss_terms)
|
223
|
-
if /none|na|n\/a|not[_|(\s*)]?applicable/i.match?(severity)
|
224
|
-
impact = 0.0 # Informative
|
225
|
-
elsif /low|cat(egory)?\s*(iii|3)/i.match?(severity)
|
226
|
-
impact = 0.3 # Low Impact
|
227
|
-
elsif /med(ium)?|cat(egory)?\s*(ii|2)/i.match?(severity)
|
228
|
-
impact = 0.5 # Medium Impact
|
229
|
-
elsif /high|cat(egory)?\s*(i|1)/i.match?(severity)
|
230
|
-
impact = 0.7 # High Impact
|
231
|
-
elsif /crit(ical)?|severe/i.match?(severity)
|
232
|
-
impact = 1.0 # Critical Controls
|
233
|
-
else
|
234
|
-
raise SeverityInputError, "'#{severity}' is not a valid severity value. It should be a Float between 0.0 and " \
|
235
|
-
'1.0 or one of the approved keywords.'
|
236
|
-
end
|
237
|
-
|
238
|
-
impact == 1.0 && use_cvss_terms ? 0.7 : impact
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.get_impact_string(impact, use_cvss_terms: true)
|
242
|
-
return if impact.nil?
|
243
|
-
|
244
|
-
value = impact.to_f
|
245
|
-
unless value.between?(0, 1)
|
246
|
-
raise ImpactInputError, "'#{value}' is not a valid impact score. Valid impact scores: [0.0 - 1.0]."
|
247
|
-
end
|
248
|
-
|
249
|
-
IMPACT_SCORES.reverse_each do |name, impact_score|
|
250
|
-
if name == 'critical' && value >= impact_score && use_cvss_terms
|
251
|
-
return 'high'
|
252
|
-
elsif value >= impact_score
|
253
|
-
return name
|
254
|
-
else
|
255
|
-
next
|
256
|
-
end
|
163
|
+
def self.get_impact(severity)
|
164
|
+
case severity
|
165
|
+
when 'low' then 0.3
|
166
|
+
when 'medium' then 0.5
|
167
|
+
when 'high' then 0.7
|
168
|
+
else severity
|
257
169
|
end
|
258
170
|
end
|
259
171
|
|
260
172
|
def self.unpack_inspec_json(directory, inspec_json, separated, output_format)
|
261
|
-
if directory == 'id'
|
262
|
-
directory = inspec_json['name']
|
263
|
-
end
|
264
173
|
controls = generate_controls(inspec_json)
|
265
174
|
unpack_profile(directory || 'profile', controls, separated, output_format || 'json')
|
266
175
|
create_inspec_yml(directory || 'profile', inspec_json)
|
267
|
-
create_license(directory || 'profile', inspec_json)
|
268
|
-
create_readme_md(directory || 'profile', inspec_json)
|
269
176
|
end
|
270
177
|
|
271
178
|
private_class_method def self.wrap(str, width = WIDTH)
|
@@ -279,46 +186,35 @@ module Utils
|
|
279
186
|
private_class_method def self.generate_controls(inspec_json)
|
280
187
|
controls = []
|
281
188
|
inspec_json['controls'].each do |json_control|
|
282
|
-
control =
|
189
|
+
control = Inspec::Control.new
|
283
190
|
if (defined? control.desc).nil?
|
284
191
|
control.descriptions[:default] = json_control['desc']
|
285
|
-
control.descriptions[:rationale] = json_control['tags']['rationale']
|
286
|
-
control.descriptions[:check] = json_control['tags']['check']
|
287
|
-
control.descriptions[:fix] = json_control['tags']['fix']
|
288
192
|
else
|
289
193
|
control.desc = json_control['desc']
|
290
194
|
end
|
291
195
|
control.id = json_control['id']
|
292
196
|
control.title = json_control['title']
|
293
197
|
control.impact = get_impact(json_control['impact'])
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
control.add_tag(
|
300
|
-
control.add_tag(
|
301
|
-
control.add_tag(
|
302
|
-
control.add_tag(
|
303
|
-
control.add_tag(
|
304
|
-
control.add_tag(
|
305
|
-
control.add_tag(
|
306
|
-
control.add_tag(
|
307
|
-
control.add_tag(
|
308
|
-
control.add_tag(
|
309
|
-
control.add_tag(
|
310
|
-
control.add_tag(
|
311
|
-
control.add_tag(
|
312
|
-
control.add_tag(
|
313
|
-
control.add_tag(
|
314
|
-
control.add_tag(::Inspec::Object::Tag.new('documentable', json_control['tags']['documentable'])) unless json_control['tags']['documentable'].blank?
|
315
|
-
control.add_tag(::Inspec::Object::Tag.new('mitigations', json_control['tags']['mitigations'])) unless json_control['tags']['mitigations'].blank?
|
316
|
-
control.add_tag(::Inspec::Object::Tag.new('severity_override_guidance', json_control['tags']['severity_override_guidance'])) unless json_control['tags']['severity_override_guidance'].blank?
|
317
|
-
control.add_tag(::Inspec::Object::Tag.new('potential_impacts', json_control['tags']['potential_impacts'])) unless json_control['tags']['potential_impacts'].blank?
|
318
|
-
control.add_tag(::Inspec::Object::Tag.new('third_party_tools', json_control['tags']['third_party_tools'])) unless json_control['tags']['third_party_tools'].blank?
|
319
|
-
control.add_tag(::Inspec::Object::Tag.new('mitigation_controls', json_control['tags']['mitigation_controls'])) unless json_control['tags']['mitigation_controls'].blank?
|
320
|
-
control.add_tag(::Inspec::Object::Tag.new('responsibility', json_control['tags']['responsibility'])) unless json_control['tags']['responsibility'].blank?
|
321
|
-
control.add_tag(::Inspec::Object::Tag.new('ia_controls', json_control['tags']['ia_controls'])) unless json_control['tags']['ia_controls'].blank?
|
198
|
+
control.add_tag(Inspec::Tag.new('gtitle', json_control['tags']['gtitle']))
|
199
|
+
control.add_tag(Inspec::Tag.new('satisfies', json_control['tags']['satisfies'])) if json_control['tags']['satisfies']
|
200
|
+
control.add_tag(Inspec::Tag.new('gid', json_control['tags']['gid']))
|
201
|
+
control.add_tag(Inspec::Tag.new('rid', json_control['tags']['rid']))
|
202
|
+
control.add_tag(Inspec::Tag.new('stig_id', json_control['tags']['stig_id']))
|
203
|
+
control.add_tag(Inspec::Tag.new('fix_id', json_control['tags']['fix_id']))
|
204
|
+
control.add_tag(Inspec::Tag.new('cci', json_control['tags']['cci']))
|
205
|
+
control.add_tag(Inspec::Tag.new('nist', json_control['tags']['nist']))
|
206
|
+
control.add_tag(Inspec::Tag.new('false_negatives', json_control['tags']['false_negatives'])) if json_control['tags']['false_positives'] != ''
|
207
|
+
control.add_tag(Inspec::Tag.new('false_positives', json_control['tags']['false_positives'])) if json_control['tags']['false_positives'] != ''
|
208
|
+
control.add_tag(Inspec::Tag.new('documentable', json_control['tags']['documentable'])) if json_control['tags']['documentable'] != ''
|
209
|
+
control.add_tag(Inspec::Tag.new('mitigations', json_control['tags']['mitigations'])) if json_control['tags']['mitigations'] != ''
|
210
|
+
control.add_tag(Inspec::Tag.new('severity_override_guidance', json_control['tags']['documentable'])) if json_control['tags']['severity_override_guidance'] != ''
|
211
|
+
control.add_tag(Inspec::Tag.new('potential_impacts', json_control['tags']['potential_impacts'])) if json_control['tags']['potential_impacts'] != ''
|
212
|
+
control.add_tag(Inspec::Tag.new('third_party_tools', json_control['tags']['third_party_tools'])) if json_control['tags']['third_party_tools'] != ''
|
213
|
+
control.add_tag(Inspec::Tag.new('mitigation_controls', json_control['tags']['mitigation_controls'])) if json_control['tags']['mitigation_controls'] != ''
|
214
|
+
control.add_tag(Inspec::Tag.new('responsibility', json_control['tags']['responsibility'])) if json_control['tags']['responsibility'] != ''
|
215
|
+
control.add_tag(Inspec::Tag.new('ia_controls', json_control['tags']['ia_controls'])) if json_control['tags']['ia_controls'] != ''
|
216
|
+
control.add_tag(Inspec::Tag.new('check', json_control['tags']['check']))
|
217
|
+
control.add_tag(Inspec::Tag.new('fix', json_control['tags']['fix']))
|
322
218
|
|
323
219
|
controls << control
|
324
220
|
end
|
@@ -330,70 +226,32 @@ module Utils
|
|
330
226
|
#
|
331
227
|
private_class_method def self.create_inspec_yml(directory, inspec_json)
|
332
228
|
benchmark_info =
|
333
|
-
"name: #{inspec_json['name']}
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
229
|
+
"name: #{inspec_json['name']}
|
230
|
+
title: #{inspec_json['title']}
|
231
|
+
maintainer: #{inspec_json['maintainer']}
|
232
|
+
copyright: #{inspec_json['copyright']}
|
233
|
+
copyright_email: #{inspec_json['copyright_email']}
|
234
|
+
license: #{inspec_json['license']}
|
235
|
+
summary: #{inspec_json['summary']}
|
236
|
+
version: #{inspec_json['version']}"
|
341
237
|
|
342
238
|
myfile = File.new("#{directory}/inspec.yml", 'w')
|
343
239
|
myfile.puts benchmark_info
|
344
240
|
end
|
345
241
|
|
346
|
-
private_class_method def self.create_license(directory, inspec_json)
|
347
|
-
license_content = ''
|
348
|
-
if !inspec_json['license'].nil?
|
349
|
-
begin
|
350
|
-
response = Net::HTTP.get_response(URI(inspec_json['license']))
|
351
|
-
if response.code == '200'
|
352
|
-
license_content = response.body
|
353
|
-
else
|
354
|
-
license_content = inspec_json['license']
|
355
|
-
end
|
356
|
-
rescue StandardError => _e
|
357
|
-
license_content = inspec_json['license']
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
myfile = File.new("#{directory}/LICENSE", 'w')
|
362
|
-
myfile.puts license_content
|
363
|
-
end
|
364
|
-
|
365
|
-
private_class_method def self.create_readme_md(directory, inspec_json)
|
366
|
-
readme_contents =
|
367
|
-
"\# #{inspec_json['title']}\n" \
|
368
|
-
"#{inspec_json['summary']}\n" \
|
369
|
-
"---\n" \
|
370
|
-
"Name: #{inspec_json['name']}\n" \
|
371
|
-
"Author: #{inspec_json['maintainer']}\n" \
|
372
|
-
"Status: #{inspec_json['status']}\n" \
|
373
|
-
"Copyright: #{inspec_json['copyright']}\n" \
|
374
|
-
"Copyright Email: #{inspec_json['copyright_email']}\n" \
|
375
|
-
"Version: #{inspec_json['version']}\n" \
|
376
|
-
"#{inspec_json['plaintext']}\n" \
|
377
|
-
"Reference: #{inspec_json['reference_href']}\n" \
|
378
|
-
"Reference by: #{inspec_json['reference_publisher']}\n" \
|
379
|
-
"Reference source: #{inspec_json['reference_source']}\n"
|
380
|
-
|
381
|
-
myfile = File.new("#{directory}/README.md", 'w')
|
382
|
-
myfile.puts readme_contents
|
383
|
-
end
|
384
|
-
|
385
242
|
private_class_method def self.unpack_profile(directory, controls, separated, output_format)
|
386
243
|
FileUtils.rm_rf(directory) if Dir.exist?(directory)
|
387
244
|
Dir.mkdir directory unless Dir.exist?(directory)
|
388
245
|
Dir.mkdir "#{directory}/controls" unless Dir.exist?("#{directory}/controls")
|
389
246
|
Dir.mkdir "#{directory}/libraries" unless Dir.exist?("#{directory}/libraries")
|
247
|
+
myfile = File.new("#{directory}/README.md", 'w')
|
248
|
+
myfile.puts "# Example InSpec Profile\n\nthis example shows the implementation of an InSpec profile."
|
390
249
|
if separated
|
391
250
|
if output_format == 'ruby'
|
392
251
|
controls.each do |control|
|
393
252
|
file_name = control.id.to_s
|
394
253
|
myfile = File.new("#{directory}/controls/#{file_name}.rb", 'w')
|
395
|
-
myfile.puts
|
396
|
-
myfile.puts wrap(control.to_ruby.gsub('"', "\'"), WIDTH) + "\n"
|
254
|
+
myfile.puts wrap(control.to_ruby, WIDTH) + "\n"
|
397
255
|
myfile.close
|
398
256
|
end
|
399
257
|
else
|
@@ -408,8 +266,7 @@ module Utils
|
|
408
266
|
myfile = File.new("#{directory}/controls/controls.rb", 'w')
|
409
267
|
if output_format == 'ruby'
|
410
268
|
controls.each do |control|
|
411
|
-
myfile.puts
|
412
|
-
myfile.puts wrap(control.to_ruby.gsub('"', "\'"), WIDTH) + "\n"
|
269
|
+
myfile.puts wrap(control.to_ruby, WIDTH) + "\n"
|
413
270
|
end
|
414
271
|
else
|
415
272
|
controls.each do |control|
|
@@ -427,9 +284,3 @@ module Utils
|
|
427
284
|
end
|
428
285
|
end
|
429
286
|
end
|
430
|
-
|
431
|
-
# rubocop:enable Metrics/ClassLength
|
432
|
-
# rubocop:enable Metrics/AbcSize
|
433
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
434
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
435
|
-
# rubocop:enable Metrics/MethodLength
|