Class: Arachni::State::Framework

Inherits:
Object
  • Object
show all
Defined in:
lib/arachni/state/framework.rb,
lib/arachni/state/framework/rpc.rb

Overview

State information for Framework.

Author:

Defined Under Namespace

Classes: Error, RPC

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFramework

Returns a new instance of Framework.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/arachni/state/framework.rb', line 65

def initialize
    @rpc = RPC.new
    @audited_page_count = 0

    @browser_skip_states = Support::LookUp::HashSet.new( hasher: :persistent_hash )

    @page_queue_filter = Support::LookUp::HashSet.new( hasher: :persistent_hash )
    @url_queue_filter  = Support::LookUp::HashSet.new( hasher: :persistent_hash )

    @running = false
    @pre_pause_status = nil

    @pause_signals    = Set.new
    @paused_signal    = Queue.new
    @suspended_signal = Queue.new
    @aborted_signal   = Queue.new

    @status_messages = []
end

Instance Attribute Details

#audited_page_countInteger

Returns:

  • (Integer)


57
58
59
# File 'lib/arachni/state/framework.rb', line 57

def audited_page_count
  @audited_page_count
end

#browser_skip_statesSet (readonly)

Returns:



48
49
50
# File 'lib/arachni/state/framework.rb', line 48

def browser_skip_states
  @browser_skip_states
end

#page_queue_filterSupport::LookUp::HashSet (readonly)



42
43
44
# File 'lib/arachni/state/framework.rb', line 42

def page_queue_filter
  @page_queue_filter
end

#pause_signalsArray (readonly)

Returns:



60
61
62
# File 'lib/arachni/state/framework.rb', line 60

def pause_signals
  @pause_signals
end

#rpcRPC

Returns:



39
40
41
# File 'lib/arachni/state/framework.rb', line 39

def rpc
  @rpc
end

#runningBool

Returns:

  • (Bool)


54
55
56
# File 'lib/arachni/state/framework.rb', line 54

def running
  @running
end

#statusSymbol

Returns:

  • (Symbol)


51
52
53
# File 'lib/arachni/state/framework.rb', line 51

def status
  @status
end

#status_messagesArray<String> (readonly)

Returns:



63
64
65
# File 'lib/arachni/state/framework.rb', line 63

def status_messages
  @status_messages
end

#url_queue_filterSupport::LookUp::HashSet (readonly)



45
46
47
# File 'lib/arachni/state/framework.rb', line 45

def url_queue_filter
  @url_queue_filter
end

Class Method Details

.load(directory) ⇒ Object



387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/arachni/state/framework.rb', line 387

def self.load( directory )
    framework = new

    framework.rpc = RPC.load( "#{directory}/rpc/" )

    %w(page_queue_filter url_queue_filter browser_skip_states).each do |attribute|
        framework.send(attribute).merge Marshal.load( IO.binread( "#{directory}/#{attribute}" ) )
    end

    framework.audited_page_count = Marshal.load( IO.binread( "#{directory}/audited_page_count" ) )
    framework
end

Instance Method Details

#abort(block = true) ⇒ Bool

Returns ‘true` if the abort request was successful, `false` if the system is already #suspended? or is #suspending?.

Parameters:

  • block (Bool) (defaults to: true)

    ‘true` if the method should block until an abortion has completed, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the abort request was successful, `false` if the system is already #suspended? or is #suspending?.

Raises:

  • (StateNotAbortable)

    When not #running?.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/arachni/state/framework.rb', line 202

def abort( block = true )
    return false if aborting? || aborted?

    if !running?
        fail Error::StateNotAbortable, 'Cannot suspend an idle state.'
    end

    set_status_message :aborting
    @status = :aborting
    @abort = true

    @aborted_signal.pop if block
    true
end

#abort?Bool

Returns ‘true` if a #abort signal is in place , `false` otherwise.

Returns:

  • (Bool)

    ‘true` if a #abort signal is in place , `false` otherwise.



219
220
221
# File 'lib/arachni/state/framework.rb', line 219

def abort?
    !!@abort
end

#abortedObject

Signals a completed abort operation.



224
225
226
227
228
229
# File 'lib/arachni/state/framework.rb', line 224

def aborted
    @abort = false
    @status = :aborted
    @aborted_signal << true
    nil
end

#aborted?Bool

Returns ‘true` if the system has been aborted, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system has been aborted, `false` otherwise.



233
234
235
# File 'lib/arachni/state/framework.rb', line 233

def aborted?
    @status == :aborted
end

#aborting?Bool

Returns ‘true` if the system is being aborted, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system is being aborted, `false` otherwise.



