From 4e124436e1a3d77717ef14442f0ea4097be2d239 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Sun, 22 May 2005 02:50:35 +0000 Subject: [PATCH] testing global log registration, spoonm's going to hate it! git-svn-id: file:///home/svn/incoming/trunk@2500 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/framework.rb | 2 - lib/msf/shared/logging/LogDispatcher.rb | 146 ++++++++++++++++------- lib/msf/shared/logging/LogSink.rb | 24 +--- lib/msf/shared/logging/sinks/Flatfile.rb | 12 +- user_interfaces/test.rb | 4 +- 5 files changed, 110 insertions(+), 78 deletions(-) diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index fff81dd9d1..241572ecf6 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -13,8 +13,6 @@ module Msf ### class Framework - include Msf::Logging::LogDispatcher - def initialize() self.events = EventDispatcher.new # self.encoders = EncoderManager.new diff --git a/lib/msf/shared/logging/LogDispatcher.rb b/lib/msf/shared/logging/LogDispatcher.rb index b13e765418..d285f936ed 100644 --- a/lib/msf/shared/logging/LogDispatcher.rb +++ b/lib/msf/shared/logging/LogDispatcher.rb @@ -8,61 +8,119 @@ module Logging # LogDispatcher # ------------- # -# This interface is included in the Framework class and is used to provide a -# common interface for dispatching logs to zero or more registered log sinks. -# Log sinks are typically backed against arbitrary storage mediums, such as a -# flatfile, a database, or the console. The log dispatcher itself is really -# just a log sink that backs itself against zero or more log sinks rather than -# a file, database, or other persistent storage. +# 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' # ### -module LogDispatcher - - include Msf::Logging::LogSink +class LogDispatcher def initialize() - initialize_log_dispatcher - end - - # - # Log sink registration - # - - def add_log_sink(sink) - log_sinks_rwlock.synchronize_write { - log_sinks << sink - } - end - - def remove_log_sink(sink) - log_sinks_rwlock.synchronize_write { - sink.cleanup - - log_sinks.delete(sink) - } - end - - # - # Log dispatching - # -protected - - def initialize_log_dispatcher - self.log_sinks = [] + self.log_sinks = {} self.log_sinks_rwlock = ReadWriteLock.new end - def log(sev, level, msg, from) + # Returns the sink that is associated with the supplied source + def [](src) + sink = nil + log_sinks_rwlock.synchronize_read { - log_sinks.each { |sink| - sink.dispatch_log(sev, level, msg, from) - } + sink = log_sinks[src] + } + + return sink + end + + # Calls the source association routnie + def []=(src, sink) + store(src, sink) + end + + # Associates the supplied source with the supplied sink + def store(src, sink) + log_sinks_rwlock.synchronize_write { + if (log_sinks[src] == nil) + log_sinks[src] = sink + else + raise( + RuntimeError, + "The supplied log source #{src} is already registered.", + caller) + end } end - attr_accessor :log_sinks - attr_accessor :log_sinks_rwlock + # Removes a source association if one exists + def delete(src) + sink = nil + log_sinks_rwlock.synchronize_write { + 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, from) + log_sinks_rwlock.synchronize_read { + if ((sink = log_sinks[src])) + sink.log(sev, src, level, msg, from) + end + } + end + + attr_accessor :log_sinks, :log_sinks_rwlock end -end; 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. +# +### +def dlog(msg, src = 'core', level = 0, from = caller) + $dispatcher.log(Msf::LOG_DEBUG, src, level, msg, from) +end + +def elog(msg, src = 'core', level = 0, from = caller) + $dispatcher.log(Msf::LOG_ERROR, src, level, msg, from) +end + +def wlog(msg, src = 'core', level = 0, from = caller) + $dispatcher.log(Msf::LOG_WARN, src, level, msg, from) +end + +def ilog(msg, src = 'core', level = 0, from = caller) + $dispatcher.log(Msf::LOG_INFO, src, level, msg, from) +end + +def rlog(msg, src = 'core', level = 0, from = caller) + $dispatcher.log(Msf::LOG_RAW, src, level, msg, from) +end + +def register_log_source(src, sink) + $dispatcher[src] = sink +end + +def deregister_log_source(src, sink) + $dispatcher.delete(src) +end + +# Creates the global log dispatcher +$dispatcher = Msf::Logging::LogDispatcher.new diff --git a/lib/msf/shared/logging/LogSink.rb b/lib/msf/shared/logging/LogSink.rb index 77117921a5..ecfe2f9d2d 100644 --- a/lib/msf/shared/logging/LogSink.rb +++ b/lib/msf/shared/logging/LogSink.rb @@ -18,32 +18,12 @@ module LogSink def cleanup end - def dlog(level, msg, from = caller) - log(LOG_DEBUG, level, msg, from) - end - - def elog(level, msg, from = caller) - log(LOG_ERROR, level, msg, from) - end - - def wlog(level, msg, from = caller) - log(LOG_WARN, level, msg, from) - end - - def ilog(level, msg, from = caller) - log(LOG_INFO, level, msg, from) - end - - def rlog(msg) - log(LOG_RAW, 0, msg, nil) + def log(sev, src, level, msg, from) + raise NotImplementedError end protected - def log(sev, level, msg, from) - raise NotImplementedError - end - def get_current_timestamp return Time.now.strftime("%m/%d/%Y %H:%M:%S") end diff --git a/lib/msf/shared/logging/sinks/Flatfile.rb b/lib/msf/shared/logging/sinks/Flatfile.rb index 30af7f301a..1a937fb764 100644 --- a/lib/msf/shared/logging/sinks/Flatfile.rb +++ b/lib/msf/shared/logging/sinks/Flatfile.rb @@ -17,26 +17,22 @@ class Flatfile def initialize(file) self.fd = File.new(file, "a") - - ilog(0, "Logging initialized.") end def cleanup - ilog(0, "Logging finished.") - fd.close end -protected - - def log(sev, level, msg, from) + def log(sev, src, level, msg, from) if (sev == LOG_RAW) fd.write(msg) else - fd.write("[#{get_current_timestamp}] (sev=#{sev},level=#{level}): #{msg}\n") + fd.write("[#{get_current_timestamp}] (src=#{src},sev=#{sev},level=#{level}): #{msg}\n") end end +protected + attr_accessor :fd end diff --git a/user_interfaces/test.rb b/user_interfaces/test.rb index d50a1a8fd9..8ac9f0645f 100755 --- a/user_interfaces/test.rb +++ b/user_interfaces/test.rb @@ -4,9 +4,9 @@ require 'Msf/Core' require 'Encoders/IA32/JmpCallAdditive' require 'Nops/IA32/SingleByte' -framework = Msf::Framework.new +register_log_source('core', Msf::Logging::Sinks::Flatfile.new('/tmp/msfcli.log')) -framework.add_log_sink(Msf::Logging::Sinks::Flatfile.new('/tmp/msfcli.log')) +dlog('yo yo yo') #encoder = framework.encoders.instantiate('gen_ia32_jmp_call_additive') encoder = Msf::Encoders::Generic::IA32::JmpCallAdditive.new