Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

event_dispatcher.rb 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. # -*- coding: binary -*-
  2. require 'msf/core'
  3. module Msf
  4. ###
  5. #
  6. # This event subscriber class exposes methods that are called when internal
  7. # framework events occur, such as the loading and creation of a module.
  8. #
  9. ###
  10. module GeneralEventSubscriber
  11. #
  12. # Called when a module is loaded
  13. #
  14. def on_module_load(refname, klass)
  15. end
  16. #
  17. # Called when a new module instance is created
  18. #
  19. def on_module_created(instance)
  20. end
  21. #
  22. # Called when a module is run
  23. #
  24. def on_module_run(instance)
  25. end
  26. #
  27. # Called when a module finishes
  28. #
  29. def on_module_complete(instance)
  30. end
  31. #
  32. # Called when a module raises an exception
  33. #
  34. def on_module_error(instance, exception)
  35. end
  36. end
  37. ###
  38. #
  39. # This class manages subscriber registration and is the entry point
  40. # for dispatching various events that occur for modules, such as
  41. # exploit results and auxiliary module data. The framework
  42. # and external modules can register themselves as subscribers to
  43. # various events such that they can perform custom actions when
  44. # a specific event or events occur.
  45. #
  46. ###
  47. class EventDispatcher
  48. include Framework::Offspring
  49. def initialize(framework)
  50. self.framework = framework
  51. self.general_event_subscribers = []
  52. self.custom_event_subscribers = []
  53. self.exploit_event_subscribers = []
  54. self.session_event_subscribers = []
  55. self.db_event_subscribers = []
  56. self.ui_event_subscribers = []
  57. end
  58. ##
  59. #
  60. # Subscriber registration
  61. #
  62. ##
  63. #
  64. # This method adds a general subscriber. General subscribers receive
  65. # notifications when all events occur.
  66. #
  67. def add_general_subscriber(subscriber)
  68. add_event_subscriber(general_event_subscribers, subscriber)
  69. end
  70. #
  71. # Removes a general subscriber.
  72. #
  73. def remove_general_subscriber(subscriber)
  74. remove_event_subscriber(general_event_subscribers, subscriber)
  75. end
  76. #
  77. # This method adds a db event subscriber. db event subscribers
  78. # receive notifications when events occur that pertain to db changes.
  79. # The subscriber provided must implement the DatabaseEvent module methods
  80. # in some form.
  81. #
  82. def add_db_subscriber(subscriber)
  83. add_event_subscriber(db_event_subscribers, subscriber)
  84. end
  85. #
  86. # Removes a db event subscriber.
  87. #
  88. def remove_db_subscriber(subscriber)
  89. remove_event_subscriber(db_event_subscribers, subscriber)
  90. end
  91. #
  92. # This method adds an exploit event subscriber. Exploit event subscribers
  93. # receive notifications when events occur that pertain to exploits, such as
  94. # the success or failure of an exploitation attempt. The subscriber
  95. # provided must implement the ExploitEvent module methods in some form.
  96. #
  97. def add_exploit_subscriber(subscriber)
  98. add_event_subscriber(exploit_event_subscribers, subscriber)
  99. end
  100. #
  101. # Removes an exploit event subscriber.
  102. #
  103. def remove_exploit_subscriber(subscriber)
  104. remove_event_subscriber(exploit_event_subscribers, subscriber)
  105. end
  106. #
  107. # This method adds a session event subscriber. Session event subscribers
  108. # receive notifications when sessions are opened and closed. The
  109. # subscriber provided must implement the SessionEvent module methods in
  110. # some form.
  111. #
  112. def add_session_subscriber(subscriber)
  113. add_event_subscriber(session_event_subscribers, subscriber)
  114. end
  115. #
  116. # Removes a session event subscriber.
  117. #
  118. def remove_session_subscriber(subscriber)
  119. remove_event_subscriber(session_event_subscribers, subscriber)
  120. end
  121. ##
  122. #
  123. # General events
  124. #
  125. ##
  126. #
  127. # Called when a module is loaded into the framework. This, in turn,
  128. # notifies all registered general event subscribers.
  129. #
  130. # This is covered by the method_missing logic, but defining it manually
  131. # reduces startup time by about 10%.
  132. #
  133. def on_module_load(name, mod)
  134. general_event_subscribers.each { |subscriber|
  135. subscriber.on_module_load(name, mod)
  136. }
  137. end
  138. #
  139. # Capture incoming events and pass them off to the subscribers
  140. #
  141. # When receiving an on_* event, look for a subscriber type matching the
  142. # type of the event. If one exists, send the event on to each subscriber
  143. # of that type. Otherwise, try to send the event each of the general
  144. # subscribers.
  145. #
  146. # Event method names should be like "on_<type>_<event>", e.g.:
  147. # on_exploit_success.
  148. #
  149. def method_missing(name, *args)
  150. event,type,rest = name.to_s.split("_", 3)
  151. subscribers = "#{type}_event_subscribers"
  152. found = false
  153. case event
  154. when "on"
  155. if respond_to?(subscribers, true)
  156. found = true
  157. self.send(subscribers).each do |sub|
  158. next if not sub.respond_to?(name, true)
  159. sub.send(name, *args)
  160. end
  161. else
  162. (general_event_subscribers + custom_event_subscribers).each do |sub|
  163. next if not sub.respond_to?(name, true)
  164. sub.send(name, *args)
  165. found = true
  166. end
  167. end
  168. when "add"
  169. if respond_to?(subscribers, true)
  170. found = true
  171. add_event_subscriber(self.send(subscribers), *args)
  172. end
  173. when "remove"
  174. if respond_to?(subscribers, true)
  175. found = true
  176. remove_event_subscriber(self.send(subscribers), *args)
  177. end
  178. end
  179. return found
  180. end
  181. protected
  182. #
  183. # Adds an event subscriber to the supplied subscriber array.
  184. #
  185. def add_event_subscriber(array, subscriber) # :nodoc:
  186. array << subscriber
  187. end
  188. #
  189. # Removes an event subscriber from the supplied subscriber array.
  190. #
  191. def remove_event_subscriber(array, subscriber) # :nodoc:
  192. array.delete(subscriber)
  193. end
  194. attr_accessor :custom_event_subscribers # :nodoc:
  195. attr_accessor :db_event_subscribers # :nodoc:
  196. attr_accessor :exploit_event_subscribers # :nodoc:
  197. attr_accessor :general_event_subscribers # :nodoc:
  198. attr_accessor :session_event_subscribers # :nodoc:
  199. attr_accessor :ui_event_subscribers # :nodoc:
  200. end
  201. end