239
240
241
# File 'lib/arachni/state/framework.rb', line 239

def aborting?
    @status == :aborting
end

#add_status_message(message, *sprintf) ⇒ Object

Pushes a message to #status_messages.

Parameters:



127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/arachni/state/framework.rb', line 127

def add_status_message( message, *sprintf )
    if message.is_a? Symbol
        if !available_status_messages.include?( message )
            fail Error::InvalidStatusMessage,
                 "Could not find status message for: '#{message}'"
        end

        message = available_status_messages[message] % sprintf
    end

    @status_messages << message.to_s
end

#available_status_messagesHash{Symbol=>String}

Returns All possible #status_messages by type.

Returns:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/arachni/state/framework.rb', line 95

def available_status_messages
    {
        pausing:                          'Will pause as soon as the current page is audited.',
        suspending:                       'Will suspend as soon as the current page is audited.',
        waiting_for_browser_cluster_jobs: 'Waiting for %i browser cluster jobs to finish.',
        suspending_plugins:               'Suspending plugins.',
        saving_snapshot:                  'Saving snapshot at: %s',
        snapshot_location:                'Snapshot location: %s',
        browser_cluster_startup:          'Initialising the browser cluster.',
        browser_cluster_shutdown:         'Shutting down the browser cluster.',
        clearing_queues:                  'Clearing the audit queues.',
        waiting_for_plugins:              'Waiting for the plugins to finish.',
        aborting:                         'Aborting the scan.'
    }
end

#clearObject



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/arachni/state/framework.rb', line 400

def clear
    rpc.clear

    @page_queue_filter.clear
    @url_queue_filter.clear

    @pause_signals.clear
    @paused_signal.clear
    @suspended_signal.clear

    @running = false
    @pre_pause_status = nil

    @browser_skip_states.clear
    @audited_page_count = 0
end

#clear_status_messagesObject



141
142
143
# File 'lib/arachni/state/framework.rb', line 141

def clear_status_messages
    @status_messages.clear
end

#dump(directory) ⇒ Object



375
376
377
378
379
380
381
382
383
384
385
# File 'lib/arachni/state/framework.rb', line 375

def dump( directory )
    FileUtils.mkdir_p( directory )

    rpc.dump( "#{directory}/rpc/" )

    %w(page_queue_filter url_queue_filter browser_skip_states
        audited_page_count).each do |attribute|

        IO.binwrite( "#{directory}/#{attribute}", Marshal.dump( send(attribute) ) )
    end
end

#page_seen(page) ⇒ Object

Parameters:

  • page (Page)

    Page to mark as seen.

See Also:



160
161
162
# File 'lib/arachni/state/framework.rb', line 160

def page_seen( page )
    @page_queue_filter << page
end

#page_seen?(page) ⇒ Bool

