mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 11:18:06 +00:00
130 lines
4.4 KiB
Ruby
130 lines
4.4 KiB
Ruby
################################################################################
|
|
#
|
|
# Script for generating test scenarios for identifying conflicts and
|
|
# version mismatches within a recently upgraded base box.
|
|
#
|
|
# Requires: SecGen batch database configured, see README-Batch-VMs.md
|
|
#
|
|
# 1) A scenario file is created for each software module within lib/test/tmp/
|
|
# 2) a batch_secgen entry is created for each generated scenario
|
|
# 3) batch_secgen spins up each scenario and reports on failures
|
|
#
|
|
################################################################################
|
|
|
|
require 'fileutils'
|
|
|
|
require_relative '../helpers/print.rb'
|
|
require_relative '../helpers/constants.rb'
|
|
require_relative '../../lib/readers/module_reader.rb'
|
|
require_relative '../output/xml_scenario_generator.rb'
|
|
require_relative '../objects/system'
|
|
require_relative '../objects/module'
|
|
|
|
@path_to_ruby = '/usr/bin/ruby'
|
|
@network_module = ''
|
|
|
|
def select_base
|
|
bases = ModuleReader.read_bases
|
|
Print.info 'Now listing all available bases: '
|
|
|
|
bases.each_with_index do |base, i|
|
|
Print.info "#{i}: #{base.attributes['name'][0]} at #{base.attributes['module_path'][0]}"
|
|
end
|
|
|
|
Print.info 'Input the index for the base you want to generate test scenarios for:'
|
|
user_index = gets.chomp.to_i
|
|
selected_base = bases[user_index]
|
|
Print.info "You have selected: #{selected_base.attributes['name'][0]} at #{selected_base.attributes['module_path'][0]}"
|
|
|
|
selected_base
|
|
end
|
|
|
|
def get_network_module
|
|
if @network_module == ''
|
|
@network_module = Module.new('network')
|
|
@network_module.attributes['type'] = ['private_network']
|
|
end
|
|
@network_module
|
|
end
|
|
|
|
def generate_scenarios(selected_base)
|
|
tmp_dir = "#{ROOT_DIR}/lib/test/tmp"
|
|
|
|
Dir.mkdir tmp_dir unless Dir.exists? tmp_dir
|
|
unless Dir.entries(tmp_dir).size == 2
|
|
Print.info 'The temporary scenario directory (lib/test/tmp) contains files. Do you want to remove them? [Y/n]'
|
|
input = STDIN.gets.chomp
|
|
unless input == 'N' or input == 'n'
|
|
Print.info 'Removing lib/test/tmp'
|
|
FileUtils.rm_r(Dir.glob(tmp_dir))
|
|
Print.info 'Creating lib/test/tmp'
|
|
Dir.mkdir tmp_dir
|
|
end
|
|
end
|
|
|
|
# Get installable software modules (vulns, services, utilities)
|
|
|
|
vulnerabilities = ModuleReader.read_vulnerabilities
|
|
services = ModuleReader.read_services
|
|
utilities = ModuleReader.read_utilities
|
|
|
|
available_software_modules = vulnerabilities + services + utilities
|
|
|
|
# If the module conflicts with the base, remove it.
|
|
available_software_modules.delete_if do |module_for_possible_exclusion|
|
|
(module_for_possible_exclusion.conflicts_with(selected_base) ||
|
|
selected_base.conflicts_with(module_for_possible_exclusion))
|
|
end
|
|
|
|
output_scenario_paths = []
|
|
|
|
available_software_modules.each_with_index do |mod, i|
|
|
## Create a system_name based on the selected module and the base name
|
|
system_name = mod.module_path_end
|
|
|
|
# Clean up name
|
|
system_name = system_name.gsub(/ /, '_')
|
|
system_name = system_name.gsub(/\//, '')
|
|
|
|
module_selections = []
|
|
module_selections << selected_base
|
|
module_selections << mod
|
|
module_selections << get_network_module
|
|
|
|
system = System.new(system_name, {}, [])
|
|
system.module_selections = module_selections
|
|
|
|
xml_generator = XmlScenarioGenerator.new([system], system_name, Time.new.to_s)
|
|
xml_content = xml_generator.output
|
|
|
|
output_filename = "#{tmp_dir}/#{i}.xml"
|
|
Print.std "Creating scenario definition file: #{output_filename}"
|
|
begin
|
|
File.open(output_filename, 'w+') do |file|
|
|
file.write(xml_content)
|
|
end
|
|
output_scenario_paths << output_filename
|
|
rescue StandardError => e
|
|
Print.err "Error writing file: #{e.message}"
|
|
abort
|
|
end
|
|
end
|
|
output_scenario_paths
|
|
end
|
|
|
|
def add_to_secgen_batch(scenario_paths)
|
|
Print.info 'Do you want to add the generated test scenarios to the batch? [Y/n]'
|
|
input = STDIN.gets.chomp
|
|
unless input == 'N' or input == 'n'
|
|
Print.info "Adding #{scenario_paths.size} jobs to batch queue"
|
|
scenario_paths.each do |scenario_path|
|
|
puts `#{@path_to_ruby} #{ROOT_DIR}/lib/batch/batch_secgen.rb add --instances test --- -s #{scenario_path} --read-options #{ROOT_DIR}/secgen.conf r`
|
|
end
|
|
end
|
|
end
|
|
|
|
Print.info 'Script for generating base module upgrade test scenarios'
|
|
base = select_base
|
|
output_scenario_paths = generate_scenarios(base)
|
|
Print.info 'Scenario files generated successfully.'
|
|
add_to_secgen_batch(output_scenario_paths) |