Skip to content

Commit

Permalink
Use the new Config and Workers in Engine#initialize (closes #124).
Browse files Browse the repository at this point in the history
  • Loading branch information
postmodern committed Jun 4, 2024
1 parent 23e2bb5 commit edfd97a
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 90 deletions.
78 changes: 49 additions & 29 deletions lib/ronin/recon/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
#

require 'ronin/recon/config'
require 'ronin/recon/workers'
require 'ronin/recon/worker_pool'
require 'ronin/recon/value_status'
Expand All @@ -43,6 +44,16 @@ module Recon
#
class Engine

# The configuration for the engine.
#
# @return [Config]
attr_reader :config

# The workers to use.
#
# @return [Workers]
attr_reader :workers

# The scope to constrain recon to.
#
# @return [Scope]
Expand All @@ -67,13 +78,6 @@ class Engine
# @api public
attr_reader :graph

# The workers that the engine will use.
#
# @return [Workers]
#
# @api public
attr_reader :workers

# The common logger for the engine.
#
# @return [Console::Logger]
Expand All @@ -94,8 +98,16 @@ class Engine
# The maximum depth to limit recon to. If not specified recon will
# continue until there are no more new values discovered.
#
# @param [Workers] workers
# The workers to use for recon.
# @param [String, nil] config_file
# The path to the configuration file.
#
# @param [Config, nil] config
# The configuration for the engine. If specified, it will override
# `config_file:`.
#
# @param [Workers, Array<Class<Worker>>, nil] workers
# The worker classes to use. If specified, it will override the workers
# specified in `config.workers`.
#
# @param [Console::Logger] logger
# The common logger for the recon engine.
Expand All @@ -111,35 +123,41 @@ class Engine
#
# @api public
#
def initialize(values, ignore: [],
max_depth: nil,
workers: Workers.default,
logger: Console.logger)
@scope = Scope.new(values, ignore: ignore)

@workers = workers
@worker_classes = {}
@worker_pools = {}
@worker_pool_count = 0

@value_status = ValueStatus.new
@graph = Graph.new
@max_depth = max_depth
@output_queue = Async::Queue.new
def initialize(values, ignore: [],
max_depth: nil,
config: nil,
config_file: nil,
workers: nil,
logger: Console.logger)
@config = if config then config
elsif config_file then Config.load(config_file)
else Config.default
end
@workers = workers || Workers.load(@config.workers)
@logger = logger

@scope = Scope.new(values, ignore: ignore)
@max_depth = max_depth

@on_value_callbacks = []
@on_connection_callbacks = []
@on_job_started_callbacks = []
@on_job_completed_callbacks = []
@on_job_failed_callbacks = []

@logger = logger
@value_status = ValueStatus.new
@graph = Graph.new

yield self if block_given?

@worker_classes = {}
@worker_pools = {}
@worker_pool_count = 0
@output_queue = Async::Queue.new

@workers.each do |worker_class|
add_worker(worker_class)
end

yield self if block_given?
end

#
Expand Down Expand Up @@ -235,8 +253,10 @@ def run(task=Async::Task.current)
#
# @api private
#
def add_worker(worker_class, concurrency: worker_class.concurrency,
params: nil)
def add_worker(worker_class, params: nil, concurrency: nil)
params ||= @config.params[worker_class.id]
concurrency ||= @config.concurrency[worker_class.id]

