Class: Arachni::RPC::XML::Server::Dispatcher

Inherits:
Base
  • Object
show all
Includes:
Module::Utilities, UI::Output, Sys
Defined in:
lib/rpc/xml/server/dispatcher.rb

Overview

Dispatcher class

Dispatches XML-RPC servers on demand providing a centralised environment for multiple XMLRPC clients and allows for extensive process monitoring.

The process goes something like this:

* a client issues a 'dispatch' call
* the dispatcher starts a new XMLRPC server on a random port
* the dispatcher returns the port of the XMLRPC server to the client
* the client connects to the XMLRPC server listening on that port and does his business

Once the client finishes using the XMLRPC server it must shut it down.<br/> If it doesn’t the system will be eaten away by idle instances of XMLRPC servers.

@author: Tasos “Zapotek” Laskos

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

@version: 0.1.1

Instance Method Summary collapse

Methods included from UI::Output

#buffer, #debug!, #debug?, #flush_buffer, #mute!, #muted?, #only_positives!, #only_positives?, #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?, #unmute!, #verbose!, #verbose?

Methods included from Module::Utilities

#exception_jail, #get_path, #normalize_url, #read_file, #seed

Methods inherited from Base

#add_handler, #alive?

Constructor Details

#initialize(opts) ⇒ Dispatcher

Returns a new instance of Dispatcher.



53
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
# File 'lib/rpc/xml/server/dispatcher.rb', line 53

def initialize( opts )

    banner

    @opts = opts
    @opts.rpc_port  ||= 7331
    @opts.pool_size ||= 5

    if opts.help
        print_help
        exit 0
    end

    super( @opts )

    prep_logging

    print_status( 'Initing XMLRPC Server...' )

    add_handler( "dispatcher", self )

    # trap interupts and exit cleanly when required
    trap( 'HUP' ) { shutdown }
    trap( 'INT' ) { shutdown }

    @jobs = []
    @pool = Queue.new

    print_status( 'Warming up the pool...' )
    prep_pool
    print_status( 'Done.' )

    print_status( 'Initialization complete.' )

end

Instance Method Details

Outputs the Arachni banner.<br/> Displays version number, revision number, author details etc.



185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rpc/xml/server/dispatcher.rb', line 185

def banner

    puts 'Arachni - Web Application Security Scanner Framework
   Author: Tasos "Zapotek" Laskos <[email protected]>
                                  <[email protected]>
           (With the support of the community and the Arachni Team.)

   Website:       http://github.com/Zapotek/arachni
   Documentation: http://github.com/Zapotek/arachni/wiki'
    puts
    puts

end

#dispatch(owner = 'unknown') ⇒ Hash

Dispatches an XMLRPC server instance from the pool

Parameters:

  • owner (String) (defaults to: 'unknown')

    an owner assign to the dispatched XMLRPC server

Returns:

  • (Hash)

    includes port number, owner, clock info and proc info



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/rpc/xml/server/dispatcher.rb', line 108

def dispatch( owner = 'unknown' )

    # just to make sure...
    owner = owner.to_s
    cjob  = @pool.pop
    cjob['owner']     = owner
    cjob['starttime'] = Time.now

    print_status( "Server dispatched -- PID: #{cjob['pid']} - " +
        "Port: #{cjob['port']} - Owner: #{cjob['owner']}" )

    prep_pool

    @jobs << cjob

    return job( cjob['pid'] )
end

#job(pid) ⇒ Hash

Returns proc info for a given pid

Parameters:

  • pid (Fixnum)

Returns:

  • (Hash)


133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/rpc/xml/server/dispatcher.rb', line 133

def job( pid )
    @jobs.each {
        |i|
        cjob = i.dup
        if cjob['pid'] == pid
            cjob['currtime'] = Time.now
            cjob['age'] = cjob['currtime'] - cjob['birthdate']
            cjob['runtime']  = cjob['currtime'] - cjob['starttime']
            cjob['proc'] =  proc( cjob['pid'] )

            return remove_nils( cjob )
        end
    }
end

#jobsArray<Hash>

Returns proc info for all jobs

Returns:

  • (Array<Hash>)


153
154
155
156
157
158
159
160
161
# File 'lib/rpc/xml/server/dispatcher.rb', line 153

def jobs
    jobs = []
    @jobs.each {
        |cjob|
        proc_info = job( cjob['pid'] )
        jobs << proc_info if proc_info
    }
    return jobs
end


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/rpc/xml/server/dispatcher.rb', line 199

def print_help
    puts <<USAGE
  Usage:  arachni_xmlrpcd \[options\]

  Supported options:

-h
--help                      output this

--port                      specify port to listen to
                                (Default: #{@opts.rpc_port})

--reroute-to-logfile        reroute all output to a logfile under 'logs/'

--pool-size                 how many server workers/processes should be available
                              at any given moment (Default: #{@opts.pool_size})

--debug


SSL --------------------------

(All SSL options will be honored by the dispatched XMLRPC instances as well.)
(Do *not* use encrypted keys!)

--ssl                       use SSL?
                               (If you want encryption without authentication
                                you can skip rest of the SSL options.)

--ssl-pkey   <file>         location of the SSL private key (.pem)
                                (Used to verify the server to the clients.)

--ssl-cert   <file>         location of the SSL certificate (.pem)
                                (Used to verify the server to the clients.)

--ssl-ca     <file>         location of the CA certificate (.pem)
                                (Used to verify the clients to the server.)
USAGE
end

#runObject

Starts the dispatcher’s server



90
91
92
93
# File 'lib/rpc/xml/server/dispatcher.rb', line 90

def run
    print_status( 'Starting the server...' )
    super
end

#shutdownObject



95
96
97
98
99
# File 'lib/rpc/xml/server/dispatcher.rb', line 95

def shutdown
    print_status( 'Shutting down...' )
    super
    print_status( 'Done.' )
end

#statsHash

Returns server stats regarding the jobs and pool

Returns:

  • (Hash)


168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/rpc/xml/server/dispatcher.rb', line 168

def stats
    cjobs    = jobs( )
    running  = cjobs.reject{ |job| job['proc'].empty? }
    finished = cjobs - running

    return {
        'running_jobs'    => running,
        'finished_jobs'   => finished,
        'init_pool_size'  => @opts.pool_size,
        'curr_pool_size'  => @pool.size
    }
end