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 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