Module: AbideDevUtils::XCCDF::Common

Included in:
Benchmark, ObjectContainer, XccdfElement
Defined in:
lib/abide_dev_utils/xccdf.rb

Overview

Common constants and methods included by nearly everything else

Constant Summary collapse

XPATHS =
{
  benchmark: {
    all: 'xccdf:Benchmark',
    title: 'xccdf:Benchmark/xccdf:title',
    version: 'xccdf:Benchmark/xccdf:version'
  },
  cis: {
    profiles: {
      all: 'xccdf:Benchmark/xccdf:Profile',
      relative_title: './xccdf:title',
      relative_select: './xccdf:select'
    }
  }
}.freeze
CONTROL_PREFIX =
/^[\d.]+_/.freeze
UNDERSCORED =
/(\s|\(|\)|-|\.)/.freeze
CIS_NEXT_GEN_WINDOWS =
/[Nn]ext_[Gg]eneration_[Ww]indows_[Ss]ecurity/.freeze
CIS_CONTROL_NUMBER =
/([0-9.]+[0-9]+)/.freeze
CIS_LEVEL_CODE =
/(?:_|^)([Ll]evel_[0-9]|[Ll]1|[Ll]2|[NnBb][GgLl]|#{CIS_NEXT_GEN_WINDOWS})/.freeze
CIS_CONTROL_PARTS =
/#{CIS_CONTROL_NUMBER}#{CIS_LEVEL_CODE}?_+([A-Za-z].*)/.freeze
CIS_PROFILE_PARTS =
/#{CIS_LEVEL_CODE}[_-]+([A-Za-z].*)/.freeze

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Object



163
164
165
# File 'lib/abide_dev_utils/xccdf.rb', line 163

def ==(other)
  diff_properties.map { |x| send(x) } == other.diff_properties.map { |x| other.send(x) }
end

#abide_object?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/abide_dev_utils/xccdf.rb', line 186

def abide_object?
  true
end

#control_parts(control, parent_level: nil) ⇒ Object



133
134
135
136
137
138
139
# File 'lib/abide_dev_utils/xccdf.rb', line 133

def control_parts(control, parent_level: nil)
  mdata = control_profile_text(control).match(CIS_CONTROL_PARTS)
  raise AbideDevUtils::Errors::ControlPartsError, control if mdata.nil?

  mdata[2] = parent_level unless parent_level.nil?
  mdata[1..3]
end

#control_profile_text(item) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/abide_dev_utils/xccdf.rb', line 141

def control_profile_text(item)
  return item.raw_title if item.respond_to?(:abide_object?)

  if item.respond_to?(:split)
    return item.split('benchmarks_rule_')[-1] if item.include?('benchmarks_rule_')

    item.split('benchmarks_profile_')[-1]
  else
    return item['idref'].to_s.split('benchmarks_rule_')[-1] if item.name == 'select'

    item['id'].to_s.split('benchmarks_profile_')[-1]
  end
end

#default_diff_optsObject



167
168
169
170
171
172
173
174
175
176
# File 'lib/abide_dev_utils/xccdf.rb', line 167

def default_diff_opts
  {
    similarity: 1,
    strict: true,
    strip: true,
    array_path: true,
    delimiter: '//',
    use_lcs: false
  }
end

#diff(other, **opts) ⇒ Object



178
179
180
181
182
183
184
# File 'lib/abide_dev_utils/xccdf.rb', line 178

def diff(other, **opts)
  Hashdiff.diff(
    to_h,
    other.to_h,
    default_diff_opts.merge(opts)
  )
end

#name_normalize_control(control) ⇒ Object



112
113
114
# File 'lib/abide_dev_utils/xccdf.rb', line 112

def name_normalize_control(control)
  normalize_string(control_profile_text(control).gsub(CONTROL_PREFIX, ''))
end

#normalize_control_name(control, number_format: false) ⇒ Object



106
107
108
109
110
# File 'lib/abide_dev_utils/xccdf.rb', line 106

def normalize_control_name(control, number_format: false)
  return number_normalize_control(control) if number_format

  name_normalize_control(control)
end

#normalize_profile_name(prof, **_opts) ⇒ Object



97
98
99
100
101
102
103
104
# File 'lib/abide_dev_utils/xccdf.rb', line 97

def normalize_profile_name(prof, **_opts)
  prof_name = normalize_string("profile_#{control_profile_text(prof)}").dup
  prof_name.gsub!(CIS_NEXT_GEN_WINDOWS, 'ngws')
  prof_name.delete_suffix!('_environment_general_use')
  prof_name.delete_suffix!('sensitive_data_environment_limited_functionality')
  prof_name.strip!
  prof_name
end

#normalize_string(str) ⇒ Object



86
87
88
89
90
91
92
93
94
95
# File 'lib/abide_dev_utils/xccdf.rb', line 86

def normalize_string(str)
  nstr = str.dup.downcase
  nstr.gsub!(/[^a-z0-9]$/, '')
  nstr.gsub!(/^[^a-z]/, '')
  nstr.gsub!(/(?:_|^)([Ll]1_|[Ll]2_|ng_)/, '')
  nstr.delete!('(/|\\|\+)')
  nstr.gsub!(UNDERSCORED, '_')
  nstr.strip!
  nstr
end

#number_normalize_control(control) ⇒ Object



116
117
118
119
# File 'lib/abide_dev_utils/xccdf.rb', line 116

def number_normalize_control(control)
  numpart = CONTROL_PREFIX.match(control_profile_text(control)).to_s.chop.gsub(UNDERSCORED, '_')
  "c#{numpart}"
end

#profile_parts(profile) ⇒ Object



125
126
127
128
129
130
131
# File 'lib/abide_dev_utils/xccdf.rb', line 125

def profile_parts(profile)
  parts = control_profile_text(profile).match(CIS_PROFILE_PARTS)
  raise AbideDevUtils::Errors::ProfilePartsError, profile if parts.nil?

  parts[1].gsub!(/[Ll]evel_/, 'L')
  parts[1..2]
end

#sorted_control_classes(raw_select_list, sort_key: :number) ⇒ Object



155
156
157
# File 'lib/abide_dev_utils/xccdf.rb', line 155

def sorted_control_classes(raw_select_list, sort_key: :number)
  raw_select_list.map { |x| Control.new(x) }.sort_by(&sort_key)
end

#sorted_profile_classes(raw_profile_list, sort_key: :title) ⇒ Object



159
160
161
# File 'lib/abide_dev_utils/xccdf.rb', line 159

def sorted_profile_classes(raw_profile_list, sort_key: :title)
  raw_profile_list.map { |x| Profile.new(x) }.sort_by(&sort_key)
end

#text_normalize(control) ⇒ Object



121
122
123
# File 'lib/abide_dev_utils/xccdf.rb', line 121

def text_normalize(control)
  control_profile_text(control).tr('_', ' ')
end

#validate_xccdf(path) ⇒ Object



82
83
84
# File 'lib/abide_dev_utils/xccdf.rb', line 82

def validate_xccdf(path)
  AbideDevUtils::Validate.file(path, extension: '.xml')
end

#xpath(path) ⇒ Object



78
79
80
# File 'lib/abide_dev_utils/xccdf.rb', line 78

def xpath(path)
  @xml.xpath(path)
end