Class: Arachni::UI::Web::Server
- Defined in:
- lib/ui/web/server.rb
Constant Summary collapse
- HELPER_OWNER =
This will be used for the “owner” field of the helper instance
"WebUI helper"
Class Method Summary collapse
- .prep_webrick ⇒ Object
-
.run!(options = {}) ⇒ Object
override run! using this patch: github.com/sinatra/sinatra/pull/132.
Instance Method Summary collapse
- #component_cache_filled? ⇒ Boolean
-
#connect_to_instance(port) ⇒ Object
Provides an easy way to connect to an instance by port.
-
#dispatcher ⇒ Object
Provides easy access to the dispatcher and handles failure.
-
#dispatcher_stats ⇒ Object
Provides statistics about running jobs etc using the dispatcher.
-
#ensure_dispatcher ⇒ Bool
Makes sure that we have a dispatcher, if not it redirects the user to an appropriate error page.
- #ensure_welcomed ⇒ Object
- #escape_hash(hash) ⇒ Object
- #exception_jail(&block) ⇒ Object
- #fill_component_cache ⇒ Object
- #helper_instance ⇒ Object
- #options ⇒ Object
-
#port_to_url(port) ⇒ Object
Converts a port to a URL instance.
- #prep_modules(params) ⇒ Object
-
#prep_opts(params) ⇒ Hash
Prepares form params to be used as options for XMLRPC transmission.
- #prep_plugins(params) ⇒ Object
-
#prep_session ⇒ Object
Makes sure that all systems are go and populates the session with default values.
-
#save_and_shutdown(arachni) ⇒ Object
Saves the report and shuts down the instance.
-
#save_shutdown_and_show(arachni) ⇒ Object
Saves the report, shuts down the instance and returns the content as HTML to be sent back to the user’s browser.
- #show(page, layout = true) ⇒ Object
-
#shutdown_all ⇒ Object
Kills all running instances.
-
#shutdown_zombies ⇒ Integer
Kills all idle instances.
-
#to_i(str) ⇒ Object
Similar to String.to_i but it returns the original object if String is not a number.
- #unescape_hash(hash) ⇒ Object
- #welcomed! ⇒ Object
- #welcomed? ⇒ Boolean
Class Method Details
.prep_webrick ⇒ Object
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
# File 'lib/ui/web/server.rb', line 847 def self.prep_webrick if @@conf['ssl']['server']['key'] pkey = ::OpenSSL::PKey::RSA.new( File.read( @@conf['ssl']['server']['key'] ) ) end if @@conf['ssl']['server']['cert'] cert = ::OpenSSL::X509::Certificate.new( File.read( @@conf['ssl']['server']['cert'] ) ) end if @@conf['ssl']['key'] || @@conf['ssl']['cert'] || @@conf['ssl']['ca'] verification = OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT else verification = ::OpenSSL::SSL::VERIFY_NONE end return { :SSLEnable => @@conf['ssl']['server']['enable'] || false, :SSLVerifyClient => verification, :SSLCertName => [ [ "CN", Arachni::Options.instance.server || ::WEBrick::Utils::getservername ] ], :SSLCertificate => cert, :SSLPrivateKey => pkey, :SSLCACertificateFile => @@conf['ssl']['server']['ca'] } end |
.run!(options = {}) ⇒ Object
override run! using this patch: github.com/sinatra/sinatra/pull/132
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 |
# File 'lib/ui/web/server.rb', line 826 def self.run!( = {} ) set handler = detect_rack_handler handler_name = handler.name.gsub( /.*::/, '' ) # handler specific options use the lower case handler name as hash key, if present handler_opts = [handler_name.downcase.to_sym] || {} puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " + "on #{port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i handler.run self, handler_opts.merge( :Host => bind, :Port => port ) do |server| [ :INT, :TERM ].each { |sig| trap( sig ) { quit!( server, handler_name ) } } set :running, true end rescue Errno::EADDRINUSE => e puts "== Someone is already performing on port #{port}!" end |
Instance Method Details
#component_cache_filled? ⇒ Boolean
379 380 381 382 383 384 385 |
# File 'lib/ui/web/server.rb', line 379 def component_cache_filled? begin return @@modules.size + @@plugins.size rescue return false end end |
#connect_to_instance(port) ⇒ Object
Provides an easy way to connect to an instance by port
209 210 211 212 213 214 215 216 217 |
# File 'lib/ui/web/server.rb', line 209 def connect_to_instance( port ) prep_session begin return Arachni::RPC::XML::Client::Instance.new( , port_to_url( port ) ) rescue Exception raise "Instance on port #{port} has shutdown." end end |
#dispatcher ⇒ Object
Provides easy access to the dispatcher and handles failure
233 234 235 236 237 238 239 |
# File 'lib/ui/web/server.rb', line 233 def dispatcher begin @dispatcher ||= Arachni::RPC::XML::Client::Dispatcher.new( , session[:dispatcher_url] ) rescue Exception => e redirect '/dispatcher_error' end end |
#dispatcher_stats ⇒ Object
Provides statistics about running jobs etc using the dispatcher
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/ui/web/server.rb', line 244 def dispatcher_stats stats = dispatcher.stats stats['running_jobs'].each { |job| begin job['paused'] = connect_to_instance( job['port'] ).framework.paused? rescue end } return stats end |
#ensure_dispatcher ⇒ Bool
Makes sure that we have a dispatcher, if not it redirects the user to an appropriate error page.
444 445 446 447 448 449 450 |
# File 'lib/ui/web/server.rb', line 444 def ensure_dispatcher begin dispatcher.alive? rescue Exception => e redirect '/dispatcher/error' end end |
#ensure_welcomed ⇒ Object
197 198 199 200 201 202 |
# File 'lib/ui/web/server.rb', line 197 def ensure_welcomed return if welcomed? welcomed! redirect '/welcome' end |
#escape_hash(hash) ⇒ Object
327 328 329 330 331 332 333 334 335 |
# File 'lib/ui/web/server.rb', line 327 def escape_hash( hash ) hash.each_pair { |k, v| hash[k] = escape( hash[k] ) if hash[k].is_a?( String ) hash[k] = escape_hash( v ) if v.is_a? Hash } return hash end |
#exception_jail(&block) ⇒ Object
172 173 174 175 176 177 178 |
# File 'lib/ui/web/server.rb', line 172 def exception_jail( &block ) # begin block.call # rescue Errno::ECONNREFUSED => e # erb :error, { :layout => true }, :error => 'Remote server has been shut down.' # end end |
#fill_component_cache ⇒ Object
387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/ui/web/server.rb', line 387 def fill_component_cache if !component_cache_filled? do_shutdown = true else do_shutdown = false end @@modules ||= helper_instance.framework.lsmod.dup @@plugins ||= helper_instance.framework.lsplug.dup # shutdown the helper instance, we got what we wanted helper_instance.service.shutdown! if do_shutdown end |
#helper_instance ⇒ Object
366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/ui/web/server.rb', line 366 def helper_instance begin @@arachni ||= nil if !@@arachni instance = dispatcher.dispatch( HELPER_OWNER ) @@arachni = connect_to_instance( instance['port'] ) end return @@arachni rescue redirect '/dispatcher/error' end end |
#options ⇒ Object
256 257 258 |
# File 'lib/ui/web/server.rb', line 256 def Arachni::Options.instance end |
#port_to_url(port) ⇒ Object
Converts a port to a URL instance.
224 225 226 227 228 |
# File 'lib/ui/web/server.rb', line 224 def port_to_url( port ) uri = URI( session[:dispatcher_url] ) uri.port = port.to_i uri.to_s end |
#prep_modules(params) ⇒ Object
347 348 349 350 351 352 |
# File 'lib/ui/web/server.rb', line 347 def prep_modules( params ) return ['-'] if !params['modules'] mods = params['modules'].keys return ['*'] if mods.empty? return mods end |
#prep_opts(params) ⇒ Hash
Prepares form params to be used as options for XMLRPC transmission
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/ui/web/server.rb', line 280 def prep_opts( params ) need_to_split = [ 'exclude_cookies', 'exclude', 'include' ] cparams = {} params.each_pair { |name, value| next if [ '_csrf', 'modules', 'plugins' ].include?( name ) || ( value.is_a?( String ) && value.empty?) value = true if value == 'on' if name == 'cookiejar' cparams['cookies'] = Arachni::HTTP.( value[:tempfile] ) elsif need_to_split.include?( name ) && value.is_a?( String ) cparams[name] = value.split( "\r\n" ) elsif name == 'redundant' cparams[name] = [] value.split( "\r\n" ).each { |rule| regexp, counter = rule.split( ':', 2 ) cparams[name] << { 'regexp' => regexp, 'count' => counter } } else cparams[name] = to_i( value ) end } if !cparams['audit_links'] && !cparams['audit_forms'] && !cparams['audit_cookies'] && !cparams['audit_headers'] cparams['audit_links'] = true cparams['audit_forms'] = true cparams['audit_cookies'] = true end return cparams end |
#prep_plugins(params) ⇒ Object
354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/ui/web/server.rb', line 354 def prep_plugins( params ) plugins = {} return plugins if !params['plugins'] params['plugins'].keys.each { |name| plugins[name] = params['options'][name] || {} } return plugins end |
#prep_session ⇒ Object
Makes sure that all systems are go and populates the session with default values
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/ui/web/server.rb', line 405 def prep_session session[:dispatcher_url] ||= 'http://localhost:7331' ensure_dispatcher session['opts'] ||= {} session['opts']['settings'] ||= { 'audit_links' => true, 'audit_forms' => true, 'audit_cookies' => true, 'http_req_limit' => 20, 'user_agent' => 'Arachni/' + Arachni::VERSION } session['opts']['modules'] ||= [ '*' ] session['opts']['plugins'] ||= YAML::dump( { 'content_types' => {}, 'healthmap' => {}, 'metamodules' => {} } ) # # Garbage collector, zombie killer. Reaps idle processes every 5 seconds. # @@reaper ||= Thread.new { while( true ) shutdown_zombies ::IO::select( nil, nil, nil, 5 ) end } end |
#save_and_shutdown(arachni) ⇒ Object
Saves the report and shuts down the instance
468 469 470 471 472 473 |
# File 'lib/ui/web/server.rb', line 468 def save_and_shutdown( arachni ) arachni.framework.clean_up!( true ) report_path = settings.reports.save( arachni.framework.auditstore ) arachni.service.shutdown! return report_path end |
#save_shutdown_and_show(arachni) ⇒ Object
Saves the report, shuts down the instance and returns the content as HTML to be sent back to the user’s browser.
458 459 460 461 |
# File 'lib/ui/web/server.rb', line 458 def save_shutdown_and_show( arachni ) report = save_and_shutdown( arachni ) settings.reports.get( 'html', settings.reports.all.last.id ) end |
#show(page, layout = true) ⇒ Object
180 181 182 183 184 185 186 187 |
# File 'lib/ui/web/server.rb', line 180 def show( page, layout = true ) if page == :dispatcher ensure_dispatcher erb :dispatcher, { :layout => true }, :stats => dispatcher_stats else erb page.to_sym, { :layout => layout } end end |
#shutdown_all ⇒ Object
Kills all running instances
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'lib/ui/web/server.rb', line 478 def shutdown_all settings.log.dispatcher_global_shutdown( env ) dispatcher.stats['running_jobs'].each { |job| begin save_and_shutdown( connect_to_instance( job['port'] ) ) rescue begin connect_to_instance( job['port'] ).service.shutdown! rescue settings.log.instance_fucker_wont_die( env, port_to_url( job['port'] ) ) next end end settings.log.instance_shutdown( env, port_to_url( job['port'] ) ) } end |
#shutdown_zombies ⇒ Integer
Kills all idle instances
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'lib/ui/web/server.rb', line 502 def shutdown_zombies i = 0 dispatcher.stats['running_jobs'].each { |job| begin arachni = connect_to_instance( job['port'] ) begin if !arachni.framework.busy? && !job['owner'] != HELPER_OWNER save_and_shutdown( arachni ) settings.log.webui_zombie_cleanup( env, port_to_url( job['port'] ) ) i+=1 end rescue end rescue end } return i end |
#to_i(str) ⇒ Object
Similar to String.to_i but it returns the original object if String is not a number
263 264 265 266 267 268 269 270 271 |
# File 'lib/ui/web/server.rb', line 263 def to_i( str ) return str if !str.is_a?( String ) if str.match( /\d+/ ).to_s.size == str.size return str.to_i else return str end end |
#unescape_hash(hash) ⇒ Object
337 338 339 340 341 342 343 344 345 |
# File 'lib/ui/web/server.rb', line 337 def unescape_hash( hash ) hash.each_pair { |k, v| hash[k] = unescape( hash[k] ) if hash[k].is_a?( String ) hash[k] = unescape_hash( v ) if v.is_a? Hash } return hash end |
#welcomed! ⇒ Object
193 194 195 |
# File 'lib/ui/web/server.rb', line 193 def welcomed! File.new( settings.db + '/welcomed', 'w' ).close end |
#welcomed? ⇒ Boolean
189 190 191 |
# File 'lib/ui/web/server.rb', line 189 def welcomed? File.exist?( settings.db + '/welcomed' ) end |