Returns ‘true` if the `page` has already been seen (based on the #page_queue_filter), `false` otherwise.

Parameters:

Returns:

  • (Bool)

    ‘true` if the `page` has already been seen (based on the #page_queue_filter), `false` otherwise.

See Also:



152
153
154
# File 'lib/arachni/state/framework.rb', line 152

def page_seen?( page )
    @page_queue_filter.include? page
end

#pause(caller, block = true) ⇒ TrueClass

Returns Pauses the framework on a best effort basis, might take a while to take effect.

Parameters:

  • caller (Object)

    Identification for the caller which issued the pause signal.

  • block (Bool) (defaults to: true)

    ‘true` if the method should block until the pause has completed, `false` otherwise.

Returns:

  • (TrueClass)

    Pauses the framework on a best effort basis, might take a while to take effect.



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/arachni/state/framework.rb', line 313

def pause( caller, block = true )
    @pre_pause_status ||= @status if !paused? && !pausing?

    if !paused?
        @status = :pausing
        set_status_message :pausing
    end

    @pause_signals << caller

    paused if !running?

    @paused_signal.pop if block && !paused?
    true
end

#pause?Bool

Returns ‘true` if the framework should pause, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the framework should pause, `false` otherwise.



350
351
352
# File 'lib/arachni/state/framework.rb', line 350

def pause?
    @pause_signals.any?
end

#pausedObject

Signals that the system has been paused..



330
331
332
333
334
# File 'lib/arachni/state/framework.rb', line 330

def paused
    clear_status_messages
    @status = :paused
    @paused_signal << nil
end

#paused?Bool

Returns ‘true` if the framework is paused.

Returns:

  • (Bool)

    ‘true` if the framework is paused.



338
339
340
# File 'lib/arachni/state/framework.rb', line 338

def paused?
    @status == :paused
end

#pausing?Bool

Returns ‘true` if the system is being paused, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system is being paused, `false` otherwise.



344
345
346
# File 'lib/arachni/state/framework.rb', line 344

def pausing?
    @status == :pausing
end

#resume(caller) ⇒ Bool

Resumes a paused system

Parameters:

  • caller (Object)

    Identification for the caller whose #pause signal to remove. The system is resumed once there are no more #pause signals left.

Returns:

  • (Bool)

    ‘true` if the system is resumed, `false` if there are more #pause signals pending.



363
364
365
366
367
368
369
370
371
372
373
# File 'lib/arachni/state/framework.rb', line 363

def resume( caller )
    @pause_signals.delete( caller )

    if @pause_signals.empty?
        @status = @pre_pause_status
        @pre_pause_status = nil
        return true
    end

    false
end

#running?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/arachni/state/framework.rb', line 188

def running?
    !!@running
end

#scanning?Bool

Returns ‘true` if the system is scanning, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system is scanning, `false` otherwise.



300
301
302
# File 'lib/arachni/state/framework.rb', line 300

def scanning?
    @status == :scanning
end

#set_status_message(*args) ⇒ Object

Sets a message as #status_messages.

Parameters:



115
116
117
118
# File 'lib/arachni/state/framework.rb', line 115

def set_status_message( *args )
    clear_status_messages
    add_status_message( *args )
end

#statisticsObject



85
86
87
88
89
90
91
# File 'lib/arachni/state/framework.rb', line 85

def statistics
    {
        rpc:                @rpc.statistics,
        audited_page_count: @audited_page_count,
        browser_states:     @browser_skip_states.size
    }
end

#suspend(block = true) ⇒ Bool

Returns ‘true` if the suspend request was successful, `false` if the system is already #suspended? or is #suspending?.

Parameters:

  • block (Bool) (defaults to: true)

    ‘true` if the method should block until a suspend has completed, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the suspend request was successful, `false` if the system is already #suspended? or is #suspending?.

Raises:



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/arachni/state/framework.rb', line 253

def suspend( block = true )
    return false if suspending? || suspended?

    if paused? || pausing?
        fail Error::StateNotSuspendable, 'Cannot suspend a paused state.'
    end

    if !running?
        fail Error::StateNotSuspendable, 'Cannot suspend an idle state.'
    end

    set_status_message :suspending
    @status = :suspending
    @suspend = true

    @suspended_signal.pop if block
    true
end

#suspend?Bool

Returns ‘true` if an #abort signal is in place , `false` otherwise.

Returns:

  • (Bool)

    ‘true` if an #abort signal is in place , `false` otherwise.



274
275
276
# File 'lib/arachni/state/framework.rb', line 274

def suspend?
    !!@suspend
end

#suspendedObject

Signals a completed suspension.



279
280
281
282
283
284
# File 'lib/arachni/state/framework.rb', line 279

def suspended
    @suspend = false
    @status = :suspended
    @suspended_signal << true
    nil
end

#suspended?Bool

Returns ‘true` if the system has been suspended, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system has been suspended, `false` otherwise.



288
289
290
# File 'lib/arachni/state/framework.rb', line 288

def suspended?
    @status == :suspended
end

#suspending?Bool

Returns ‘true` if the system is being suspended, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the system is being suspended, `false` otherwise.



294
295
296
# File 'lib/arachni/state/framework.rb', line 294

def suspending?
    @status == :suspending
end

#update_browser_skip_states(states) ⇒ Object

Parameters:



184
185
186
# File 'lib/arachni/state/framework.rb', line 184

def update_browser_skip_states( states )
    @browser_skip_states.merge states
end

#url_seen(url) ⇒ Object

Parameters:

  • url (Page)

    URL to mark as seen.

See Also:



179
180
181
# File 'lib/arachni/state/framework.rb', line 179

def url_seen( url )
    @url_queue_filter << url
end

#url_seen?(url) ⇒ Bool

Returns ‘true` if the `url` has already been seen (based on the #url_queue_filter), `false` otherwise.

Parameters:

Returns:

  • (Bool)

    ‘true` if the `url` has already been seen (based on the #url_queue_filter), `false` otherwise.

See Also:



171
172
173
# File 'lib/arachni/state/framework.rb', line 171

def url_seen?( url )
    @url_queue_filter.include? url
end