PR comments
This commit is contained in:
parent
1137036ecb
commit
682653e9d9
|
@ -41,7 +41,7 @@ module Auxiliary
|
|||
# Whether or not the exploit should be run in the context of a background
|
||||
# job.
|
||||
#
|
||||
def self.run_simple(omod, opts = {}, job_listener: NoopJobListener.instance, &block)
|
||||
def self.run_simple(omod, opts = {}, job_listener: Msf::Simple::NoopJobListener.instance, &block)
|
||||
|
||||
# Clone the module to prevent changes to the original instance
|
||||
mod = omod.replicant
|
||||
|
@ -108,7 +108,7 @@ module Auxiliary
|
|||
#
|
||||
# The local output through which data can be displayed.
|
||||
#
|
||||
def self.check_simple(mod, opts, job_listener: NoopJobListener.instance)
|
||||
def self.check_simple(mod, opts, job_listener: Msf::Simple::NoopJobListener.instance)
|
||||
Msf::Simple::Framework.simplify_module(mod, false)
|
||||
|
||||
mod._import_extra_options(opts)
|
||||
|
|
|
@ -177,7 +177,7 @@ module Exploit
|
|||
#
|
||||
# The local output through which data can be displayed.
|
||||
#
|
||||
def self.check_simple(mod, opts, job_listener: NoopJobListener.instance)
|
||||
def self.check_simple(mod, opts, job_listener: Msf::Simple::NoopJobListener.instance)
|
||||
Msf::Simple::Framework.simplify_module(mod, false)
|
||||
mod._import_extra_options(opts)
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
require 'singleton'
|
||||
|
||||
class NoopJobListener
|
||||
module Msf
|
||||
module Simple
|
||||
class NoopJobListener
|
||||
|
||||
include Singleton
|
||||
include Singleton
|
||||
|
||||
def waiting(id); end
|
||||
def waiting(id); end
|
||||
|
||||
def start(id); end
|
||||
def start(id); end
|
||||
|
||||
def completed(id, result, mod); end
|
||||
def completed(id, result, mod); end
|
||||
|
||||
def failed(id, error, mod); end
|
||||
def failed(id, error, mod); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,104 +1,109 @@
|
|||
require 'monitor'
|
||||
|
||||
class RpcJobStatusTracker
|
||||
module Msf
|
||||
module RPC
|
||||
class RpcJobStatusTracker
|
||||
|
||||
include MonitorMixin
|
||||
include MonitorMixin
|
||||
|
||||
def initialize
|
||||
@ready = Set.new
|
||||
@running = Set.new
|
||||
# Can be expanded upon later to allow the option of a MemCacheStore being backed by redis for example
|
||||
@results = ResultsMemoryStore.new
|
||||
end
|
||||
def initialize
|
||||
@ready = Set.new
|
||||
@running = Set.new
|
||||
# Can be expanded upon later to allow the option of a MemCacheStore being backed by redis for example
|
||||
@results = ResultsMemoryStore.new
|
||||
end
|
||||
|
||||
def waiting(id)
|
||||
ready << id
|
||||
end
|
||||
def waiting(id)
|
||||
ready << id
|
||||
end
|
||||
|
||||
def start(id)
|
||||
running << id
|
||||
ready.delete(id)
|
||||
end
|
||||
def start(id)
|
||||
running << id
|
||||
ready.delete(id)
|
||||
end
|
||||
|
||||
def completed(id, result, mod)
|
||||
add_result(id, { result: result }, mod)
|
||||
end
|
||||
def completed(id, result, mod)
|
||||
add_result(id, { result: result }, mod)
|
||||
end
|
||||
|
||||
def failed(id, error, mod)
|
||||
add_result(id, { error: error.to_s }, mod)
|
||||
end
|
||||
def failed(id, error, mod)
|
||||
add_result(id, { error: error.to_s }, mod)
|
||||
end
|
||||
|
||||
def running?(id)
|
||||
running.include? id
|
||||
end
|
||||
def running?(id)
|
||||
running.include? id
|
||||
end
|
||||
|
||||
def waiting?(id)
|
||||
ready.include? id
|
||||
end
|
||||
def waiting?(id)
|
||||
ready.include? id
|
||||
end
|
||||
|
||||
def finished?(id)
|
||||
results.exist? id
|
||||
end
|
||||
def finished?(id)
|
||||
results.exist? id
|
||||
end
|
||||
|
||||
def result(id)
|
||||
result = results.fetch(id)
|
||||
return unless result
|
||||
def result(id)
|
||||
result = results.fetch(id)
|
||||
return unless result
|
||||
|
||||
JSON.parse(result).with_indifferent_access
|
||||
end
|
||||
::JSON.parse(result).with_indifferent_access
|
||||
end
|
||||
|
||||
def delete(id)
|
||||
results.delete(id)
|
||||
end
|
||||
def delete(id)
|
||||
results.delete(id)
|
||||
end
|
||||
|
||||
def result_ids
|
||||
results.keys
|
||||
end
|
||||
def result_ids
|
||||
results.keys
|
||||
end
|
||||
|
||||
def waiting_ids
|
||||
ready.to_a
|
||||
end
|
||||
def waiting_ids
|
||||
ready.to_a
|
||||
end
|
||||
|
||||
def running_ids
|
||||
running.to_a
|
||||
end
|
||||
def running_ids
|
||||
running.to_a
|
||||
end
|
||||
|
||||
def data
|
||||
results.data
|
||||
end
|
||||
def data
|
||||
results.data
|
||||
end
|
||||
|
||||
alias ack delete
|
||||
alias ack delete
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def add_result(id, result, mod)
|
||||
string = result.to_json
|
||||
results.write(id, string)
|
||||
rescue ::Exception => e
|
||||
wlog("Job with id: #{id} finished but the result could not be stored")
|
||||
wlog("#{e.class}, #{e.message}")
|
||||
add_fallback_result(id, mod)
|
||||
ensure
|
||||
running.delete(id)
|
||||
end
|
||||
def add_result(id, result, mod)
|
||||
string = result.to_json
|
||||
results.write(id, string)
|
||||
rescue ::Exception => e
|
||||
wlog("Job with id: #{id} finished but the result could not be stored")
|
||||
wlog("#{e.class}, #{e.message}")
|
||||
add_fallback_result(id, mod)
|
||||
ensure
|
||||
running.delete(id)
|
||||
end
|
||||
|
||||
def add_fallback_result(id, mod)
|
||||
string = {
|
||||
error: 'Job finished but the result could not be stored',
|
||||
data: { mod: mod.fullname }
|
||||
}.to_json
|
||||
def add_fallback_result(id, mod)
|
||||
string = {
|
||||
error: {
|
||||
message: 'Job finished but the result could not be stored',
|
||||
data: { mod: mod.fullname }
|
||||
}
|
||||
}.to_json
|
||||
results.write(id, string)
|
||||
rescue ::Exception => e
|
||||
wlog("Job with id: #{id} fallback result failed to be stored")
|
||||
wlog("#{e.class}, #{e.message}")
|
||||
end
|
||||
|
||||
results.write(id, string)
|
||||
rescue ::Exception => e
|
||||
wlog("Job with id: #{id} fallback result failed to be stored")
|
||||
wlog("#{e.class}, #{e.message}")
|
||||
end
|
||||
attr_accessor :ready, :running, :results
|
||||
|
||||
attr_accessor :ready, :running, :results
|
||||
|
||||
class ResultsMemoryStore < ActiveSupport::Cache::MemoryStore
|
||||
def keys
|
||||
@data.keys
|
||||
class ResultsMemoryStore < ActiveSupport::Cache::MemoryStore
|
||||
def keys
|
||||
@data.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ class Service
|
|||
self.token_timeout = self.options[:token_timeout] || 300
|
||||
self.tokens = self.options[:tokens] || {}
|
||||
self.users = self.options[:users] || []
|
||||
self.job_status_tracker = RpcJobStatusTracker.new
|
||||
self.job_status_tracker = Msf::RPC::RpcJobStatusTracker.new
|
||||
|
||||
add_handler("core", Msf::RPC::RPC_Core.new(self))
|
||||
add_handler("auth", Msf::RPC::RPC_Auth.new(self))
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
require 'msf/core/rpc/v10/rpc_job_status_tracker'
|
||||
|
||||
RSpec.describe RpcJobStatusTracker do
|
||||
RSpec.describe Msf::RPC::RpcJobStatusTracker do
|
||||
context 'With default options' do
|
||||
let(:job_status_tracker) { described_class.new }
|
||||
let(:job_id) { 'super_random_job_id' }
|
||||
|
|
Loading…
Reference in New Issue