worker = worker_class.new(params: params)
worker_pool = WorkerPool.new(worker, concurrency: concurrency,
output_queue: @output_queue,
Expand Down
6 changes: 3 additions & 3 deletions lib/ronin/recon/worker_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class WorkerPool
# @param [Worker] worker
# The initialized worker object.
#
# @param [Integer] concurrency
# @param [Integer, nil] concurrency
# The number of async tasks to spawn.
#
# @param [Async::Queue] output_queue
Expand All @@ -84,12 +84,12 @@ class WorkerPool
# @param [Console::Logger] logger
# The console logger object.
#
def initialize(worker, concurrency: worker.class.concurrency,
def initialize(worker, concurrency: nil,
output_queue: ,
params: nil,
logger: Console.logger)
@worker = worker
@concurrency = concurrency
@concurrency = concurrency || worker.class.concurrency

@input_queue = Async::Queue.new
@output_queue = output_queue
Expand Down
47 changes: 2 additions & 45 deletions lib/ronin/recon/workers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def initialize(workers=Set.new)
#
# Loads the worker classes.
#
# @param [Array<String>] worker_ids
# The array of worker IDs to load.
# @param [Enumerable<String>] worker_ids
# The list of worker IDs to load.
#
# @return [Workers]
#
Expand Down Expand Up @@ -87,49 +87,6 @@ def self.all
load(Recon.list_files)
end

# The default set of workers to load.
#
# @api private
DEFAULT_SET = %w[
dns/lookup
dns/reverse_lookup
dns/mailservers
dns/nameservers
dns/subdomain_enum
dns/suffix_enum
dns/srv_enum
net/ip_range_enum
net/port_scan
net/service_id
ssl/cert_grab
ssl/cert_enum
web/spider
web/dir_enum
]

#
# Loads the default set of workers.
#
# * {DNS::Lookup dns/lookup}
# * {DNS::Mailservers dns/mailservers}
# * {DNS::Nameservers dns/nameservers}
# * {DNS::SubdomainEnum dns/subdomain_enum}
# * {DNS::SuffixEnum dns/suffix_enum}
# * {DNS::SRVEnum dns/srv_enum}
# * {Net::IPRangeEnum net/ip_range_enum}
# * {Net::PortScan net/port_scan}
# * {Net::ServiceID net/service_id}
# * {SSL::CertGrab ssl/cert_grab}
# * {SSL::CertEnum ssl/cert_enum}
# * {Web::Spider web/spider}
# * {Web::DirEnum web/dir_enum}
#
# @return [WorkerSet]
#
def self.default
load(DEFAULT_SET)
end

#
# Loads all workers under a specific category.
#
Expand Down
68 changes: 66 additions & 2 deletions spec/engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
expect(subject.scope.ignore).to eq([])
end

it "must default #workers to Ronin::Recon::Workers.default" do
expect(subject.workers).to eq(Ronin::Recon::Workers.default)
it "must default #workers to the default set of workers" do
expect(subject.workers).to eq(
Ronin::Recon::Workers.load(Ronin::Recon::Config::Workers::DEFAULT)
)
end

it "must initialize #value_status to an empty Ronin::Recon::ValueStatus" do
Expand Down Expand Up @@ -74,6 +76,68 @@
end
end

context "when given the config_file: keyword argument" do
let(:fixtures_dir) { File.join(__dir__,'fixtures') }
let(:config_file) { File.join(fixtures_dir,'config.yml') }
let(:config) { Ronin::Recon::Config.load(config_file) }

subject { described_class.new(values, config_file: config_file) }

it "must load the configuration from the file and set #config" do
expect(subject.config).to eq(config)
end

it "must initialize #workers based on the `workers:` defined in the configuration file" do
expect(subject.workers).to eq(
Ronin::Recon::Workers.load(config.workers)
)
end
end

context "when given the config: keyword argument" do
let(:config) do
Ronin::Recon::Config.new(
workers: %w[
dns/lookup
dns/reverse_lookup
dns/nameservers
dns/mailservers
]
)
end

subject { described_class.new(values, config: config) }

it "must set #config to the value passed in by the config: keyword argument" do
expect(subject.config).to be(config)
end

it "must initialize #workers based on the #workers in the config value" do
expect(subject.workers).to eq(
Ronin::Recon::Workers.load(config.workers)
)
end

context "and when the workers: keyword argument is given" do
let(:workers) do
Ronin::Recon::Workers.load(%w[
dns/lookup
dns/reverse_lookup
dns/subdomain_enum
])
end

subject do
described_class.new(values, config: config,
workers: workers)
end

it "must set #workers to the workers: keyword argument value" do
expect(subject.workers).to be(workers)
end
end
end

context "when given the workers: keyword argument" do
let(:workers) do
Ronin::Recon::Workers.load(
Expand Down
11 changes: 0 additions & 11 deletions spec/workers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,6 @@
end
end

describe ".default" do
subject { described_class }

it "must load the default set of workers and return a #{described_class}" do
worker_set = subject.default

expect(worker_set).to be_kind_of(described_class)
expect(worker_set.classes.map(&:id)).to eq(described_class::DEFAULT_SET)
end
end

describe ".category" do
subject { described_class }

Expand Down

0 comments on commit edfd97a

Please sign in to comment.