diff --git a/Gemfile b/Gemfile index 319545466677..44a97a4ccae4 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,8 @@ source 'https://rubygems.org' # spec.add_runtime_dependency '', [] gemspec name: 'metasploit-framework' +gem 'rex-core', git: 'https://github.com/sempervictus/rex-core.git', branch: 'structure/move_logging_to_core' + # separate from test as simplecov is not run on travis-ci group :coverage do # code coverage for tests diff --git a/Gemfile.lock b/Gemfile.lock index 6c3f9c881a9a..402e9b0d6650 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,10 @@ +GIT + remote: https://github.com/sempervictus/rex-core.git + revision: 7b5e2954d3be6375f911ee359b048a91f881c222 + branch: structure/move_logging_to_core + specs: + rex-core (0.1.29) + PATH remote: . specs: @@ -345,7 +352,6 @@ GEM rex-core rex-struct2 rex-text - rex-core (0.1.28) rex-encoder (0.1.6) metasm rex-arch @@ -510,6 +516,7 @@ DEPENDENCIES pry-byebug rake redcarpet + rex-core! rspec-rails rspec-rerun rubocop @@ -519,4 +526,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.1.4 + 2.2.33 diff --git a/lib/rex/logging.rb b/lib/rex/logging.rb deleted file mode 100644 index eb2fb80bacb0..000000000000 --- a/lib/rex/logging.rb +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: binary -*- -module Rex::Logging - - -# -# Log severities -# -LOG_ERROR = :error -LOG_DEBUG = :debug -LOG_INFO = :info -LOG_WARN = :warn -LOG_RAW = :raw - -## -# -# Log levels -# -## - -# -# LEV_0 - Default -# -# This log level is the default log level if none is specified. It should be -# used when a log message should always be displayed when logging is enabled. -# Very few log messages should occur at this level aside from necessary -# information logging and error/warning logging. Debug logging at level zero -# is not advised. -# -LEV_0 = 0 - -# -# LEV_1 - Extra -# -# This log level should be used when extra information may be needed to -# understand the cause of an error or warning message or to get debugging -# information that might give clues as to why something is happening. This -# log level should be used only when information may be useful to understanding -# the behavior of something at a basic level. This log level should not be -# used in an exhaustively verbose fashion. -# -LEV_1 = 1 - -# -# LEV_2 - Verbose -# -# This log level should be used when verbose information may be needed to -# analyze the behavior of the framework. This should be the default log -# level for all detailed information not falling into LEV_0 or LEV_1. -# It is recommended that this log level be used by default if you are -# unsure. -# -LEV_2 = 2 - -# -# LEV_3 - Insanity -# -# This log level should contain very verbose information about the -# behavior of the framework, such as detailed information about variable -# states at certain phases including, but not limited to, loop iterations, -# function calls, and so on. This log level will rarely be displayed, -# but when it is the information provided should make it easy to analyze -# any problem. -# -LEV_3 = 3 - -require 'rex/logging/log_dispatcher' -end diff --git a/lib/rex/logging/log_dispatcher.rb b/lib/rex/logging/log_dispatcher.rb deleted file mode 100644 index f85fc86fabe0..000000000000 --- a/lib/rex/logging/log_dispatcher.rb +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: binary -*- -require 'rex/sync' - -module Rex -module Logging - -### -# -# The log dispatcher associates log sources with log sinks. A log source -# is a unique identity that is associated with one and only one log sink. -# For instance, the framework-core registers the 'core' -# -### -class LogDispatcher - - # - # Creates the global log dispatcher instance and initializes it for use. - # - def initialize() - self.log_sinks = {} - self.log_levels = {} - self.log_sinks_lock = Mutex.new - end - - # - # Returns the sink that is associated with the supplied source. - # - def [](src) - sink = nil - - log_sinks_lock.synchronize { - sink = log_sinks[src] - } - - return sink - end - - # - # Calls the source association routie. - # - def []=(src, sink) - store(src, sink) - end - - # - # Associates the supplied source with the supplied sink. If a log level - # has already been defined for the source, the level argument is ignored. - # Use set_log_level to alter it. - # - def store(src, sink, level = 0) - log_sinks_lock.synchronize { - if (log_sinks[src] == nil) - log_sinks[src] = sink - - set_log_level(src, level) if (log_levels[src] == nil) - else - raise( - RuntimeError, - "The supplied log source #{src} is already registered.", - caller) - end - } - end - - # - # Removes a source association if one exists. - # - def delete(src) - sink = nil - - log_sinks_lock.synchronize { - sink = log_sinks[src] - - log_sinks.delete(src) - } - - if (sink) - sink.cleanup - - return true - end - - return false - end - - # - # Performs the actual log operation against the supplied source - # - def log(sev, src, level, msg) - log_sinks_lock.synchronize { - if ((sink = log_sinks[src])) - next if (log_levels[src] and level > log_levels[src]) - - sink.log(sev, src, level, msg) - end - } - end - - # - # This method sets the log level threshold for a given source. - # - def set_level(src, level) - log_levels[src] = level.to_i - end - - # - # This method returns the log level threshold of a given source. - # - def get_level(src) - log_levels.fetch(src, DEFAULT_LOG_LEVEL) - end - - attr_accessor :log_sinks, :log_sinks_lock # :nodoc: - attr_accessor :log_levels # :nodoc: -end - -end -end - -# An instance of the log dispatcher exists in the global namespace, along -# with stubs for many of the common logging methods. Various sources can -# register themselves as a log sink such that logs can be directed at -# various targets depending on where they're sourced from. By doing it -# this way, things like sessions can use the global logging stubs and -# still be directed at the correct log file. -# -### -ExceptionCallStack = "__EXCEPTCALLSTACK__" - -BACKTRACE_LOG_LEVEL = 3 # Equal to LEV_3 -DEFAULT_LOG_LEVEL = 0 # Equal to LEV_3 - -def dlog(msg, src = 'core', level = 0) - $dispatcher.log(LOG_DEBUG, src, level, msg) -end - -# Logs errors in a standard format for each Log Level. -# -# @param msg [String] Contains message from the developer explaining why an error was encountered. -# Can also be an +Exception+, in which case a log is built from the +Exception+ with no accompanying message. -# -# @param src [String] Used to indicate where the error is originating from. Most commonly set to 'core'. -# -# @param log_level [Integer] Indicates the level of logging the message should be recorded at. If log_level is greater than -# the global log level set for +src+, then the log is not recorded. -# -# @param error [Exception] Exception of an error that needs to be logged. For all log messages, the class and message of -# an exception is added to a log message. If the global log level set for +src+ is greater than +BACKTRACE_LOG_LEVEL+, -# then the stack trace for an error is also added to the log message. -# -# (Eg Loop Iterations, Variables, Function Calls). -# -# @return [NilClass]. -def elog(msg, src = 'core', log_level = 0, error: nil) - error = msg.is_a?(Exception) ? msg : error - - if error.nil? || !error.is_a?(Exception) - $dispatcher.log(LOG_ERROR, src, log_level, msg) - else - error_details = "#{error.class} #{error.message}" - if get_log_level(src) >= BACKTRACE_LOG_LEVEL - if error.backtrace - error_details << "\nCall stack:\n#{error.backtrace.join("\n")}" - else - error_details << "\nCall stack:\nNone" - end - end - - if msg.is_a?(Exception) - $dispatcher.log(LOG_ERROR, src, log_level,"#{error_details}") - else - $dispatcher.log(LOG_ERROR, src, log_level,"#{msg} - #{error_details}") - end - end -end - -def wlog(msg, src = 'core', level = 0) - $dispatcher.log(LOG_WARN, src, level, msg) -end - -def ilog(msg, src = 'core', level = 0) - $dispatcher.log(LOG_INFO, src, level, msg) -end - -def rlog(msg, src = 'core', level = 0) - if (msg == ExceptionCallStack) - msg = "\nCall stack:\n" + $@.join("\n") + "\n" - end - - $dispatcher.log(LOG_RAW, src, level, msg) -end - -def log_source_registered?(src) - ($dispatcher[src] != nil) -end - -def register_log_source(src, sink, level = nil) - $dispatcher[src] = sink - - set_log_level(src, level) if (level) -end - -def deregister_log_source(src) - $dispatcher.delete(src) -end - -def set_log_level(src, level) - $dispatcher.set_level(src, level) -end - -def get_log_level(src) - $dispatcher.get_level(src) -end - -# Creates the global log dispatcher -$dispatcher = Rex::Logging::LogDispatcher.new diff --git a/lib/rex/logging/log_sink.rb b/lib/rex/logging/log_sink.rb deleted file mode 100644 index aef54b76f9c2..000000000000 --- a/lib/rex/logging/log_sink.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: binary -*- - -module Rex -module Logging - -### -# -# This abstract interface is what must be implemented by any class -# that would like to register as a log sink on a given LogDispatcher -# instance, such as the Framework object. -# -### -module LogSink - - def cleanup - end - - # - # This method must be implemented by any derived log sink classes and is - # intended to take the supplied parameters and persist them to an arbitrary - # medium. - # - def log(sev, src, level, msg) - raise NotImplementedError - end - -protected - - # - # This method returns the current timestamp in MM/DD/YYYY HH:Mi:SS format. - # - def get_current_timestamp - return ::Time.now.strftime("%m/%d/%Y %H:%M:%S") - end - -end - -end -end diff --git a/lib/rex/logging/log_sink_factory.rb b/lib/rex/logging/log_sink_factory.rb deleted file mode 100644 index aad2d0bf0633..000000000000 --- a/lib/rex/logging/log_sink_factory.rb +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: binary -*- - - -module Rex - module Logging - - ### - # - # LogSinkFactory can instantiate a LogSink based on the given name. - # - ### - module LogSinkFactory - # Creates a new log sink of the given name. If no name is provided, a default - # Flatfile log sink is chosen - # - # @param [String] name The name of the required log sink within Rex::Logging::Sinks - # @param [Array] attrs The attributes to use with the given log sink - # @return [Rex::Logging::LogSink] The newly created log sink - def self.new(name = nil, *attrs) - name ||= Rex::Logging::Sinks::Flatfile.name.demodulize - raise NameError unless available_sinks.include?(name.to_sym) - - log_sink = Rex::Logging::Sinks.const_get(name) - log_sink.new(*attrs) - rescue NameError - raise Rex::ArgumentError, "Could not find logger #{name}, expected one of #{available_sinks.join(', ')}" - end - - # Returns a list of the available sinks that can be created by this factory - # - # @return [Array] The available sinks that can be created by this factory - def self.available_sinks - Rex::Logging::Sinks.constants - [Rex::Logging::Sinks::Stream.name.demodulize.to_sym] - end - end - end -end diff --git a/lib/rex/logging/sinks/flatfile.rb b/lib/rex/logging/sinks/flatfile.rb deleted file mode 100644 index 8391916cda8c..000000000000 --- a/lib/rex/logging/sinks/flatfile.rb +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: binary -*- -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against a -# file on disk. -# -### -class Flatfile < Rex::Logging::Sinks::Stream - - # - # Creates a flatfile log sink instance that will be configured to log to - # the supplied file path. - # - def initialize(file) - super(File.new(file, 'a')) - end - -end - -end end end diff --git a/lib/rex/logging/sinks/stderr.rb b/lib/rex/logging/sinks/stderr.rb deleted file mode 100644 index f5aefdfe0389..000000000000 --- a/lib/rex/logging/sinks/stderr.rb +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: binary -*- -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against stderr -### -class Stderr < Rex::Logging::Sinks::Stream - - # - # Creates a log sink instance that will be configured to log to stderr - # - def initialize(*_attrs) - super($stderr) - end - -end - -end end end diff --git a/lib/rex/logging/sinks/stdout.rb b/lib/rex/logging/sinks/stdout.rb deleted file mode 100644 index a4c5c473b2ec..000000000000 --- a/lib/rex/logging/sinks/stdout.rb +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: binary -*- -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against stdout -### -class Stdout < Rex::Logging::Sinks::Stream - - # - # Creates a log sink instance that will be configured to log to stdout - # - def initialize(*_attrs) - super($stdout) - end - -end - -end end end diff --git a/lib/rex/logging/sinks/stdout_without_timestamps.rb b/lib/rex/logging/sinks/stdout_without_timestamps.rb deleted file mode 100644 index 5501ecd9b538..000000000000 --- a/lib/rex/logging/sinks/stdout_without_timestamps.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: binary -*- - - -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against stdout -### -class StdoutWithoutTimestamps < Rex::Logging::Sinks::Stream - - # - # Creates a log sink instance that will be configured to log to stdout - # - def initialize(*_attrs) - super($stdout) - end - - # - # Writes log data to a stream - # - # - # Writes log data to a stream - # - def log(sev, src, level, msg) # :nodoc: - if sev == LOG_RAW - stream.write(msg) - else - stream.write("[#{log_code_for(sev)}(#{level})] #{src}: #{msg}\n") - end - - stream.flush - end - -end - -end end end diff --git a/lib/rex/logging/sinks/stream.rb b/lib/rex/logging/sinks/stream.rb deleted file mode 100644 index a763cb29b343..000000000000 --- a/lib/rex/logging/sinks/stream.rb +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: binary -*- - - -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against a stream -### -class Stream - - include Rex::Logging::LogSink - - def initialize(stream) - @stream = stream - end - - # - # Writes log data to a stream - # - def log(sev, src, level, msg) # :nodoc: - if sev == LOG_RAW - stream.write(msg) - else - stream.write("[#{get_current_timestamp}] [#{log_code_for(sev)}(#{level})] #{src}: #{msg}\n") - end - - stream.flush - end - - def cleanup # :nodoc: - stream.close - end - - protected - - attr_accessor :stream # :nodoc: - - # - # This method returns the corresponding log code for the given severity - # - def log_code_for(sev) - code = 'i' - - case sev - when LOG_DEBUG - code = 'd' - when LOG_ERROR - code = 'e' - when LOG_INFO - code = 'i' - when LOG_WARN - code = 'w' - end - - code - end - -end - -end end end diff --git a/lib/rex/logging/sinks/timestamp_colorless_flatfile.rb b/lib/rex/logging/sinks/timestamp_colorless_flatfile.rb deleted file mode 100644 index 50123f1ea634..000000000000 --- a/lib/rex/logging/sinks/timestamp_colorless_flatfile.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: binary -*- - - -module Rex -module Logging -module Sinks - -### -# -# This class implements the LogSink interface and backs it against a -# file on disk. The logged messages will have their colors and trailing -# whitespace removed -# -### -class TimestampColorlessFlatfile < Flatfile - def log(sev, src, level, msg) # :nodoc: - return unless msg.present? - if sev == LOG_RAW - msg = msg.gsub(/\x1b\[[0-9;]*[mG]/,'').gsub(/[\x01-\x02]/, ' ').gsub(/\s+$/,'') - msg = "[#{get_current_timestamp}] #{msg}\n" - end - super(sev, src, level, msg) - end -end - -end end end