Class: Arachni::Plugin::Manager

Inherits:
ComponentManager show all
Includes:
Module::Utilities
Defined in:
lib/arachni/plugin/manager.rb

Overview

Holds and manages the plugins.

@author: Tasos “Zapotek” Laskos

<[email protected]>
<[email protected]>

@version: 0.1.1

Direct Known Subclasses

RPC::Server::Plugin::Manager

Constant Summary collapse

DEFAULT =
[
    'defaults/*'
]

Constants inherited from ComponentManager

ComponentManager::EXCLUDE, ComponentManager::WILDCARD

Instance Method Summary collapse

Methods included from Module::Utilities

#exception_jail, #get_path, #hash_keys_to_str, #normalize_url, #read_file, #seed, #uri_decode, #uri_encode, #uri_parse, #uri_parser, #url_sanitize

Methods inherited from ComponentManager

#[], #available, #load, #name_to_path, #parse, #path_to_name, #paths, #prep_opts, #wilcard_to_names

Methods included from UI::Output

#buffer, #debug!, #debug?, #flush_buffer, #mute!, #muted?, #only_positives!, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_pp, #print_error, #print_error_backtrace, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, #uncap_buffer!, #unmute!, #verbose!, #verbose?

Constructor Details

#initialize(framework) ⇒ Manager

Returns a new instance of Manager.

Parameters:



40
41
42
43
44
45
# File 'lib/arachni/plugin/manager.rb', line 40

def initialize( framework )
    super( framework.opts.dir['plugins'], Arachni::Plugins )
    @framework = framework

    @jobs = []
end

Instance Method Details

#block!Object

Blocks until all plug-ins have finished executing.



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/arachni/plugin/manager.rb', line 123

def block!
    while( !@jobs.empty? )

        print_debug
        print_debug( "Waiting on the following (#{@jobs.size}) plugins to finish:" )
        print_debug( job_names.join( ', ' ) )
        print_debug

        @jobs.delete_if { |j| !j.alive? }
        ::IO::select( nil, nil, nil, 1 )
    end
end

#busy?Bool

Will return false if all plug-ins have finished executing.

Returns:

  • (Bool)


141
142
143
# File 'lib/arachni/plugin/manager.rb', line 141

def busy?
    !@jobs.reject{ |j| j.alive? }.empty?
end

#create(name) ⇒ Object



115
116
117
118
# File 'lib/arachni/plugin/manager.rb', line 115

def create( name )
    opts = @framework.opts.plugins[name]
    self[name].new( @framework, prep_opts( name, self[name], opts ) )
end

#get(name) ⇒ Thread

Gets a running plug-in by name.

Parameters:

Returns:

  • (Thread)


181
182
183
184
# File 'lib/arachni/plugin/manager.rb', line 181

def get( name )
    @jobs.each { |job| return job if job[:name] == name }
    return
end

#job_namesArray

Returns the names of the running plug-ins.

Returns:



150
151
152
# File 'lib/arachni/plugin/manager.rb', line 150

def job_names
    @jobs.map{ |j| j[:name] }
end

#jobsArray<Thread>

Returns all the running threads.

Returns:



159
160
161
# File 'lib/arachni/plugin/manager.rb', line 159

def jobs
    @jobs
end

#kill(name) ⇒ Object

Kills a plug-in by name.

Parameters:



168
169
170
171
172
# File 'lib/arachni/plugin/manager.rb', line 168

def kill( name )
    job = get( name )
    return job.kill if job
    return nil
end

#load_defaults!Object



47
48
49
# File 'lib/arachni/plugin/manager.rb', line 47

def load_defaults!
    load( DEFAULT )
end

#runObject

Runs each plug-in in its own thread.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/arachni/plugin/manager.rb', line 54

def run
    i = 0
    each {
        |name, plugin|

        if( ret = sane_env?( plugin ) ) != true
            if !ret[:gem_errors].empty?
                print_error( "[#{name}] The following plug-in dependencies aren't satisfied:" )
                ret[:gem_errors].each {
                   |gem|
                    print_info( "\t* #{gem}" )
                }

                print_info( "Try installing them by running:" )
                print_info( "\tgem install #{ret[:gem_errors].join( ' ' )}" )
            end

            raise
        end

        @jobs << Thread.new {

            exception_jail( false ) {
                Thread.current[:name] = name

                plugin_new = create( name )
                plugin_new.prepare
                plugin_new.run
                plugin_new.clean_up
            }

        }

        i += 1
    }

    if i > 0
        print_status( 'Waiting for plugins to settle...' )
        ::IO::select( nil, nil, nil, 1 )
    end
end

#sane_env?(plugin) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/arachni/plugin/manager.rb', line 96

def sane_env?( plugin )
    gem_errors = []

    plugin.gems.each {
        |gem|
        begin
            require gem
        rescue Exception => e
            gem_errors << gem
        end
    }

    return {
        :gem_errors => gem_errors
    } if !gem_errors.empty?

    return true
end