2012-10-01 18:09:30 +00:00
|
|
|
# Concern for behavior that all namespace modules that wrap Msf::Modules must support like version checking and
|
|
|
|
# grabbing the version specific-Metasploit* class.
|
|
|
|
module Msf::Modules::Namespace
|
|
|
|
# Returns the Metasploit(3|2|1) class from the module_evalled content.
|
|
|
|
#
|
|
|
|
# @note The module content must be module_evalled into this namespace module before the return of
|
2012-10-02 21:26:57 +00:00
|
|
|
# {#metasploit_class} is valid.
|
2012-10-01 18:09:30 +00:00
|
|
|
#
|
|
|
|
# @return [Msf::Module] if a Metasploit(3|2|1) class exists in this module
|
|
|
|
# @return [nil] if such as class is not defined.
|
|
|
|
def metasploit_class
|
|
|
|
metasploit_class = nil
|
|
|
|
|
|
|
|
::Msf::Framework::Major.downto(1) do |major|
|
2012-10-08 22:29:36 +00:00
|
|
|
# Since we really only care about the deepest namespace, we don't
|
|
|
|
# need to look for parents' constants. However, the "inherit"
|
|
|
|
# parameter for const_defined? only exists after 1.9. If we ever
|
|
|
|
# drop 1.8 support, we can save a few cycles here by passing false
|
|
|
|
# here.
|
2012-10-08 17:11:59 +00:00
|
|
|
if const_defined?("Metasploit#{major}")
|
2012-10-01 18:09:30 +00:00
|
|
|
metasploit_class = const_get("Metasploit#{major}")
|
|
|
|
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
metasploit_class
|
|
|
|
end
|
|
|
|
|
Rescue Errno::ENOENT from File.open in read_module_content
[Fixes #38426061, #38097411]
Msf::Modules::Loader::Directory#read_module_content may calculate a non-existent
module_path that gets passed to File.open causing an Errno::ENOENT exception
to be raised when using the module cache with a module that has been
moved to a new path (as is the case that originally found this bug) or
deleted. Now, the exception is rescued and read_module_content returns
an empty string (''), which load_module detects with
module_content.empty? and returns earlier without attempting to module
eval the (empty) content.
As having Msf::Modules::Loader::Directory#read_module_content rescue the
exception, meant there was another place that needed to log and error
and store an error in Msf::ModuleManager#module_load_error_by_path, I
refactored the error reporting to call
Msf::Modules::Loader::Base#load_error, which handles writing to the log
and setting the Hash, so the error reporting is consistent across the
loaders.
The exception hierarchy was also refactored so that
namespace_module.metasploit_class now has an error raising counter-part:
namespace_module.metasploit_class! that can be used with
Msf::Modules::Loader::Base#load_error as it requires an exception, and
not just a string so the exception class, message, and backtrace can be
logged.
2012-11-06 23:38:38 +00:00
|
|
|
def metasploit_class!(module_path, module_reference_name)
|
2013-08-30 21:28:33 +00:00
|
|
|
metasploit_class = self.metasploit_class
|
Rescue Errno::ENOENT from File.open in read_module_content
[Fixes #38426061, #38097411]
Msf::Modules::Loader::Directory#read_module_content may calculate a non-existent
module_path that gets passed to File.open causing an Errno::ENOENT exception
to be raised when using the module cache with a module that has been
moved to a new path (as is the case that originally found this bug) or
deleted. Now, the exception is rescued and read_module_content returns
an empty string (''), which load_module detects with
module_content.empty? and returns earlier without attempting to module
eval the (empty) content.
As having Msf::Modules::Loader::Directory#read_module_content rescue the
exception, meant there was another place that needed to log and error
and store an error in Msf::ModuleManager#module_load_error_by_path, I
refactored the error reporting to call
Msf::Modules::Loader::Base#load_error, which handles writing to the log
and setting the Hash, so the error reporting is consistent across the
loaders.
The exception hierarchy was also refactored so that
namespace_module.metasploit_class now has an error raising counter-part:
namespace_module.metasploit_class! that can be used with
Msf::Modules::Loader::Base#load_error as it requires an exception, and
not just a string so the exception class, message, and backtrace can be
logged.
2012-11-06 23:38:38 +00:00
|
|
|
|
2013-08-30 21:28:33 +00:00
|
|
|
unless metasploit_class
|
|
|
|
raise Msf::Modules::MetasploitClassCompatibilityError.new(
|
|
|
|
:module_path => module_path,
|
|
|
|
:module_reference_name => module_reference_name
|
|
|
|
)
|
|
|
|
end
|
Rescue Errno::ENOENT from File.open in read_module_content
[Fixes #38426061, #38097411]
Msf::Modules::Loader::Directory#read_module_content may calculate a non-existent
module_path that gets passed to File.open causing an Errno::ENOENT exception
to be raised when using the module cache with a module that has been
moved to a new path (as is the case that originally found this bug) or
deleted. Now, the exception is rescued and read_module_content returns
an empty string (''), which load_module detects with
module_content.empty? and returns earlier without attempting to module
eval the (empty) content.
As having Msf::Modules::Loader::Directory#read_module_content rescue the
exception, meant there was another place that needed to log and error
and store an error in Msf::ModuleManager#module_load_error_by_path, I
refactored the error reporting to call
Msf::Modules::Loader::Base#load_error, which handles writing to the log
and setting the Hash, so the error reporting is consistent across the
loaders.
The exception hierarchy was also refactored so that
namespace_module.metasploit_class now has an error raising counter-part:
namespace_module.metasploit_class! that can be used with
Msf::Modules::Loader::Base#load_error as it requires an exception, and
not just a string so the exception class, message, and backtrace can be
logged.
2012-11-06 23:38:38 +00:00
|
|
|
|
2013-08-30 21:28:33 +00:00
|
|
|
metasploit_class
|
Rescue Errno::ENOENT from File.open in read_module_content
[Fixes #38426061, #38097411]
Msf::Modules::Loader::Directory#read_module_content may calculate a non-existent
module_path that gets passed to File.open causing an Errno::ENOENT exception
to be raised when using the module cache with a module that has been
moved to a new path (as is the case that originally found this bug) or
deleted. Now, the exception is rescued and read_module_content returns
an empty string (''), which load_module detects with
module_content.empty? and returns earlier without attempting to module
eval the (empty) content.
As having Msf::Modules::Loader::Directory#read_module_content rescue the
exception, meant there was another place that needed to log and error
and store an error in Msf::ModuleManager#module_load_error_by_path, I
refactored the error reporting to call
Msf::Modules::Loader::Base#load_error, which handles writing to the log
and setting the Hash, so the error reporting is consistent across the
loaders.
The exception hierarchy was also refactored so that
namespace_module.metasploit_class now has an error raising counter-part:
namespace_module.metasploit_class! that can be used with
Msf::Modules::Loader::Base#load_error as it requires an exception, and
not just a string so the exception class, message, and backtrace can be
logged.
2012-11-06 23:38:38 +00:00
|
|
|
end
|
|
|
|
|
2012-10-01 18:09:30 +00:00
|
|
|
# Raises an error unless {Msf::Framework::VersionCore} and {Msf::Framework::VersionAPI} meet the minimum required
|
|
|
|
# versions defined in RequiredVersions in the module content.
|
|
|
|
#
|
|
|
|
# @note The module content must be module_evalled into this namespace module using module_eval_with_lexical_scope
|
2012-10-02 21:26:57 +00:00
|
|
|
# before calling {#version_compatible!} is valid.
|
2012-10-01 18:09:30 +00:00
|
|
|
#
|
2012-10-02 21:26:57 +00:00
|
|
|
# @param [String] module_path Path from where the module was read.
|
|
|
|
# @param [String] module_reference_name The canonical name for the module.
|
2012-10-01 18:09:30 +00:00
|
|
|
# @raise [Msf::Modules::VersionCompatibilityError] if RequiredVersion[0] > Msf::Framework::VersionCore or
|
|
|
|
# RequiredVersion[1] > Msf::Framework::VersionApi
|
|
|
|
# @return [void]
|
2012-10-02 21:26:57 +00:00
|
|
|
def version_compatible!(module_path, module_reference_name)
|
2012-10-01 18:09:30 +00:00
|
|
|
if const_defined?(:RequiredVersions)
|
|
|
|
required_versions = const_get(:RequiredVersions)
|
|
|
|
minimum_core_version = required_versions[0]
|
|
|
|
minimum_api_version = required_versions[1]
|
|
|
|
|
|
|
|
if (minimum_core_version > ::Msf::Framework::VersionCore or
|
|
|
|
minimum_api_version > ::Msf::Framework::VersionAPI)
|
|
|
|
raise Msf::Modules::VersionCompatibilityError.new(
|
2012-10-02 21:26:57 +00:00
|
|
|
:module_path => module_path,
|
|
|
|
:module_reference_name => module_reference_name,
|
2012-10-01 18:09:30 +00:00
|
|
|
:minimum_api_version => minimum_api_version,
|
|
|
|
:minimum_core_version => minimum_core_version
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-10-08 17:11:59 +00:00
|
|
|
end
|
2012-10-08 17:42:34 +00:00
|
|
|
|