module Msf ### # # This class hooks all session creation events and plays a sound # ### class Plugin::EventSounds < Msf::Plugin attr_accessor :theme, :base, :queue, :queue_thread include Msf::SessionEvent def play_sound(event) self.queue.push(event) end def on_session_open(session) event = 'session_open_' + session.type play_sound(event) end def on_session_close(session, reason='') sid = session.sid.to_s play_sound('session') sid.unpack("C*").each do |c| play_sound("num" + [c].pack("C")) end play_sound('closed') end def on_plugin_load play_sound('plugin_load') end def on_plugin_unload play_sound('plugin_unload') end def start_sound_queue self.queue_thread = Thread.new do begin while(true) while(event = self.queue.shift) path = ::File.join(self.base, self.theme, "#{event}.wav") if(::File.exists?(path)) Rex::Compat.play_sound(path) else print_status("Warning: sound file not found: #{path}") end end select(nil, nil, nil, 0.25) end rescue ::Exception => e print_status("Sound plugin: fatal error #{e} #{e.backtrace}") end end end def stop_sound_queue self.queue_thread.kill if self.queue_thread self.queue_thread = nil self.queue = [] end def initialize(framework, opts) super self.queue = [] self.theme = opts['theme'] || 'default' self.base = File.join(Msf::Config.install_root, "data", "sounds") self.framework.events.add_session_subscriber(self) start_sound_queue self.on_plugin_load end def cleanup self.on_plugin_unload self.framework.events.remove_session_subscriber(self) stop_sound_queue end def name "sounds" end def desc "Automatically plays a sound when various framework events occur" end end end