lib/cms_scanner/scan.rb
# frozen_string_literal: true
module CMSScanner
# Scan
class Scan
attr_reader :run_error
def initialize
NS.start_memory = GetProcessMem.new.bytes
controllers << NS::Controller::Core.new
exit_hook
yield self if block_given?
end
# @return [ Controllers ]
def controllers
@controllers ||= NS::Controllers.new
end
def run
controllers.run
rescue OptParseValidator::NoRequiredOption => e
@run_error = e
formatter.output('@usage', msg: e.message)
rescue NoMemoryError, ScriptError, SecurityError, SignalException, StandardError, SystemStackError => e
@run_error = e
output_params = {
reason: e.is_a?(Interrupt) ? 'Canceled by User' : e.message,
trace: e.backtrace,
verbose: NS::ParsedCli.verbose || run_error_exit_code == NS::ExitCode::EXCEPTION
}
output_params[:url] = controllers.first.target.url if NS::ParsedCli.url
formatter.output('@scan_aborted', output_params)
ensure
formatter.beautify
end
# Used for convenience
# @See Formatter
def formatter
controllers.first.formatter
end
# @return [ Hash ]
def datastore
controllers.first.datastore
end
# Hook to be able to have an exit code returned
# depending on the findings / errors
# :nocov:
def exit_hook
# Avoid hooking the exit when rspec is running, otherwise it will always return 0
# and Travis won't detect failed builds. Couldn't find a better way, even though
# some people managed to https://github.com/rspec/rspec-core/pull/410
return if defined?(RSpec)
at_exit do
exit(run_error_exit_code) if run_error
# The parsed_option[:url] must be checked to avoid raising erros when only -h/-v are given
exit(NS::ExitCode::VULNERABLE) if NS::ParsedCli.url && controllers.first.target.vulnerable?
exit(NS::ExitCode::OK)
end
end
# :nocov:
# @return [ Integer ] The exit code related to the run_error
def run_error_exit_code
return NS::ExitCode::CLI_OPTION_ERROR if run_error.is_a?(OptParseValidator::Error) ||
run_error.is_a?(OptionParser::ParseError)
return NS::ExitCode::INTERRUPTED if run_error.is_a?(Interrupt)
return NS::ExitCode::ERROR if run_error.is_a?(NS::Error::Standard) ||
run_error.is_a?(CMSScanner::Error::Standard)
NS::ExitCode::EXCEPTION
end
end
end