Module: Arachni::RPC::Server::Framework::MultiInstance

Includes:
Distributor, Master, Slave
Included in:
Arachni::RPC::Server::Framework
Defined in:
lib/arachni/rpc/server/framework/multi_instance.rb

Overview

Holds multi-Instance methods for the Arachni::RPC::Server::Framework.

Author:

  • Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Constant Summary

Constants included from Distributor

Distributor::MAX_CONCURRENCY

Instance Method Summary collapse

Methods included from Master

#enslave, #has_slaves?, #master?, #set_as_master, #slave_sitrep

Methods included from Slave

#process_pages, #set_master, #slave?

Methods included from Distributor

#connect_to_instance, #each_slave, #iterator_for, #map_slaves, #slave_iterator

Instance Method Details

#errors(starting_line = 0, &block) ⇒ Array<String>

Parameters:

  • starting_line (Integer) (defaults to: 0)

    Sets the starting line for the range of errors to return.

Returns:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/arachni/rpc/server/framework/multi_instance.rb', line 44

def errors( starting_line = 0, &block )
    return [] if !File.exists? error_logfile

    error_strings = error_buffer.dup

    if starting_line != 0
        error_strings = error_strings[starting_line..-1]
    end

    return error_strings if !block_given?

    if !has_slaves?
        block.call( error_strings )
        return
    end

    foreach = proc do |instance, iter|
        instance.framework.errors( starting_line ) { |errs| iter.return( errs ) }
    end
    after = proc { |out| block.call( (error_strings | errs).flatten ) }
    map_slaves( foreach, after )
end

#multi_self_urlObject



199
200
201
# File 'lib/arachni/rpc/server/framework/multi_instance.rb', line 199

def multi_self_url
    options.rpc.server_socket || self_url
end

#progress(opts = {}, &block) ⇒ Hash

Provides aggregated progress data.

Parameters:

  • opts (Hash) (defaults to: {})

    Options about what data to include:

Options Hash (opts):

  • :slaves (Bool) — default: true

    Slave statistics.

  • :issues (Bool) — default: true

    Issue summaries.

  • :statistics (Bool) — default: true

    Master/merged statistics.

  • :errors (Bool, Integer) — default: false

    Logged errors. If an integer is provided it will return errors past that index.

  • :sitemap (Bool, Integer) — default: false

    Scan sitemap. If an integer is provided it will return entries past that index.

  • :as_hash (Bool) — default: false

    If set to `true`, will convert issues to hashes before returning them.

Returns:

  • (Hash)

    Progress data.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/arachni/rpc/server/framework/multi_instance.rb', line 88

def progress( opts = {}, &block )
    opts = opts.my_symbolize_keys

    include_statistics = opts[:statistics].nil? ? true : opts[:statistics]
    include_slaves     = opts[:slaves].nil?     ? true : opts[:slaves]
    include_issues     = opts[:issues].nil?     ? true : opts[:issues]
    include_sitemap    = opts.include?( :sitemap ) ?
        (opts[:sitemap] || 0) : false
    include_errors     = opts.include?( :errors ) ?
        (opts[:errors] || 0) : false

    as_hash = opts[:as_hash] ? true : opts[:as_hash]

    data = {
        status: status,
        busy:   running?,
        seed:   Utilities.random_seed
    }

    if include_issues
        data[:issues] = as_hash ? issues_as_hash : issues
    end

    if include_statistics
        data[:statistics] = self.statistics
    end

    if include_sitemap
        data[:sitemap] =
            sitemap_entries( include_sitemap.is_a?( Integer ) ? include_sitemap : 0 )
    end

    if include_errors
        data[:errors] =
            errors( include_errors.is_a?( Integer ) ? include_errors : 0 )
    end

    if solo? || slave? || !include_slaves
        block.call data.merge( messages: status_messages )
        return
    end

    data[:instances] = {
        self_url => {
            url:      self_url,
            status:   status,
            messages: status_messages,
            busy:     running?
        }
    }

    if include_statistics
        data[:instances][self_url][:statistics] = data[:statistics].dup
    end

    foreach = proc do |instance, iter|
        instance.framework.progress( opts.merge( issues: false ) ) do |d|
            if d.rpc_exception?
                iter.return( nil )
            else
                iter.return( d.merge( url: instance.url ) )
            end
        end
    end

    after = proc do |slave_data|
        slave_data.compact!

        slave_data.each do |slave|
            slave = slave.my_symbolize_keys

            if include_errors
                data[:errors] |= slave[:errors]
            end

            data[:instances][slave[:url]] = slave
        end

        data[:instances] = Hash[data[:instances].sort_by { |k, _| k }].values

        if include_statistics
            data[:statistics] =
                merge_statistics( data[:instances].map { |v| v[:statistics] } )
        end

        data[:busy]   = slave_data.map { |d| d[:busy] }.include?( true )
        data[:master] = self_url

        block.call( data )
    end

    map_slaves( foreach, after )
end

#solo?Bool

Returns `true` if this instance is running solo (i.e. not a member of a multi-Instance operation), `false` otherwise.

Returns:

  • (Bool)

    `true` if this instance is running solo (i.e. not a member of a multi-Instance operation), `false` otherwise.



36
37
38
# File 'lib/arachni/rpc/server/framework/multi_instance.rb', line 36

def solo?
    !master? && !slave?
end

#update_page_queue(pages, token = nil) ⇒ Bool

Updates the page queue with the provided pages.

Parameters:

  • pages (Array<Arachni::Page>)

    List of pages.

  • token (String) (defaults to: nil)

    Privileged token, prevents this method from being called by 3rd parties when this instance is a master. If this instance is not a master one the token needn't be provided.

Returns:

  • (Bool)

    `true` on success, `false` on invalid `token`.



193
194
195
196
197
# File 'lib/arachni/rpc/server/framework/multi_instance.rb', line 193

def update_page_queue( pages, token = nil )
    return false if master? && !valid_token?( token )
    [pages].flatten.each { |page| push_to_page_queue( page )}
    true
end