diff --git a/README.md b/README.md
index 3f97696..ddda781 100644
--- a/README.md
+++ b/README.md
@@ -74,6 +74,7 @@ Arguments:
Commands:
completion
+ config
help
irb
new
diff --git a/gemspec.yml b/gemspec.yml
index 76284fd..ed8804d 100644
--- a/gemspec.yml
+++ b/gemspec.yml
@@ -27,6 +27,13 @@ generated_files:
- data/completions/ronin-recon
- man/ronin-recon.1
- man/ronin-recon-completion.1
+ - man/ronin-recon-config.1
+ - man/ronin-recon-config-disable.1
+ - man/ronin-recon-config-enable.1
+ - man/ronin-recon-config-get.1
+ - man/ronin-recon-config-list.1
+ - man/ronin-recon-config-set.1
+ - man/ronin-recon-config-unset.1
- man/ronin-recon-irb.1
- man/ronin-recon-new.1
- man/ronin-recon-workers.1
diff --git a/lib/ronin/recon/cli/commands/config.rb b/lib/ronin/recon/cli/commands/config.rb
new file mode 100644
index 0000000..31bcbe1
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../command'
+
+require 'command_kit/commands/auto_load'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ #
+ # Get and set ronin-recon configuration.
+ #
+ # ## Usage
+ #
+ # ronin-recon config [options] [COMMAND [ARGS...]]
+ #
+ # ## Options
+ #
+ # -h, --help Print help information
+ #
+ # ## Arguments
+ #
+ # [COMMAND] The command name to run
+ # [ARGS ...] Additional arguments for the command
+ #
+ # ## Commands
+ #
+ # disable
+ # enable
+ # get
+ # help
+ # list
+ # set
+ # unset
+ #
+ # ## Examples
+ #
+ # ronin-recon config list
+ # ronin-recon config enable api/hunter_io
+ # ronin-recon config disable api/hunter_io
+ # ronin-recon config set --param api/hunter_io.api_key=...
+ # ronin-recon config set --concurrency web/spider=10
+ # ronin-recon config unset --param web/spider.proxy
+ # ronin-recon config unset --concurrency web/spider
+ #
+ # @since 0.2.0
+ #
+ class Config < Command
+
+ include CommandKit::Commands::AutoLoad.new(
+ dir: "#{__dir__}/config",
+ namespace: "#{self}"
+ )
+
+ examples [
+ 'list',
+ 'enable api/hunter_io',
+ 'disable api/hunter_io',
+ 'set --param api/hunter_io.api_key=...',
+ 'set --concurrency web/spider=10',
+ 'unset --param web/spider.proxy',
+ 'unset --concurrency web/spider'
+ ]
+
+ description 'Get and set ronin-recon configuration'
+
+ man_page 'ronin-config.1'
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/disable.rb b/lib/ronin/recon/cli/commands/config/disable.rb
new file mode 100644
index 0000000..13dfd72
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/disable.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Disables a worker in the configuration file.
+ #
+ # ## Usage
+ #
+ # ronin-recon config disable [options] WORKER
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -h, --help Print help information
+ #
+ # ## Arguments
+ #
+ # WORKER The worker ID to disable
+ #
+ # @since 0.2.0
+ #
+ class Disable < ConfigCommand
+
+ argument :worker, required: true,
+ desc: 'The worker ID to disable'
+
+ description "Disables a worker in the configuration file"
+
+ man_page 'ronin-recon-config-disable.1'
+
+ #
+ # Runs the `ronin-recon config disable` command.
+ #
+ # @param [String] worker
+ #
+ def run(worker)
+ load_config
+
+ @config.workers.delete(worker)
+
+ save_config
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/enable.rb b/lib/ronin/recon/cli/commands/config/enable.rb
new file mode 100644
index 0000000..afa3310
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/enable.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Enables a worker in the configuration file.
+ #
+ # ## Usage
+ #
+ # ronin-recon config enable [options] WORKER
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -h, --help Print help information
+ #
+ # ## Arguments
+ #
+ # WORKER The worker ID to enable
+ #
+ # @since 0.2.0
+ #
+ class Enable < ConfigCommand
+
+ argument :worker, required: true,
+ desc: 'The worker ID to enable'
+
+ description "Enables a worker in the configuration file"
+
+ man_page 'ronin-recon-config-enable.1'
+
+ #
+ # Runs the `ronin-recon config enable` command.
+ #
+ # @param [String] worker
+ #
+ def run(worker)
+ load_config
+
+ @config.workers.add(worker)
+
+ save_config
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/get.rb b/lib/ronin/recon/cli/commands/config/get.rb
new file mode 100644
index 0000000..78b0144
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/get.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Gets the concurrency or a param for a worker.
+ #
+ # ## Usage
+ #
+ # ronin-recon config get [options] {--concurrency WORKER | --param WORKER.NAME}
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -c, --concurrency WORKER Gets the concurrency of a worker
+ # -p, --param WORKER.PARAM Gets a param for a worker
+ # -h, --help Print help information
+ #
+ # @since 0.2.0
+ #
+ class Get < ConfigCommand
+
+ usage '[options] {--concurrency WORKER | --param WORKER.NAME}'
+
+ option :concurrency, short: '-c',
+ value: {
+ type: String,
+ usage: 'WORKER'
+ },
+ desc: 'Gets the concurrency for the worker' do |worker|
+ @mode = :concurrency
+ @worker = worker
+ end
+
+ option :param, short: '-p',
+ value: {
+ type: /\A[^\.\=\s]+\.[^=\s]+\z/,
+ usage: 'WORKER.PARAM'
+ },
+ desc: 'Gets the param for the worker' do |str|
+ @mode = :param
+ @worker, @param = str.split('.',2)
+ end
+
+ description 'Gets the concurrency or a param for a worker'
+
+ man_page 'ronin-recon-config-get.1'
+
+ # Specifies whether to unset the worker's concurrency or param.
+ #
+ # @return [:concurrency, :param, nil]
+ attr_reader :mode
+
+ # The worker name.
+ #
+ # @return [String, nil]
+ attr_reader :worker
+
+ # The param name to unset.
+ #
+ # @return [String, nil]
+ attr_reader :param
+
+ #
+ # Runs the `ronin-recon config set` command.
+ #
+ def run
+ load_config
+
+ case @mode
+ when :concurrency
+ if (concurrency = @config.concurrency[@worker])
+ puts concurrency
+ end
+ when :param
+ if (params = @config.params[@worker]) &&
+ (value = params[@param])
+ puts value
+ end
+ else
+ print_error "--concurrency or --param options must be given"
+ exit(1)
+ end
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/list.rb b/lib/ronin/recon/cli/commands/config/list.rb
new file mode 100644
index 0000000..0a574df
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/list.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Lists the values in the configuration file.
+ #
+ # ## Usage
+ #
+ # ronin-recon config list [options]
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -h, --help Print help information
+ #
+ # @since 0.2.0
+ #
+ class List < ConfigCommand
+
+ description "Lists the values in the configuration file"
+
+ man_page 'ronin-recon-config-list.1'
+
+ #
+ # Runs the `ronin-recon config list` command.
+ #
+ def run
+ load_config
+
+ puts "Workers:"
+ @config.workers.each do |worker_id|
+ puts " * #{worker_id}"
+ end
+
+ unless @config.concurrency.empty?
+ puts
+ puts "Concurrency:"
+ @config.concurrency.each do |worker_id,concurrency|
+ puts " * #{worker_id}=#{concurrency}"
+ end
+ end
+
+ unless @config.params.empty?
+ puts
+ puts "Params:"
+ @config.params.each do |worker_id,params|
+ puts " * #{worker_id}"
+
+ params.each do |name,value|
+ puts " * #{name}=#{value}"
+ end
+ end
+ end
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/set.rb b/lib/ronin/recon/cli/commands/config/set.rb
new file mode 100644
index 0000000..68c1c04
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/set.rb
@@ -0,0 +1,119 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Sets the concurrency or a param for a worker.
+ #
+ # ## Usage
+ #
+ # ronin-recon config set [options]
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -c, --concurrency WORKER=NUM Sets the concurrency of a worker
+ # -p, --param WORKER.NAME=VALUE Sets a param for a worker
+ # -h, --help Print help information
+ #
+ # @since 0.2.0
+ #
+ class Set < ConfigCommand
+
+ option :concurrency, short: '-c',
+ value: {
+ type: /\A[^\.\=\s]+=\d+\z/,
+ usage: 'WORKER=NUM'
+ },
+ desc: 'Gets the concurrency for the worker' do |str|
+ @mode = :concurrency
+ @worker, value = str.split('=',2)
+ @concurrency = value.to_i
+ end
+
+ option :param, short: '-p',
+ value: {
+ type: /\A[^\.\=\s]+\.[^=\s]+=.+\z/,
+ usage: 'WORKER.NAME=VALUE'
+ },
+ desc: 'Gets the param for the worker' do |str|
+ @mode = :param
+ prefix, @param_value = str.split('=',2)
+ @worker, @param_name = prefix.split('.',2)
+ end
+
+ description "Sets the concurrency or a param for a worker"
+
+ man_page 'ronin-recon-config-set.1'
+
+ # The worker name.
+ #
+ # @return [String, nil]
+ attr_reader :worker
+
+ # The concurrency value to set.
+ #
+ # @return [Integer, nil]
+ attr_reader :concurrency
+
+ # The param name to set.
+ #
+ # @return [String, nil]
+ attr_reader :param_name
+
+ # The param value to set.
+ #
+ # @return [String, nil]
+ attr_reader :param_value
+
+ #
+ # Runs the `ronin-recon config set` command.
+ #
+ def run
+ load_config
+
+ if @concurrency
+ @config.concurrency[@worker] = @concurrency
+ elsif @param_name
+ if (params = @config.params[@worker])
+ params[@param_name] = @param_value
+ else
+ @config.params[@worker] = {@param_name => @param_value}
+ end
+ else
+ print_error "--concurrency or --param options must be given"
+ exit(1)
+ end
+
+ save_config
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/commands/config/unset.rb b/lib/ronin/recon/cli/commands/config/unset.rb
new file mode 100644
index 0000000..4db05a8
--- /dev/null
+++ b/lib/ronin/recon/cli/commands/config/unset.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative '../../config_command'
+
+module Ronin
+ module Recon
+ class CLI
+ module Commands
+ class Config < Command
+ #
+ # Unsets the concurrency or params for a worker.
+ #
+ # ## Usage
+ #
+ # ronin-recon config unset [options] {--concurrency WORKER | --param WORKER.NAME}
+ #
+ # ## Options
+ #
+ # -C, --config-file FILE Loads the configuration file
+ # -c, --concurrency WORKER Gets the concurrency of a worker
+ # -p, --param WORKER.PARAM Gets a param for a worker
+ # -h, --help Print help information
+ #
+ # @since 0.2.0
+ #
+ class Unset < ConfigCommand
+
+ usage '[options] {--concurrency WORKER | --param WORKER.NAME}'
+
+ option :concurrency, short: '-c',
+ value: {
+ type: String,
+ usage: 'WORKER'
+ },
+ desc: 'Gets the concurrency for the worker' do |worker|
+ @mode = :concurrency
+ @worker = worker
+ end
+
+ option :param, short: '-p',
+ value: {
+ type: /\A[^\.\=\s]+\.[^=\s]+\z/,
+ usage: 'WORKER.PARAM'
+ },
+ desc: 'Gets the param for the worker' do |str|
+ @mode = :param
+ @worker, @param = str.split('.',2)
+ end
+
+ description 'Unsets the concurrency or params for a worker'
+
+ man_page 'ronin-recon-config-unset.1'
+
+ # Specifies whether to unset the worker's concurrency or param.
+ #
+ # @return [:concurrency, :param, nil]
+ attr_reader :mode
+
+ # The worker name.
+ #
+ # @return [String, nil]
+ attr_reader :worker
+
+ # The param name to unset.
+ #
+ # @return [String, nil]
+ attr_reader :param
+
+ #
+ # Runs the `ronin-recon config unset` command.
+ #
+ def run
+ load_config
+
+ case @mode
+ when :concurrency
+ @config.concurrency.delete(@worker)
+ when :param
+ if (params = @config.params[@worker])
+ params.delete(@param)
+ end
+ else
+ print_error "--concurrency or --param options must be given"
+ exit(1)
+ end
+
+ save_config
+ end
+
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ronin/recon/cli/config_command.rb b/lib/ronin/recon/cli/config_command.rb
new file mode 100644
index 0000000..88c1bfc
--- /dev/null
+++ b/lib/ronin/recon/cli/config_command.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+#
+# ronin-recon - A micro-framework and tool for performing reconnaissance.
+#
+# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
+#
+# ronin-recon is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ronin-recon is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ronin-recon. If not, see .
+#
+
+require_relative 'command'
+require_relative 'config_file_option'
+
+module Ronin
+ module Recon
+ class CLI
+ #
+ # Base class for all `ronin-recon config` sub-commands.
+ #
+ # @since 0.2.0
+ #
+ class ConfigCommand < Command
+
+ include ConfigFileOption
+
+ #
+ # Saves the configuration back out to either the `--config-file`
+ # path or `~/.config/ronin-recon/config.yml`.
+ #
+ def save_config
+ if (config_file = options[:config_file])
+ @config.save(config_file)
+ else
+ @config.save
+ end
+ end
+
+ end
+ end
+ end
+end