109 lines
3.0 KiB
Ruby
109 lines
3.0 KiB
Ruby
#
|
|
# Gems
|
|
#
|
|
|
|
require 'active_support/core_ext/module/introspection'
|
|
|
|
#
|
|
# Project
|
|
#
|
|
|
|
require 'metasploit/framework/command'
|
|
require 'metasploit/framework/parsed_options'
|
|
require 'metasploit/framework/require'
|
|
|
|
# Based on pattern used for lib/rails/commands in the railties gem.
|
|
class Metasploit::Framework::Command::Base
|
|
#
|
|
# Attributes
|
|
#
|
|
|
|
# @!attribute [r] application
|
|
# The Rails application for metasploit-framework.
|
|
#
|
|
# @return [Metasploit::Framework::Application]
|
|
attr_reader :application
|
|
|
|
# @!attribute [r] parsed_options
|
|
# The parsed options from the command line.
|
|
#
|
|
# @return (see parsed_options)
|
|
attr_reader :parsed_options
|
|
|
|
#
|
|
# Class Methods
|
|
#
|
|
|
|
# @note {require_environment!} should be called to load
|
|
# `config/application.rb` to so that the RAILS_ENV can be set from the
|
|
# command line options in `ARGV` prior to `Rails.env` being set.
|
|
# @note After returning, `Rails.application` will be defined and configured.
|
|
#
|
|
# Parses `ARGV` for command line arguments to configure the
|
|
# `Rails.application`.
|
|
#
|
|
# @return (see parsed_options)
|
|
def self.require_environment!
|
|
parsed_options = self.parsed_options
|
|
# RAILS_ENV must be set before requiring 'config/application.rb'
|
|
parsed_options.environment!
|
|
ARGV.replace(parsed_options.positional)
|
|
|
|
# allow other Rails::Applications to use this command
|
|
if !defined?(Rails) || Rails.application.nil?
|
|
# @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/commands.rb#L39-L40
|
|
require Pathname.new(__FILE__).parent.parent.parent.parent.parent.join('config', 'application')
|
|
end
|
|
|
|
# have to configure before requiring environment because
|
|
# config/environment.rb calls initialize! and the initializers will use
|
|
# the configuration from the parsed options.
|
|
parsed_options.configure(Rails.application)
|
|
|
|
Rails.application.require_environment!
|
|
|
|
parsed_options
|
|
end
|
|
|
|
def self.parsed_options
|
|
parsed_options_class.new
|
|
end
|
|
|
|
def self.parsed_options_class
|
|
@parsed_options_class ||= parsed_options_class_name.constantize
|
|
end
|
|
|
|
def self.parsed_options_class_name
|
|
@parsed_options_class_name ||= "#{parent.parent}::ParsedOptions::#{name.demodulize}"
|
|
end
|
|
|
|
def self.start
|
|
parsed_options = require_environment!
|
|
new(application: Rails.application, parsed_options: parsed_options).start
|
|
end
|
|
|
|
#
|
|
# Instance Methods
|
|
#
|
|
|
|
# @param attributes [Hash{Symbol => ActiveSupport::OrderedOptions,Rails::Application}]
|
|
# @option attributes [Rails::Application] :application
|
|
# @option attributes [ActiveSupport::OrderedOptions] :parsed_options
|
|
# @raise [KeyError] if :application is not given
|
|
# @raise [KeyError] if :parsed_options is not given
|
|
def initialize(attributes={})
|
|
@application = attributes.fetch(:application)
|
|
@parsed_options = attributes.fetch(:parsed_options)
|
|
end
|
|
|
|
# @abstract Use {#application} to start this command.
|
|
#
|
|
# Starts this command.
|
|
#
|
|
# @return [void]
|
|
# @raise [NotImplementedError]
|
|
def start
|
|
raise NotImplementedError
|
|
end
|
|
end
|