class Arachni::Plugin::Manager
Holds and manages the {Plugins}.
@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>
Constants
- DEFAULT
Expressions matching default plugins.
- NAMESPACE
The namespace under which all plugins exist.
Public Class Methods
new( framework )
click to toggle source
@param [Arachni::Framework] framework
Framework instance.
Calls superclass method
Arachni::Component::Manager::new
# File lib/arachni/plugin/manager.rb, line 36 def initialize( framework ) super( framework.options.paths.plugins, NAMESPACE ) @framework = framework @jobs = {} end
reset()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 273 def self.reset State.plugins.clear Data.plugins.clear remove_constants( NAMESPACE ) end
Public Instance Methods
block()
click to toggle source
Blocks until all plug-ins have finished executing.
# File lib/arachni/plugin/manager.rb, line 162 def block while busy? print_debug print_debug "Waiting on #{@jobs.size} plugins to finish:" print_debug job_names.join( ', ' ) print_debug synchronize do @jobs.select! { |_ ,j| j.alive? } end sleep 0.1 end nil end
busy?()
click to toggle source
@return [Bool]
`false` if all plug-ins have finished executing, `true` otherwise.
# File lib/arachni/plugin/manager.rb, line 226 def busy? @jobs.any? end
create( name, options = {} )
click to toggle source
# File lib/arachni/plugin/manager.rb, line 157 def create( name, options = {} ) self[name].new( @framework, options ) end
data()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 265 def data Data.plugins end
default()
click to toggle source
@return [Array<String>]
Components to load, by name.
# File lib/arachni/plugin/manager.rb, line 53 def default parse DEFAULT end
Also aliased as: defaults
job_names()
click to toggle source
@return [Array]
Names of all running plug-ins.
# File lib/arachni/plugin/manager.rb, line 232 def job_names @jobs.keys end
jobs()
click to toggle source
@return [Hash{String=>Thread}]
All the running threads.
# File lib/arachni/plugin/manager.rb, line 238 def jobs @jobs end
kill( name )
click to toggle source
Kills a plug-in by ‘name`.
@param [String] name
# File lib/arachni/plugin/manager.rb, line 245 def kill( name ) synchronize do job = @jobs.delete( name.to_sym ) return true if job && job.kill end false end
killall()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 253 def killall synchronize do @jobs.values.each(&:kill) @jobs.clear true end end
load_default()
click to toggle source
Loads the default plugins.
@see DEFAULT
# File lib/arachni/plugin/manager.rb, line 46 def load_default load DEFAULT end
Also aliased as: load_defaults
reset()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 278 def reset killall clear self.class.reset end
restore()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 194 def restore schedule.each do |name, options| @jobs[name] = Thread.new do exception_jail( false ) do if state.include? name Thread.current[:instance] = create( name, state[name][:options] ) Thread.current[:instance].restore state[name][:data] else Thread.current[:instance] = create( name, options ) Thread.current[:instance].prepare end Thread.current[:instance].run Thread.current[:instance].clean_up synchronize do @jobs.delete name end end end end return if @jobs.empty? print_status 'Waiting for plugins to settle...' sleep 1 nil end
results()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 269 def results data.results end
run()
click to toggle source
Runs each plug-in in its own thread.
@raise [Error::UnsatisfiedDependency]
If the environment is {#sane_env? not sane}.
# File lib/arachni/plugin/manager.rb, line 62 def run print_status 'Preparing plugins...' schedule.each do |name, options| instance = create( name, options ) exception_jail do instance.prepare end rescue next @jobs[name] = Thread.new do exception_jail( false ) do Thread.current[:instance] = instance Thread.current[:instance].run Thread.current[:instance].clean_up end synchronize do @jobs.delete name end end end print_status '... done.' end
sane_env?( plugin )
click to toggle source
Checks
whether or not the environment satisfies all plugin dependencies.
@return [TrueClass, Hash]
`true` if the environment is sane, a hash with errors otherwise.
# File lib/arachni/plugin/manager.rb, line 142 def sane_env?( plugin ) gem_errors = [] plugin.gems.each do |gem| begin require gem rescue LoadError gem_errors << gem end end return { gem_errors: gem_errors } if !gem_errors.empty? true end
schedule()
click to toggle source
@return [Hash]
Sorted plugins (by priority) with their prepared options.
@raise [Error::UnsatisfiedDependency]
If the environment is not {#sane_env? sane}.
# File lib/arachni/plugin/manager.rb, line 93 def schedule ordered = [] unordered = [] loaded.each do |name| ph = { name => self[name] } if (order = self[name].info[:priority]) ordered[order] ||= [] ordered[order] << ph else unordered << ph end end ordered << unordered ordered.flatten! ordered.compact! ordered.inject({}) do |h, ph| name = ph.keys.first plugin = ph.values.first if (ret = sane_env?( plugin )) != true deps = '' if !ret[:gem_errors].empty? print_bad "[#{name}] The following plug-in dependencies aren't satisfied:" ret[:gem_errors].each { |gem| print_bad "\t* #{gem}" } deps = ret[:gem_errors].join( ' ' ) print_bad 'Try installing them by running:' print_bad "\tgem install #{deps}" end fail Error::UnsatisfiedDependency, "Plug-in dependencies not met: #{name} -- #{deps}" end h[name.to_sym] = prepare_options( name, plugin, @framework.options.plugins[name] ) h end end
state()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 261 def state State.plugins end
suspend()
click to toggle source
# File lib/arachni/plugin/manager.rb, line 178 def suspend @jobs.dup.each do |name, job| next if !job.alive? plugin = job[:instance] state.store( name, data: plugin.suspend, options: plugin.options ) kill name end nil end