abide_dev_utils 0.11.2 → 0.12.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85fb0e453df008a48284f03fe59bd1577b733498ce030039e215bf1863e1767c
4
- data.tar.gz: 9a89ac46e8506ea059044006a5c50d8132847fa2a8f9a6b726174ed51ab6421c
3
+ metadata.gz: 1e93a77cf4142b06ee4d41863ef2d0b737d21d37306b57082aa316f2731de5e9
4
+ data.tar.gz: 9b49e05aa575884d54efed8fd70b5662712845c083a8b59caeccf406a19f5633
5
5
  SHA512:
6
- metadata.gz: 9f221ac5c9c15db1414005ca4017dda7a9f848d8b7586d4b8a3ede9ecaf5fc8e35187ab2f172e127cad92a1d483befe31fa17278279b54b33abcc1d25f7a21a6
7
- data.tar.gz: b9f3e5553a03faed668600c94b44759ee4554165e20722b7c6d5108add327ba23a6986e707034647b3eed400e6217b032eb058e537a74f26d11a004cf309bcfd
6
+ metadata.gz: 51316ad752020f3b2297acbdc4bb328c5275d03e499721ee12381aaac5da3a6e77ecb9efeb0ffa4b3b6bb512154dbb4b36bf249f4816944a0110d3ceeb871b2b
7
+ data.tar.gz: 40b83d7be09ccb1349650617548276f6f34e266fe2e590e8c1b28b8e9c44f4499c93652abf9e254d77469fec9c98e9394a1ae2f4b2d3f0921827c3ce302dfb7e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.11.2)
4
+ abide_dev_utils (0.12.2)
5
5
  amatch (~> 0.4)
6
6
  cmdparse (~> 3.0)
7
7
  facterdb (>= 1.18)
@@ -120,7 +120,11 @@ module AbideDevUtils
120
120
  private
121
121
 
122
122
  def heading_builder
123
- @md.add_h2("#{@control.number} - #{@control.title}")
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 title].freeze
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[hiera_title_num number hiera_title vulnid title],
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[hiera_title_num number hiera_title vulnid title].freeze
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
@@ -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|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.11.2"
4
+ VERSION = "0.12.2"
5
5
  end
@@ -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: 'xccdf:Benchmark',
55
- title: 'xccdf:Benchmark/xccdf:title',
56
- version: 'xccdf:Benchmark/xccdf:version'
56
+ all: 'Benchmark',
57
+ title: 'Benchmark/title',
58
+ version: 'Benchmark/version'
57
59
  },
58
60
  cis: {
59
61
  profiles: {
60
- all: 'xccdf:Benchmark/xccdf:Profile',
61
- relative_title: './xccdf:title',
62
- relative_select: './xccdf: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
- STIG_PROFILE_PARTS = /(STIG)/.freeze
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
- return ['STIG', ''] if profile == 'STIG'
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].gsub!(/[Ll]evel_/, 'L')
129
- parts[1..2]
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, parent_level: nil)
133
- mdata = control_profile_text(control).match(CIS_CONTROL_PARTS)
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[2] = parent_level unless parent_level.nil?
137
- mdata[1..3]
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
- MAP_INDICES = %w[title hiera_title hiera_title_num number].freeze
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
- @title = xpath('xccdf:Benchmark/xccdf:title').text
182
- @version = xpath('xccdf:Benchmark/xccdf:version').text
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('xccdf:Benchmark/xccdf:Profile'))
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('//xccdf:select'))
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
- os, ver = facter_platform
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
- MAP_INDICES.each_with_object({}) do |idx, h|
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('xccdf:Benchmark/xccdf:platform')[0]['idref'].split(':')
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 resolve_control_reference(control)
287
- xpath("//xccdf:Rule[@id='#{control.reference}']")
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
- resolve_control_reference(control).xpath('./xccdf:title').text
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 = MAP_INDICES.each_with_object([]) do |idx_sym, ary|
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('xccdf:Benchmark/xccdf:Profile').each do |profile|
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 ObjectContainer
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
- @object_list = send(object_creation_method.to_sym, list, *args, **kwargs)
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 Controls < ObjectContainer
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 == 'control' ? @xml['idref'] : @xml['id']
623
+ @reference ||= @element_type.include?('control') ? @xml['idref'] : @xml['id']
505
624
  end
506
625
 
507
626
  def hiera_title(**opts)
508
- send("normalize_#{@element_type}_name".to_sym, @xml, **opts)
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('./xccdf:title').text
534
- @controls = Controls.new(xpath('./xccdf:select'))
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 Control < XccdfElement
540
- def initialize(control, parent_level: nil)
541
- super(control)
542
- @number, @level, @title = control_parts(control_profile_text(control), parent_level: parent_level)
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.11.2
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-08-15 00:00:00.000000000 Z
11
+ date: 2022-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri