Module: AbideDevUtils::XCCDF::Common

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

Overview

Common constants and methods included by nearly everything else

Constant Summary collapse

XPATHS =
{
  benchmark: {
    all: 'Benchmark',
    title: 'Benchmark/title',
    version: 'Benchmark/version'
  },
  cis: {
    profiles: {
      all: 'Benchmark/Profile',
      relative_title: './title',
      relative_select: './select'
    }
  }
}.freeze
CONTROL_PREFIX =
/^[\d.]+_/.freeze
UNDERSCORED =
/(\s|\(|\)|-|\.)/.freeze
CIS_TITLE_MARKER =
'CIS'
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
STIG_TITLE_MARKER =
'Security Technical Implementation Guide'
STIG_CONTROL_PARTS =
/(V-[0-9]+)/.freeze
STIG_PROFILE_PARTS =
/(MAC-\d+)_([A-Za-z].+)/.freeze
PROFILE_PARTS =
/#{CIS_PROFILE_PARTS}|#{STIG_PROFILE_PARTS}/.freeze
CONTROL_PARTS =
/#{CIS_CONTROL_PARTS}|#{STIG_CONTROL_PARTS}/.freeze

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Object



180
181
182
# File 'lib/abide_dev_utils/xccdf.rb', line 180

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

#abide_object?Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/abide_dev_utils/xccdf.rb', line 184

def abide_object?
  true
end

#control_parts(control) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/abide_dev_utils/xccdf.rb', line 145

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

  if mdata[1]
    # CIS control
    mdata[1..3]
  elsif mdata[4]
    # STIG control
    vuln_id = mdata[4]
    group = @benchmark.xpath("Group[@id='#{vuln_id}']")
    if group.xpath('Rule').length != 1
      raise AbideDevUtils::Errors::ControlPartsError, control
    end
    rule_id = group.xpath('Rule/@id').first.value
    return [vuln_id, rule_id]
  else
    raise AbideDevUtils::Errors::ControlPartsError, control
  end
end

#control_profile_text(item) ⇒ Object



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

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

#name_normalize_control(control) ⇒ Object



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

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

#normalize_control_name(control, number_format: false) ⇒ Object



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

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



101
102
103
104
105
106
107
108
# File 'lib/abide_dev_utils/xccdf.rb', line 101

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



90
91
92
93
94
95
96
97
98
99
# File 'lib/abide_dev_utils/xccdf.rb', line 90

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



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

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



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/abide_dev_utils/xccdf.rb', line 129

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

  if parts[1]
    # CIS profile
    parts[1].gsub!(/[Ll]evel_/, 'L')
    parts[1..2]
  elsif parts[3]
    # STIG profile
    parts[3..4]
  else
    raise AbideDevUtils::Errors::ProfilePartsError, profile
  end
end

#text_normalize(control) ⇒ Object



125
126
127
# File 'lib/abide_dev_utils/xccdf.rb', line 125

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

#validate_xccdf(path) ⇒ Object



86
87
88
# File 'lib/abide_dev_utils/xccdf.rb', line 86

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

#xpath(path) ⇒ Object



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

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