abide_dev_utils 0.11.2 → 0.12.2
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/abide_dev_utils/cem/generate/reference.rb +7 -2
- data/lib/abide_dev_utils/cem/mapping/mapper.rb +5 -3
- data/lib/abide_dev_utils/cli/jira.rb +22 -0
- data/lib/abide_dev_utils/jira.rb +45 -0
- data/lib/abide_dev_utils/version.rb +1 -1
- data/lib/abide_dev_utils/xccdf.rb +194 -66
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e93a77cf4142b06ee4d41863ef2d0b737d21d37306b57082aa316f2731de5e9
|
4
|
+
data.tar.gz: 9b49e05aa575884d54efed8fd70b5662712845c083a8b59caeccf406a19f5633
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51316ad752020f3b2297acbdc4bb328c5275d03e499721ee12381aaac5da3a6e77ecb9efeb0ffa4b3b6bb512154dbb4b36bf249f4816944a0110d3ceeb871b2b
|
7
|
+
data.tar.gz: 40b83d7be09ccb1349650617548276f6f34e266fe2e590e8c1b28b8e9c44f4499c93652abf9e254d77469fec9c98e9394a1ae2f4b2d3f0921827c3ce302dfb7e
|
data/Gemfile.lock
CHANGED
@@ -120,7 +120,11 @@ module AbideDevUtils
|
|
120
120
|
private
|
121
121
|
|
122
122
|
def heading_builder
|
123
|
-
@
|
123
|
+
if @framework == 'stig'
|
124
|
+
@md.add_h2(@control.id)
|
125
|
+
else
|
126
|
+
@md.add_h2("#{@control.number} - #{@control.title}")
|
127
|
+
end
|
124
128
|
end
|
125
129
|
|
126
130
|
def control_has_valid_params?
|
@@ -216,12 +220,13 @@ module AbideDevUtils
|
|
216
220
|
end
|
217
221
|
return if out_str.empty?
|
218
222
|
|
219
|
-
out_str.unshift(" #{@control.title.dump}:")
|
223
|
+
@control.title.nil? ? out_str.unshift(" #{@control.id.dump}:") : out_str.unshift(" #{@control.title.dump}:")
|
220
224
|
out_str.unshift(' control_configs:')
|
221
225
|
out_str.unshift("#{@module_name}::config:")
|
222
226
|
@md.add_ul('Hiera Configuration Example:')
|
223
227
|
@md.add_code_block(out_str.join("\n"), language: 'yaml')
|
224
228
|
rescue StandardError => e
|
229
|
+
require 'pry'; binding.pry
|
225
230
|
err_msg = [
|
226
231
|
"Failed to generate config example for control #{@control.id}",
|
227
232
|
"Error: #{e.message}",
|
@@ -6,13 +6,13 @@ require 'abide_dev_utils/cem/hiera_data/mapping_data/mixins'
|
|
6
6
|
module AbideDevUtils
|
7
7
|
module CEM
|
8
8
|
module Mapping
|
9
|
-
ALL_TYPES = %w[hiera_title_num number hiera_title vulnid
|
9
|
+
ALL_TYPES = %w[hiera_title_num number hiera_title title vulnid ruleid].freeze
|
10
10
|
FRAMEWORK_TYPES = {
|
11
11
|
'cis' => %w[hiera_title_num number hiera_title title],
|
12
|
-
'stig' => %w[
|
12
|
+
'stig' => %w[vulnid ruleid],
|
13
13
|
}.freeze
|
14
14
|
CIS_TYPES = %w[hiera_title_num number hiera_title title].freeze
|
15
|
-
STIG_TYPES = %w[
|
15
|
+
STIG_TYPES = %w[vulnid ruleid].freeze
|
16
16
|
|
17
17
|
# Represents a single map data file
|
18
18
|
class MapData
|
@@ -168,6 +168,8 @@ module AbideDevUtils
|
|
168
168
|
'hiera_title'
|
169
169
|
when %r{^V-[0-9]{6}$}
|
170
170
|
'vulnid'
|
171
|
+
when %r{^SV-[0-9]+r[0-9]+_rule$}
|
172
|
+
'ruleid'
|
171
173
|
else
|
172
174
|
'title'
|
173
175
|
end
|
@@ -22,6 +22,7 @@ module Abide
|
|
22
22
|
add_command(JiraGetIssueCommand.new)
|
23
23
|
add_command(JiraNewIssueCommand.new)
|
24
24
|
add_command(JiraFromCoverageCommand.new)
|
25
|
+
add_command(JiraFromXccdfCommand.new)
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -113,5 +114,26 @@ module Abide
|
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
117
|
+
|
118
|
+
class JiraFromXccdfCommand < CmdParse::Command
|
119
|
+
CMD_NAME = 'from_xccdf'
|
120
|
+
CMD_SHORT = 'Creates a parent issue with subtasks from a xccdf file'
|
121
|
+
CMD_LONG = 'Creates a parent issue with subtasks for a benchmark and any uncovered controls'
|
122
|
+
def initialize
|
123
|
+
super(CMD_NAME, takes_commands: false)
|
124
|
+
short_desc(CMD_SHORT)
|
125
|
+
long_desc(CMD_LONG)
|
126
|
+
argument_desc(PATH: 'An XCCDF file from the abide puppet ticket coverage command', PROJECT: 'A Jira project')
|
127
|
+
options.on('-d', '--dry-run', 'Print to console instead of saving objects') { |_| @data[:dry_run] = true }
|
128
|
+
end
|
129
|
+
|
130
|
+
def execute(path, project)
|
131
|
+
Abide::CLI::VALIDATE.file(path)
|
132
|
+
@data[:dry_run] = false if @data[:dry_run].nil?
|
133
|
+
client = JIRA.client(options: {})
|
134
|
+
proj = JIRA.project(client, project)
|
135
|
+
JIRA.new_issues_from_xccdf(client, proj, path, dry_run: @data[:dry_run])
|
136
|
+
end
|
137
|
+
end
|
116
138
|
end
|
117
139
|
end
|
data/lib/abide_dev_utils/jira.rb
CHANGED
@@ -135,6 +135,36 @@ module AbideDevUtils
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
+
def self.new_issues_from_xccdf(client, project, xccdf_path, dry_run: false)
|
139
|
+
dr_prefix = dry_run ? 'DRY RUN: ' : ''
|
140
|
+
i_attrs = all_project_issues_attrs(project)
|
141
|
+
|
142
|
+
xccdf = AbideDevUtils::XCCDF::Benchmark.new(xccdf_path)
|
143
|
+
|
144
|
+
summaries = summaries_from_xccdf(xccdf)
|
145
|
+
summaries.each do |profile_summary, control_summaries|
|
146
|
+
if summary_exist?(profile_summary, i_attrs)
|
147
|
+
AbideDevUtils::Output.simple("#{dr_prefix}Skipping #{profile_summary} as it already exists")
|
148
|
+
next
|
149
|
+
end
|
150
|
+
|
151
|
+
parent = new_issue(client, project.attrs['key'], profile_summary, dry_run: dry_run)
|
152
|
+
AbideDevUtils::Output.simple("#{dr_prefix}Created parent issue #{profile_summary}")
|
153
|
+
parent_issue = issue(client, parent.attrs['key']) unless parent.respond_to?(:dummy)
|
154
|
+
AbideDevUtils::Output.simple("#{dr_prefix}Creating subtasks, this can take a while...")
|
155
|
+
progress = AbideDevUtils::Output.progress(title: "#{dr_prefix}Creating Subtasks", total: nil)
|
156
|
+
control_summaries.each do |control_summary|
|
157
|
+
next if summary_exist?(control_summary, i_attrs)
|
158
|
+
|
159
|
+
progress.title = "#{dr_prefix}#{control_summary}"
|
160
|
+
new_subtask(client, parent_issue, control_summary, dry_run: dry_run)
|
161
|
+
progress.increment
|
162
|
+
end
|
163
|
+
final_text = "#{dr_prefix}Created #{control_summaries.count} subtasks for #{profile_summary}"
|
164
|
+
puts "\r\033[K#{final_text}\n"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
138
168
|
# def self.new_issues_from_comply_report(client, project, report, dry_run: false)
|
139
169
|
# dr_prefix = dry_run ? 'DRY RUN: ' : ''
|
140
170
|
# i_attrs = all_project_issues_attrs(project)
|
@@ -177,6 +207,21 @@ module AbideDevUtils
|
|
177
207
|
summaries.transform_keys { |k| "#{COV_PARENT_SUMMARY_PREFIX}#{benchmark}-#{k}"}
|
178
208
|
end
|
179
209
|
|
210
|
+
def self.summaries_from_xccdf(xccdf)
|
211
|
+
summaries = {}
|
212
|
+
facter_os = xccdf.facter_benchmark.join('-')
|
213
|
+
xccdf.profiles.each do |profile|
|
214
|
+
summaries["#{COV_PARENT_SUMMARY_PREFIX}#{facter_os} - #{profile.level} #{profile.title}"] = profile.controls.collect do |control|
|
215
|
+
summary = "#{COV_CHILD_SUMMARY_PREFIX}#{control.vulnid} - #{control.title}"
|
216
|
+
if summary.length > 255
|
217
|
+
summary = summary[0..251] + '...'
|
218
|
+
end
|
219
|
+
summary
|
220
|
+
end
|
221
|
+
end
|
222
|
+
summaries
|
223
|
+
end
|
224
|
+
|
180
225
|
# def self.summaries_from_comply_report(report)
|
181
226
|
# summaries = {}
|
182
227
|
# report.each do |_, v|
|
@@ -16,6 +16,8 @@ module AbideDevUtils
|
|
16
16
|
case type.downcase
|
17
17
|
when 'cis'
|
18
18
|
Benchmark.new(xccdf_file).gen_map(**opts)
|
19
|
+
when 'stig'
|
20
|
+
Benchmark.new(xccdf_file).gen_map(**opts)
|
19
21
|
else
|
20
22
|
raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type #{type} is unsupported!"
|
21
23
|
end
|
@@ -51,26 +53,31 @@ module AbideDevUtils
|
|
51
53
|
module Common
|
52
54
|
XPATHS = {
|
53
55
|
benchmark: {
|
54
|
-
all: '
|
55
|
-
title: '
|
56
|
-
version: '
|
56
|
+
all: 'Benchmark',
|
57
|
+
title: 'Benchmark/title',
|
58
|
+
version: 'Benchmark/version'
|
57
59
|
},
|
58
60
|
cis: {
|
59
61
|
profiles: {
|
60
|
-
all: '
|
61
|
-
relative_title: './
|
62
|
-
relative_select: './
|
62
|
+
all: 'Benchmark/Profile',
|
63
|
+
relative_title: './title',
|
64
|
+
relative_select: './select'
|
63
65
|
}
|
64
66
|
}
|
65
67
|
}.freeze
|
66
68
|
CONTROL_PREFIX = /^[\d.]+_/.freeze
|
67
69
|
UNDERSCORED = /(\s|\(|\)|-|\.)/.freeze
|
70
|
+
CIS_TITLE_MARKER = 'CIS'
|
68
71
|
CIS_NEXT_GEN_WINDOWS = /[Nn]ext_[Gg]eneration_[Ww]indows_[Ss]ecurity/.freeze
|
69
72
|
CIS_CONTROL_NUMBER = /([0-9.]+[0-9]+)/.freeze
|
70
73
|
CIS_LEVEL_CODE = /(?:_|^)([Ll]evel_[0-9]|[Ll]1|[Ll]2|[NnBb][GgLl]|#{CIS_NEXT_GEN_WINDOWS})/.freeze
|
71
74
|
CIS_CONTROL_PARTS = /#{CIS_CONTROL_NUMBER}#{CIS_LEVEL_CODE}?_+([A-Za-z].*)/.freeze
|
72
75
|
CIS_PROFILE_PARTS = /#{CIS_LEVEL_CODE}[_-]+([A-Za-z].*)/.freeze
|
73
|
-
|
76
|
+
STIG_TITLE_MARKER = 'Security Technical Implementation Guide'
|
77
|
+
STIG_CONTROL_PARTS = /(V-[0-9]+)/.freeze
|
78
|
+
STIG_PROFILE_PARTS = /(MAC-\d+)_([A-Za-z].+)/.freeze
|
79
|
+
PROFILE_PARTS = /#{CIS_PROFILE_PARTS}|#{STIG_PROFILE_PARTS}/.freeze
|
80
|
+
CONTROL_PARTS = /#{CIS_CONTROL_PARTS}|#{STIG_CONTROL_PARTS}/.freeze
|
74
81
|
|
75
82
|
def xpath(path)
|
76
83
|
@xml.xpath(path)
|
@@ -120,21 +127,41 @@ module AbideDevUtils
|
|
120
127
|
end
|
121
128
|
|
122
129
|
def profile_parts(profile)
|
123
|
-
|
124
|
-
|
125
|
-
parts = control_profile_text(profile).match(CIS_PROFILE_PARTS)
|
130
|
+
parts = control_profile_text(profile).match(PROFILE_PARTS)
|
126
131
|
raise AbideDevUtils::Errors::ProfilePartsError, profile if parts.nil?
|
127
132
|
|
128
|
-
parts[1]
|
129
|
-
|
133
|
+
if parts[1]
|
134
|
+
# CIS profile
|
135
|
+
parts[1].gsub!(/[Ll]evel_/, 'L')
|
136
|
+
parts[1..2]
|
137
|
+
elsif parts[3]
|
138
|
+
# STIG profile
|
139
|
+
parts[3..4]
|
140
|
+
else
|
141
|
+
raise AbideDevUtils::Errors::ProfilePartsError, profile
|
142
|
+
end
|
130
143
|
end
|
131
144
|
|
132
|
-
def control_parts(control
|
133
|
-
mdata = control_profile_text(control).match(
|
145
|
+
def control_parts(control)
|
146
|
+
mdata = control_profile_text(control).match(CONTROL_PARTS)
|
134
147
|
raise AbideDevUtils::Errors::ControlPartsError, control if mdata.nil?
|
135
148
|
|
136
|
-
mdata[
|
137
|
-
|
149
|
+
if mdata[1]
|
150
|
+
# CIS control
|
151
|
+
mdata[1..3]
|
152
|
+
elsif mdata[4]
|
153
|
+
# STIG control
|
154
|
+
vuln_id = mdata[4]
|
155
|
+
group = @benchmark.xpath("Group[@id='#{vuln_id}']")
|
156
|
+
if group.xpath('Rule').length != 1
|
157
|
+
raise AbideDevUtils::Errors::ControlPartsError, control
|
158
|
+
end
|
159
|
+
rule_id = group.xpath('Rule/@id').first.value
|
160
|
+
title = group.xpath('Rule/title').text
|
161
|
+
return [vuln_id, rule_id, title]
|
162
|
+
else
|
163
|
+
raise AbideDevUtils::Errors::ControlPartsError, control
|
164
|
+
end
|
138
165
|
end
|
139
166
|
|
140
167
|
def control_profile_text(item)
|
@@ -151,14 +178,6 @@ module AbideDevUtils
|
|
151
178
|
end
|
152
179
|
end
|
153
180
|
|
154
|
-
def sorted_control_classes(raw_select_list, sort_key: :number)
|
155
|
-
raw_select_list.map { |x| Control.new(x) }.sort_by(&sort_key)
|
156
|
-
end
|
157
|
-
|
158
|
-
def sorted_profile_classes(raw_profile_list, sort_key: :title)
|
159
|
-
raw_profile_list.map { |x| Profile.new(x) }.sort_by(&sort_key)
|
160
|
-
end
|
161
|
-
|
162
181
|
def ==(other)
|
163
182
|
diff_properties.map { |x| send(x) } == other.diff_properties.map { |x| other.send(x) }
|
164
183
|
end
|
@@ -172,14 +191,17 @@ module AbideDevUtils
|
|
172
191
|
class Benchmark
|
173
192
|
include AbideDevUtils::XCCDF::Common
|
174
193
|
|
175
|
-
|
194
|
+
CIS_MAP_INDICES = %w[title hiera_title hiera_title_num number].freeze
|
195
|
+
STIG_MAP_INDICES = %w[vulnid ruleid].freeze
|
176
196
|
|
177
|
-
attr_reader :xml, :title, :version, :diff_properties
|
197
|
+
attr_reader :xml, :title, :version, :diff_properties, :benchmark
|
178
198
|
|
179
199
|
def initialize(path)
|
180
200
|
@xml = parse(path)
|
181
|
-
@
|
182
|
-
@
|
201
|
+
@xml.remove_namespaces!
|
202
|
+
@benchmark = xpath('Benchmark')
|
203
|
+
@title = xpath('Benchmark/title').text
|
204
|
+
@version = xpath('Benchmark/version').text
|
183
205
|
@diff_properties = %i[title version profiles]
|
184
206
|
end
|
185
207
|
|
@@ -188,7 +210,7 @@ module AbideDevUtils
|
|
188
210
|
end
|
189
211
|
|
190
212
|
def profiles
|
191
|
-
@profiles ||= Profiles.new(xpath('
|
213
|
+
@profiles ||= Profiles.new(xpath('Benchmark/Profile'), @benchmark)
|
192
214
|
end
|
193
215
|
|
194
216
|
def profile_levels
|
@@ -200,7 +222,7 @@ module AbideDevUtils
|
|
200
222
|
end
|
201
223
|
|
202
224
|
def controls
|
203
|
-
@controls ||= Controls.new(xpath('//
|
225
|
+
@controls ||= Controls.new(xpath('//select'))
|
204
226
|
end
|
205
227
|
|
206
228
|
def controls_by_profile_level(level_code)
|
@@ -212,15 +234,22 @@ module AbideDevUtils
|
|
212
234
|
end
|
213
235
|
|
214
236
|
def gen_map(dir: nil, type: 'cis', parent_key_prefix: '', version_output_dir: false, **_)
|
215
|
-
|
237
|
+
case type
|
238
|
+
when 'cis'
|
239
|
+
os, ver = facter_platform
|
240
|
+
indicies = CIS_MAP_INDICES
|
241
|
+
when 'stig'
|
242
|
+
os, ver = facter_benchmark
|
243
|
+
indicies = STIG_MAP_INDICES
|
244
|
+
end
|
216
245
|
output_path = [type, os, ver]
|
217
246
|
output_path.unshift(File.expand_path(dir)) if dir
|
218
247
|
output_path << version if version_output_dir
|
219
248
|
mapping_dir = File.expand_path(File.join(output_path))
|
220
249
|
parent_key_prefix = '' if parent_key_prefix.nil?
|
221
|
-
|
250
|
+
indicies.each_with_object({}) do |idx, h|
|
222
251
|
map_file_path = "#{mapping_dir}/#{idx}.yaml"
|
223
|
-
h[map_file_path] = map_indexed(index: idx, framework: type, key_prefix: parent_key_prefix)
|
252
|
+
h[map_file_path] = map_indexed(indicies: indicies, index: idx, framework: type, key_prefix: parent_key_prefix)
|
224
253
|
end
|
225
254
|
end
|
226
255
|
|
@@ -240,10 +269,10 @@ module AbideDevUtils
|
|
240
269
|
}
|
241
270
|
end
|
242
271
|
|
243
|
-
def map_indexed(index: 'title', framework: 'cis', key_prefix: '')
|
272
|
+
def map_indexed(indicies: [], index: 'title', framework: 'cis', key_prefix: '')
|
244
273
|
c_map = profiles.each_with_object({}) do |profile, obj|
|
245
274
|
obj[profile.level.downcase] = {} unless obj[profile.level.downcase].is_a?(Hash)
|
246
|
-
obj[profile.level.downcase][profile.title.downcase] = map_controls_hash(profile, index).sort_by { |k, _| k }.to_h
|
275
|
+
obj[profile.level.downcase][profile.title.downcase] = map_controls_hash(profile, indicies, index).sort_by { |k, _| k }.to_h
|
247
276
|
end
|
248
277
|
|
249
278
|
c_map['benchmark'] = { 'title' => title, 'version' => version }
|
@@ -252,8 +281,13 @@ module AbideDevUtils
|
|
252
281
|
{ mappings.join('::') => c_map }.to_yaml
|
253
282
|
end
|
254
283
|
|
284
|
+
def facter_benchmark
|
285
|
+
id = xpath('Benchmark/@id').text
|
286
|
+
id.split('_')[0..-2]
|
287
|
+
end
|
288
|
+
|
255
289
|
def facter_platform
|
256
|
-
cpe = xpath('
|
290
|
+
cpe = xpath('Benchmark/platform')[0]['idref'].split(':')
|
257
291
|
if cpe.length > 4
|
258
292
|
product_name = cpe[4].split('_')
|
259
293
|
product_version = cpe[5].split('.') unless cpe[5].nil?
|
@@ -283,8 +317,8 @@ module AbideDevUtils
|
|
283
317
|
hash.to_yaml
|
284
318
|
end
|
285
319
|
|
286
|
-
def
|
287
|
-
xpath("//
|
320
|
+
def resolve_cis_control_reference(control)
|
321
|
+
xpath("//Rule[@id='#{control.reference}']")
|
288
322
|
end
|
289
323
|
|
290
324
|
private
|
@@ -294,15 +328,15 @@ module AbideDevUtils
|
|
294
328
|
when 'hiera_title_num'
|
295
329
|
control.hiera_title(number_format: true)
|
296
330
|
when 'title'
|
297
|
-
|
331
|
+
resolve_cis_control_reference(control).xpath('./title').text
|
298
332
|
else
|
299
333
|
control.send(index.to_sym)
|
300
334
|
end
|
301
335
|
end
|
302
336
|
|
303
|
-
def map_controls_hash(profile, index)
|
337
|
+
def map_controls_hash(profile, indicies, index)
|
304
338
|
profile.controls.each_with_object({}) do |ctrl, hsh|
|
305
|
-
control_array =
|
339
|
+
control_array = indicies.each_with_object([]) do |idx_sym, ary|
|
306
340
|
next if idx_sym == index
|
307
341
|
|
308
342
|
item = format_map_control_index(idx_sym, ctrl)
|
@@ -319,13 +353,9 @@ module AbideDevUtils
|
|
319
353
|
end
|
320
354
|
end
|
321
355
|
|
322
|
-
def sorted_profile_classes(raw_profile_list, sort_key: :level)
|
323
|
-
raw_profile_list.map { |x| Profile.new(x) }.sort_by(&sort_key)
|
324
|
-
end
|
325
|
-
|
326
356
|
def find_profiles
|
327
357
|
profs = {}
|
328
|
-
xpath('
|
358
|
+
xpath('Benchmark/Profile').each do |profile|
|
329
359
|
level_code, name = profile_parts(profile['id'])
|
330
360
|
profs[name] = {} unless profs.key?(name)
|
331
361
|
profs[name][level_code] = profile
|
@@ -352,11 +382,66 @@ module AbideDevUtils
|
|
352
382
|
end
|
353
383
|
end
|
354
384
|
|
355
|
-
class
|
385
|
+
class XccdfObject
|
386
|
+
include AbideDevUtils::XCCDF::Common
|
387
|
+
|
388
|
+
def initialize(benchmark)
|
389
|
+
@benchmark = benchmark
|
390
|
+
@benchmark_type = benchmark_type
|
391
|
+
end
|
392
|
+
|
393
|
+
def controls_class
|
394
|
+
case @benchmark_type
|
395
|
+
when :cis
|
396
|
+
CisControls
|
397
|
+
when :stig
|
398
|
+
StigControls
|
399
|
+
else
|
400
|
+
raise AbideDevUtils::Errors::UnsupportedXCCDFError
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def control_sort_key
|
405
|
+
case @benchmark_type
|
406
|
+
when :cis
|
407
|
+
:number
|
408
|
+
when :stig
|
409
|
+
:vulnid
|
410
|
+
else
|
411
|
+
raise AbideDevUtils::Errors::UnsupportedXCCDFError
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
def control_class
|
416
|
+
case @benchmark_type
|
417
|
+
when :cis
|
418
|
+
CisControl
|
419
|
+
when :stig
|
420
|
+
StigControl
|
421
|
+
else
|
422
|
+
raise AbideDevUtils::Errors::UnsupportedXCCDFError
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
private
|
427
|
+
|
428
|
+
def benchmark_type
|
429
|
+
title = @benchmark.at_xpath('title').text
|
430
|
+
if title.include?(STIG_TITLE_MARKER)
|
431
|
+
return :stig
|
432
|
+
elsif title.include?(CIS_TITLE_MARKER)
|
433
|
+
return :cis
|
434
|
+
end
|
435
|
+
raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type is unsupported!"
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
class ObjectContainer < XccdfObject
|
356
440
|
include AbideDevUtils::XCCDF::Common
|
357
441
|
|
358
|
-
def initialize(list, object_creation_method, *args, **kwargs)
|
359
|
-
|
442
|
+
def initialize(list, object_creation_method, benchmark, *args, **kwargs)
|
443
|
+
super(benchmark)
|
444
|
+
@object_list = send(object_creation_method.to_sym, list, benchmark, *args, **kwargs)
|
360
445
|
@searchable = []
|
361
446
|
end
|
362
447
|
|
@@ -399,6 +484,14 @@ module AbideDevUtils
|
|
399
484
|
|
400
485
|
private
|
401
486
|
|
487
|
+
def sorted_control_classes(raw_select_list, benchmark)
|
488
|
+
raw_select_list.map { |x| control_class.new(x, benchmark) }.sort_by(&control_sort_key)
|
489
|
+
end
|
490
|
+
|
491
|
+
def sorted_profile_classes(raw_profile_list, benchmark)
|
492
|
+
raw_profile_list.map { |x| Profile.new(x, benchmark) }.sort_by(&:title)
|
493
|
+
end
|
494
|
+
|
402
495
|
def resolve_hash_key(obj)
|
403
496
|
return obj.send(:raw_title) unless defined?(@hash_key)
|
404
497
|
|
@@ -419,8 +512,8 @@ module AbideDevUtils
|
|
419
512
|
end
|
420
513
|
|
421
514
|
class Profiles < ObjectContainer
|
422
|
-
def initialize(list)
|
423
|
-
super(list, :sorted_profile_classes)
|
515
|
+
def initialize(list, benchmark)
|
516
|
+
super(list, :sorted_profile_classes, benchmark)
|
424
517
|
searchable! :level, :title
|
425
518
|
index! :title
|
426
519
|
hash_key! :level, :title
|
@@ -443,9 +536,34 @@ module AbideDevUtils
|
|
443
536
|
end
|
444
537
|
end
|
445
538
|
|
446
|
-
class
|
447
|
-
def initialize(list)
|
448
|
-
super(list, :sorted_control_classes)
|
539
|
+
class StigControls < ObjectContainer
|
540
|
+
def initialize(list, benchmark)
|
541
|
+
super(list, :sorted_control_classes, benchmark)
|
542
|
+
searchable! :vulnid, :ruleid
|
543
|
+
index! :vulnid
|
544
|
+
hash_key! :vulnid
|
545
|
+
end
|
546
|
+
|
547
|
+
def vulnids
|
548
|
+
@vulnids ||= @object_list.map(&:vulnid).sort
|
549
|
+
end
|
550
|
+
|
551
|
+
def ruleids
|
552
|
+
@ruleids ||= @object_list.map(&:ruleid).sort
|
553
|
+
end
|
554
|
+
|
555
|
+
def include_vulnid?(item)
|
556
|
+
@object_list.map(&:vulnid).include?(item)
|
557
|
+
end
|
558
|
+
|
559
|
+
def include_ruleid?(item)
|
560
|
+
@object_list.map(&:ruleid).include?(item)
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
class CisControls < ObjectContainer
|
565
|
+
def initialize(list, benchmark)
|
566
|
+
super(list, :sorted_control_classes, benchmark)
|
449
567
|
searchable! :level, :title, :number
|
450
568
|
index! :number
|
451
569
|
hash_key! :number
|
@@ -476,10 +594,11 @@ module AbideDevUtils
|
|
476
594
|
end
|
477
595
|
end
|
478
596
|
|
479
|
-
class XccdfElement
|
597
|
+
class XccdfElement < XccdfObject
|
480
598
|
include AbideDevUtils::XCCDF::Common
|
481
599
|
|
482
|
-
def initialize(element)
|
600
|
+
def initialize(element, benchmark)
|
601
|
+
super(benchmark)
|
483
602
|
@xml = element
|
484
603
|
@element_type = self.class.name.split('::').last.downcase
|
485
604
|
@raw_title = control_profile_text(element)
|
@@ -501,11 +620,12 @@ module AbideDevUtils
|
|
501
620
|
end
|
502
621
|
|
503
622
|
def reference
|
504
|
-
@reference ||= @element_type
|
623
|
+
@reference ||= @element_type.include?('control') ? @xml['idref'] : @xml['id']
|
505
624
|
end
|
506
625
|
|
507
626
|
def hiera_title(**opts)
|
508
|
-
|
627
|
+
e_type = @element_type.include?('control') ? 'control' : 'profile'
|
628
|
+
send("normalize_#{e_type}_name".to_sym, @xml, **opts)
|
509
629
|
end
|
510
630
|
|
511
631
|
private
|
@@ -527,19 +647,27 @@ module AbideDevUtils
|
|
527
647
|
end
|
528
648
|
|
529
649
|
class Profile < XccdfElement
|
530
|
-
def initialize(profile)
|
531
|
-
super(profile)
|
650
|
+
def initialize(profile, benchmark)
|
651
|
+
super(profile, benchmark)
|
532
652
|
@level, @title = profile_parts(control_profile_text(profile))
|
533
|
-
@plain_text_title = @xml.xpath('./
|
534
|
-
@controls =
|
653
|
+
@plain_text_title = @xml.xpath('./title').text
|
654
|
+
@controls = controls_class.new(xpath('./select'), benchmark)
|
535
655
|
properties :title, :level, :plain_text_title, controls: :to_h
|
536
656
|
end
|
537
657
|
end
|
538
658
|
|
539
|
-
class
|
540
|
-
def initialize(control,
|
541
|
-
super(control)
|
542
|
-
@
|
659
|
+
class StigControl < XccdfElement
|
660
|
+
def initialize(control, benchmark)
|
661
|
+
super(control, benchmark)
|
662
|
+
@vulnid, @ruleid, @title = control_parts(control_profile_text(control))
|
663
|
+
properties :vulnid, :ruleid, :title
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
class CisControl < XccdfElement
|
668
|
+
def initialize(control, benchmark)
|
669
|
+
super(control, benchmark)
|
670
|
+
@number, @level, @title = control_parts(control_profile_text(control))
|
543
671
|
properties :number, :level, :title
|
544
672
|
end
|
545
673
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abide_dev_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- abide-team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|