diff --git a/lib/metasploit/framework/command/console.rb b/lib/metasploit/framework/command/console.rb index 3c476574289c..d104a042d33b 100644 --- a/lib/metasploit/framework/command/console.rb +++ b/lib/metasploit/framework/command/console.rb @@ -92,7 +92,6 @@ def driver_options driver_options['ModulePath'] = options.modules.path driver_options['Plugins'] = options.console.plugins driver_options['Readline'] = options.console.readline - driver_options['RealReadline'] = options.console.real_readline driver_options['Resource'] = options.console.resources driver_options['XCommands'] = options.console.commands diff --git a/lib/metasploit/framework/parsed_options/console.rb b/lib/metasploit/framework/parsed_options/console.rb index 34aa126633aa..333f3a74520b 100644 --- a/lib/metasploit/framework/parsed_options/console.rb +++ b/lib/metasploit/framework/parsed_options/console.rb @@ -16,7 +16,6 @@ def options options.console.plugins = [] options.console.quiet = false options.console.readline = true - options.console.real_readline = false options.console.resources = [] options.console.subcommand = :run } @@ -54,7 +53,10 @@ def option_parser end option_parser.on('-L', '--real-readline', 'Use the system Readline library instead of RbReadline') do - options.console.real_readline = true + message = "The RealReadline option has been marked as deprecated, and is currently a noop.\n" + message << "If you require this functionality, please use the following link to tell us:\n" + message << ' https://github.com/rapid7/metasploit-framework/issues/19399' + warn message end option_parser.on('-o', '--output FILE', 'Output to the specified file') do |file| diff --git a/lib/metasploit/framework/parsed_options/remote_db.rb b/lib/metasploit/framework/parsed_options/remote_db.rb index 49dd9c466644..5344539bfd42 100644 --- a/lib/metasploit/framework/parsed_options/remote_db.rb +++ b/lib/metasploit/framework/parsed_options/remote_db.rb @@ -13,7 +13,6 @@ def options options.console.local_output = nil options.console.plugins = [] options.console.quiet = false - options.console.real_readline = false options.console.resources = [] options.console.subcommand = :run } diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index 199980028499..c5b45b61f582 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -53,8 +53,6 @@ class Driver < Msf::Ui::Driver # @option opts [Boolean] 'AllowCommandPassthru' (true) Whether to allow # unrecognized commands to be executed by the system shell # @option opts [Boolean] 'Readline' (true) Whether to use the readline or not - # @option opts [Boolean] 'RealReadline' (false) Whether to use the system's - # readline library instead of RBReadline # @option opts [String] 'HistFile' (Msf::Config.history_file) Path to a file # where we can store command history # @option opts [Array] 'Resources' ([]) A list of resource files to @@ -64,7 +62,7 @@ class Driver < Msf::Ui::Driver # @option opts [Boolean] 'SkipDatabaseInit' (false) Whether to skip # connecting to the database and running migrations def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {}) - choose_readline(opts) + setup_readline if opts['Readline'] histfile = opts['HistFile'] || Msf::Config.history_file @@ -132,14 +130,6 @@ def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = { # stack enstack_dispatcher(CommandDispatcher::Core) - # Report readline error if there was one.. - if !@rl_err.nil? - print_error("***") - print_error("* Unable to load readline: #{@rl_err}") - print_error("* Falling back to RbReadLine") - print_error("***") - end - # Load the other "core" command dispatchers CommandDispatchers.each do |dispatcher_class| dispatcher = enstack_dispatcher(dispatcher_class) @@ -706,77 +696,46 @@ def handle_session_tlv_logging(val) # Require the appropriate readline library based on the user's preference. # # @return [void] - def choose_readline(opts) - # Choose a readline library before calling the parent - @rl_err = nil - if opts['RealReadline'] - # Remove the gem version from load path to be sure we're getting the - # stdlib readline. - gem_dir = Gem::Specification.find_all_by_name('rb-readline').first.gem_dir - rb_readline_path = File.join(gem_dir, "lib") - index = $LOAD_PATH.index(rb_readline_path) - # Bundler guarantees that the gem will be there, so it should be safe to - # assume we found it in the load path, but check to be on the safe side. - if index - $LOAD_PATH.delete_at(index) - end - end + def setup_readline + require 'readline' + + # Only Windows requires a monkey-patched RbReadline + return unless Rex::Compat.is_windows + + if defined?(::RbReadline) && !defined?(RbReadline.refresh_console_handle) + ::RbReadline.instance_eval do + class << self + alias_method :old_rl_move_cursor_relative, :_rl_move_cursor_relative + alias_method :old_rl_get_screen_size, :_rl_get_screen_size + alias_method :old_space_to_eol, :space_to_eol + alias_method :old_insert_some_chars, :insert_some_chars + end - begin - require 'readline' - - # Only Windows requires a monkey-patched RbReadline - return unless Rex::Compat.is_windows - - if defined?(::RbReadline) && !defined?(RbReadline.refresh_console_handle) - ::RbReadline.instance_eval do - class << self - alias_method :old_rl_move_cursor_relative, :_rl_move_cursor_relative - alias_method :old_rl_get_screen_size, :_rl_get_screen_size - alias_method :old_space_to_eol, :space_to_eol - alias_method :old_insert_some_chars, :insert_some_chars - end - - def self.refresh_console_handle - # hConsoleHandle gets set only when RbReadline detects it is running on Windows. - # Therefore, we don't need to check Rex::Compat.is_windows, we can simply check if hConsoleHandle is nil or not. - @hConsoleHandle = @GetStdHandle.Call(::Readline::STD_OUTPUT_HANDLE) if @hConsoleHandle - end - - def self._rl_move_cursor_relative(*args) - refresh_console_handle - old_rl_move_cursor_relative(*args) - end - - def self._rl_get_screen_size(*args) - refresh_console_handle - old_rl_get_screen_size(*args) - end - - def self.space_to_eol(*args) - refresh_console_handle - old_space_to_eol(*args) - end - - def self.insert_some_chars(*args) - refresh_console_handle - old_insert_some_chars(*args) - end + def self.refresh_console_handle + # hConsoleHandle gets set only when RbReadline detects it is running on Windows. + # Therefore, we don't need to check Rex::Compat.is_windows, we can simply check if hConsoleHandle is nil or not. + @hConsoleHandle = @GetStdHandle.Call(::Readline::STD_OUTPUT_HANDLE) if @hConsoleHandle + end + + def self._rl_move_cursor_relative(*args) + refresh_console_handle + old_rl_move_cursor_relative(*args) + end + + def self._rl_get_screen_size(*args) + refresh_console_handle + old_rl_get_screen_size(*args) + end + + def self.space_to_eol(*args) + refresh_console_handle + old_space_to_eol(*args) + end + + def self.insert_some_chars(*args) + refresh_console_handle + old_insert_some_chars(*args) end - end - rescue ::LoadError => e - if @rl_err.nil? && index - # Then this is the first time the require failed and we have an index - # for the gem version as a fallback. - @rl_err = e - # Put the gem back and see if that works - $LOAD_PATH.insert(index, rb_readline_path) - index = rb_readline_path = nil - retry - else - # Either we didn't have the gem to fall back on, or we failed twice. - # Nothing more we can do here. - raise e end end end