diff --git a/.gitignore b/.gitignore index f6ae618bd..fac755a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /coverage +/data/completions/ronin /doc /pkg /man/*.[1-9] diff --git a/Gemfile b/Gemfile index 9e9580934..0410074c6 100644 --- a/Gemfile +++ b/Gemfile @@ -14,8 +14,8 @@ if RUBY_VERSION >= '3.1.0' gem 'net-imap', '~> 0.1', group: :net, platform: :mri end -# gem 'command_kit', '~> 0.4', github: 'postmodern/command_kit.rb', -# branch: '0.4.0' +# gem 'command_kit', '~> 0.5', github: 'postmodern/command_kit.rb', +# branch: 'main' group :database do gem 'sqlite3', '~> 1.0', platform: :mri @@ -25,10 +25,10 @@ end # Library dependencies gem 'ronin-support', '~> 1.1', github: "ronin-rb/ronin-support", branch: '1.1.0' -gem 'ronin-core', '~> 0.2', github: "ronin-rb/ronin-core", +gem 'ronin-core', '~> 0.2', github: 'ronin-rb/ronin-core', + branch: '0.2.0' +gem 'ronin-repos', '~> 0.1', github: 'ronin-rb/ronin-repos', branch: '0.2.0' -# gem 'ronin-repos', '~> 0.1', github: "ronin-rb/ronin-repos", -# branch: 'main' gem 'ronin-db-activerecord', '~> 0.2', github: "ronin-rb/ronin-db-activerecord", branch: '0.2.0' gem 'ronin-db', '~> 0.2', github: "ronin-rb/ronin-db", @@ -39,18 +39,18 @@ gem 'ronin-listener-http', '~> 0.1', github: "ronin-rb/ronin-listener-http" branch: 'main' gem 'ronin-listener', '~> 0.1', github: "ronin-rb/ronin-listener", branch: 'main' -# gem 'ronin-fuzzer', '~> 0.1', github: 'ronin-rb/ronin-fuzzer', -# branch: 'main' +gem 'ronin-fuzzer', '~> 0.2', github: 'ronin-rb/ronin-fuzzer', + branch: '0.2.0' # gem 'ronin-post_ex', '~> 0.1', github: 'ronin-rb/ronin-post_ex', # branch: 'main' # gem 'ronin-code-asm', '~> 1.0', github: 'ronin-rb/ronin-code-asm', # branch: 'main' # gem 'ronin-code-sql', '~> 2.0', github: 'ronin-rb/ronin-code-sql', # branch: 'main' -# gem 'ronin-payloads', '~> 0.1', github: 'ronin-rb/ronin-payloads', -# branch: 'main' -# gem 'ronin-exploits', '~> 1.0', github: 'ronin-rb/ronin-exploits', -# branch: 'main' +gem 'ronin-payloads', '~> 0.2', github: 'ronin-rb/ronin-payloads', + branch: '0.2.0' +gem 'ronin-exploits', '~> 1.1', github: 'ronin-rb/ronin-exploits', + branch: '1.1.0' gem 'ronin-vulns', '~> 0.2', github: 'ronin-rb/ronin-vulns', branch: '0.2.0' # gem 'ronin-web-server', '~> 0.1', github: 'ronin-rb/ronin-web-server', @@ -98,4 +98,6 @@ group :development do gem 'rubocop', require: false, platform: :mri gem 'rubocop-ronin', require: false, platform: :mri gem 'pry', require: false + + gem 'command_kit-completion', '~> 0.1', require: false end diff --git a/README.md b/README.md index ff949d4bd..13d5bb52d 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Commands: cert-dump cert-gen cert-grab + completion decode, dec decrypt dns diff --git a/Rakefile b/Rakefile index b95871af2..0dea54f0a 100644 --- a/Rakefile +++ b/Rakefile @@ -41,3 +41,10 @@ task :docs => [:yard] require 'kramdown/man/task' Kramdown::Man::Task.new + +require 'command_kit/completion/task' +CommandKit::Completion::Task.new( + class_file: 'ronin/cli', + class_name: 'Ronin::CLI', + output_file: 'data/completions/ronin' +) diff --git a/gemspec.yml b/gemspec.yml index a1789dfbb..9c2babfdc 100644 --- a/gemspec.yml +++ b/gemspec.yml @@ -37,6 +37,7 @@ metadata: rubygems_mfa_required: 'true' generated_files: + - data/completions/ronin - man/ronin.1 - man/ronin-asn.1 - man/ronin-banner-grab.1 @@ -45,6 +46,7 @@ generated_files: - man/ronin-cert-dump.1 - man/ronin-cert-gen.1 - man/ronin-cert-grab.1 + - man/ronin-completion.1 - man/ronin-decode.1 - man/ronin-decrypt.1 - man/ronin-dns.1 @@ -103,13 +105,13 @@ dependencies: ronin-support: ~> 1.1 ronin-dns-proxy: ~> 0.1 ronin-core: ~> 0.2 - ronin-repos: ~> 0.1 - ronin-db: ~> 0.1 + ronin-repos: ~> 0.2 + ronin-db: ~> 0.2 ronin-listener: ~> 0.1 ronin-nmap: ~> 0.1 ronin-masscan: ~> 0.1 ronin-recon: ~> 0.1 - ronin-fuzzer: ~> 0.1 + ronin-fuzzer: ~> 0.2 ronin-web: ~> 2.0 ronin-code-asm: ~> 1.0 ronin-code-sql: ~> 2.0 diff --git a/lib/ronin/cli/commands/banner_grab.rb b/lib/ronin/cli/commands/banner_grab.rb index 0509950cc..e5ae84eae 100644 --- a/lib/ronin/cli/commands/banner_grab.rb +++ b/lib/ronin/cli/commands/banner_grab.rb @@ -45,6 +45,8 @@ class BannerGrab < ValueProcessorCommand include HostAndPort + command_name 'banner-grab' + usage '[options] {HOST:PORT} ...' option :with_host_port, desc: 'Print the service with the banner' diff --git a/lib/ronin/cli/commands/cert_dump.rb b/lib/ronin/cli/commands/cert_dump.rb index 7dd2fa5b6..b085de419 100644 --- a/lib/ronin/cli/commands/cert_dump.rb +++ b/lib/ronin/cli/commands/cert_dump.rb @@ -64,6 +64,8 @@ class CertDump < ValueProcessorCommand include CommandKit::Printing::Lists include HostAndPort + command_name 'cert-dump' + usage '[options] {HOST:PORT | URL | FILE} ...' option :common_name, short: '-C', diff --git a/lib/ronin/cli/commands/cert_gen.rb b/lib/ronin/cli/commands/cert_gen.rb index 9d8b33c64..152c99c34 100644 --- a/lib/ronin/cli/commands/cert_gen.rb +++ b/lib/ronin/cli/commands/cert_gen.rb @@ -72,6 +72,8 @@ class CertGen < Command include Core::CLI::Logging + command_name 'cert-gen' + option :version, value: { type: Integer, usage: 'NUM', diff --git a/lib/ronin/cli/commands/cert_grab.rb b/lib/ronin/cli/commands/cert_grab.rb index 8fc2af6a1..04c232077 100644 --- a/lib/ronin/cli/commands/cert_grab.rb +++ b/lib/ronin/cli/commands/cert_grab.rb @@ -52,6 +52,8 @@ class CertGrab < ValueProcessorCommand include HostAndPort + command_name 'cert-grab' + usage '[options] {HOST:PORT | URL} ...' argument :target, required: true, diff --git a/lib/ronin/cli/commands/completion.rb b/lib/ronin/cli/commands/completion.rb new file mode 100644 index 000000000..7ba22f284 --- /dev/null +++ b/lib/ronin/cli/commands/completion.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true +# +# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com) +# +# Ronin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ronin 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ronin. If not, see . +# + +require 'ronin/core/cli/completion_command' +require 'ronin/repos/cli/commands/completion' +require 'ronin/db/cli/commands/completion' +require 'ronin/fuzzer/cli/commands/completion' +require 'ronin/web/cli/commands/completion' +require 'ronin/vulns/cli/commands/completion' +require 'ronin/payloads/cli/commands/completion' +require 'ronin/exploits/cli/commands/completion' +require 'ronin/listener/cli/commands/completion' +require 'ronin/nmap/cli/commands/completion' +require 'ronin/masscan/cli/commands/completion' +require 'ronin/recon/cli/commands/completion' +require 'ronin/root' + +module Ronin + class CLI + module Commands + # + # Manages the shell completion rule for `ronin` and all other `ronin-*` + # commands. + # + # ## Usage + # + # ronin completion [options] + # + # ## Options + # + # --print Prints the shell completion file + # --install Installs the shell completion file + # --uninstall Uninstalls the shell completion file + # -h, --help Print help information + # + # ## Examples + # + # ronin completion --print + # ronin completion --install + # ronin completion --uninstall + # + # @since 2.1.0 + # + class Completion < Core::CLI::CompletionCommand + + man_dir File.join(ROOT,'man') + man_page 'ronin-completion.1' + + description 'Manages the shell completion rules for ronin and all other ronin-* commands' + + # All shell completion files for `ronin` and the other `ronin-*` + # commands. + COMPLETION_FILES = [ + File.join(ROOT,'data','completions','ronin'), + + Repos::CLI::Commands::Completion.completion_file, + DB::CLI::Commands::Completion.completion_file, + Fuzzer::CLI::Commands::Completion.completion_file, + Web::CLI::Commands::Completion.completion_file, + Vulns::CLI::Commands::Completion.completion_file, + Payloads::CLI::Commands::Completion.completion_file, + Exploits::CLI::Commands::Completion.completion_file, + Listener::CLI::Commands::Completion.completion_file, + Nmap::CLI::Commands::Completion.completion_file, + Masscan::CLI::Commands::Completion.completion_file, + Recon::CLI::Commands::Completion.completion_file + ] + + # + # Prints all completion files. + # + def print_completion_file + COMPLETION_FILES.each do |completion_file| + super(completion_file) + end + end + + # + # Installs all completion files. + # + def install_completion_file + COMPLETION_FILES.each do |completion_file| + super(completion_file) + end + end + + # + # Uninstall all completion files. + # + def uninstall_completion_file + COMPLETION_FILES.each do |completion_file| + super(completion_file) + end + end + end + end + end +end diff --git a/lib/ronin/cli/commands/new/dns_listener.rb b/lib/ronin/cli/commands/new/dns_listener.rb index 69df3fad6..67761313d 100644 --- a/lib/ronin/cli/commands/new/dns_listener.rb +++ b/lib/ronin/cli/commands/new/dns_listener.rb @@ -26,7 +26,11 @@ class New < Command # An alias for `ronin-listener new dns`. # # @since 2.1.0 - DnsListener = Ronin::Listener::CLI::Commands::New::Dns + class DnsListener < Ronin::Listener::CLI::Commands::New::Dns + + command_name 'dns-listener' + + end end end end diff --git a/lib/ronin/cli/commands/new/dns_proxy.rb b/lib/ronin/cli/commands/new/dns_proxy.rb index f70421e62..9c6c7e1dd 100644 --- a/lib/ronin/cli/commands/new/dns_proxy.rb +++ b/lib/ronin/cli/commands/new/dns_proxy.rb @@ -51,6 +51,8 @@ class DnsProxy < Command template_dir File.join(ROOT,'data','templates') + command_name 'dns-proxy' + usage 'PATH' option :host, short: '-H', diff --git a/lib/ronin/cli/commands/new/exploit.rb b/lib/ronin/cli/commands/new/exploit.rb index f96b98dc7..275c6d9a3 100644 --- a/lib/ronin/cli/commands/new/exploit.rb +++ b/lib/ronin/cli/commands/new/exploit.rb @@ -26,7 +26,8 @@ class New < Command # An alias for `ronin-exploits new`. # # @since 2.1.0 - Exploit = Ronin::Exploits::CLI::Commands::New + class Exploit < Ronin::Exploits::CLI::Commands::New + end end end end diff --git a/lib/ronin/cli/commands/new/http_listener.rb b/lib/ronin/cli/commands/new/http_listener.rb index 7e3504e0f..5a8a520c2 100644 --- a/lib/ronin/cli/commands/new/http_listener.rb +++ b/lib/ronin/cli/commands/new/http_listener.rb @@ -26,7 +26,11 @@ class New < Command # An alias for `ronin-listener new http`. # # @since 2.1.0 - HttpListener = Ronin::Listener::CLI::Commands::New::Http + class HttpListener < Ronin::Listener::CLI::Commands::New::Http + + command_name 'http-listener' + + end end end end diff --git a/lib/ronin/cli/commands/new/payload.rb b/lib/ronin/cli/commands/new/payload.rb index 068cf2aad..77fee10fe 100644 --- a/lib/ronin/cli/commands/new/payload.rb +++ b/lib/ronin/cli/commands/new/payload.rb @@ -26,7 +26,8 @@ class New < Command # An alias for `ronin-payloads new`. # # @since 2.1.0 - Payload = Ronin::Payloads::CLI::Commands::New + class Payload < Ronin::Payloads::CLI::Commands::New + end end end end diff --git a/lib/ronin/cli/commands/new/web_app.rb b/lib/ronin/cli/commands/new/web_app.rb index e0768f35c..fd68bbe9e 100644 --- a/lib/ronin/cli/commands/new/web_app.rb +++ b/lib/ronin/cli/commands/new/web_app.rb @@ -26,7 +26,11 @@ class New < Command # An alias for `ronin-web new app`. # # @since 2.1.0 - WebApp = Ronin::Web::CLI::Commands::New::App + class WebApp < Ronin::Web::CLI::Commands::New::App + + command_name 'web-app' + + end end end end diff --git a/lib/ronin/cli/commands/new/web_server.rb b/lib/ronin/cli/commands/new/web_server.rb index d0d900ec2..8c172562a 100644 --- a/lib/ronin/cli/commands/new/web_server.rb +++ b/lib/ronin/cli/commands/new/web_server.rb @@ -26,7 +26,11 @@ class New < Command # An alias for `ronin-web new server`. # # @since 2.1.0 - WebServer = Ronin::Web::CLI::Commands::New::Server + class WebServer < Ronin::Web::CLI::Commands::New::Server + + command_name 'web-server' + + end end end end diff --git a/lib/ronin/cli/commands/new/web_spider.rb b/lib/ronin/cli/commands/new/web_spider.rb index bc90e67bb..cb8c44ca1 100644 --- a/lib/ronin/cli/commands/new/web_spider.rb +++ b/lib/ronin/cli/commands/new/web_spider.rb @@ -26,7 +26,11 @@ class New < Command # An alias for `ronin-web new spider`. # # @since 2.1.0 - WebSpider = Ronin::Web::CLI::Commands::New::Spider + class WebSpider < Ronin::Web::CLI::Commands::New::Spider + + command_name 'web-spider' + + end end end end diff --git a/lib/ronin/cli/commands/public_suffix_list.rb b/lib/ronin/cli/commands/public_suffix_list.rb index d985c5bf5..d47b2a8b3 100644 --- a/lib/ronin/cli/commands/public_suffix_list.rb +++ b/lib/ronin/cli/commands/public_suffix_list.rb @@ -46,6 +46,8 @@ class PublicSuffixList < Command include CommandKit::Options::Verbose include Core::CLI::Logging + command_name 'public-suffix-list' + option :update, short: '-u', desc: 'Updates the public suffix list file' diff --git a/lib/ronin/cli/commands/tld_list.rb b/lib/ronin/cli/commands/tld_list.rb index 163504200..1bf7c3a7e 100644 --- a/lib/ronin/cli/commands/tld_list.rb +++ b/lib/ronin/cli/commands/tld_list.rb @@ -46,6 +46,8 @@ class TldList < Command include CommandKit::Options::Verbose include Core::CLI::Logging + command_name 'tld-list' + option :update, short: '-u', desc: 'Updates the TLD list file' diff --git a/man/ronin-completion.1.md b/man/ronin-completion.1.md new file mode 100644 index 000000000..7227458d3 --- /dev/null +++ b/man/ronin-completion.1.md @@ -0,0 +1,80 @@ +# ronin-completion 1 "2024-01-01" Ronin "User Manuals" + +## NAME + +ronin-completion - Manages shell completion rules for `ronin-repos` + +## SYNOPSIS + +`ronin-repos completion` [*options*] + +## DESCRIPTION + +The `ronin completion` command can print, install, or uninstall shell +completion rules for the `ronin` command and all other `ronin-*` commands. + +Supports installing completion rules for Bash or Zsh shells. +Completion rules for the Fish shell is currently not supported. + +### ZSH SUPPORT + +Zsh users will have to add the following lines to their `~/.zshrc` file in +order to enable Zsh's Bash completion compatibility layer: + + autoload -Uz +X compinit && compinit + autoload -Uz +X bashcompinit && bashcompinit + +## OPTIONS + +`--print` +: Prints the shell completion file. + +`--install` +: Installs the shell completion file. + +`--uninstall` +: Uninstalls the shell completion file. + +`-h`, `--help` +: Prints help information. + +## ENVIRONMENT + +*PREFIX* +: Specifies the root prefix for the file system. + +*HOME* +: Specifies the home directory of the user. Ronin will search for the + `~/.cache/ronin-repos` cache directory within the home directory. + +*XDG_DATA_HOME* +: Specifies the data directory to use. Defaults to `$HOME/.local/share`. + +## FILES + +`~/.local/share/bash-completion/completions/` +: The user-local installation directory for Bash completion files. + +`/usr/local/share/bash-completion/completions/` +: The system-wide installation directory for Bash completions files. + +`/usr/local/share/zsh/site-functions/` +: The installation directory for Zsh completion files. + +## EXAMPLES + +`ronin completion --print` +: Prints all shell completion rules instead of installing them. + +`ronin completion --install` +: Installs all shell completion rules for `ronin` and the other `ronin-*` + commands. + +`ronin-repos completion --uninstall` +: Uninstalls all shell completion rules for `ronin` and the other `ronin-*` + commands. + +## AUTHOR + +Postmodern + diff --git a/spec/cli/commands/completion_spec.rb b/spec/cli/commands/completion_spec.rb new file mode 100644 index 000000000..2e99839bc --- /dev/null +++ b/spec/cli/commands/completion_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' +require 'ronin/cli/commands/completion' +require_relative 'man_page_example' + +describe Ronin::CLI::Commands::Completion do + it "must inherit from Ronin::Core::CLI::CompletionCommand" do + expect(described_class).to be < Ronin::Core::CLI::CompletionCommand + end + + it "must set man_dir" do + expect(described_class.man_dir).to_not be(nil) + expect(File.directory?(described_class.man_dir)).to be(true) + end + + include_examples "man_page" +end