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



169
170
171
# File 'lib/abide_dev_utils/xccdf.rb', line 169

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

#abide_object?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/abide_dev_utils/xccdf.rb', line 173

def abide_object?
  true
end

#control_parts(control) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/abide_dev_utils/xccdf.rb', line 134

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}']")
    raise AbideDevUtils::Errors::ControlPartsError, control if group.xpath('Rule').length != 1

    rule_id = group.xpath('Rule/@id').first.value
    title = group.xpath('Rule/title').text
    [vuln_id, rule_id, title]
  else
    raise AbideDevUtils::Errors::ControlPartsError, control
  end
end

#control_profile_text(item) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/abide_dev_utils/xccdf.rb', line 155

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



105
106
107
# File 'lib/abide_dev_utils/xccdf.rb', line 105

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

#normalize_control_name(control, number_format: false) ⇒ Object



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

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



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

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



79
80
81
82
83
84
85
86
87
88
# File 'lib/abide_dev_utils/xccdf.rb', line 79

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



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

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



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/abide_dev_utils/xccdf.rb', line 118

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



114
115
116
# File 'lib/abide_dev_utils/xccdf.rb', line 114

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

#validate_xccdf(path) ⇒ Object



75
76
77
# File 'lib/abide_dev_utils/xccdf.rb', line 75

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

#xpath(path) ⇒ Object



71
72
73
# File 'lib/abide_dev_utils/xccdf.rb', line 71

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