Class/Module Index [+]

Quicksearch

Rex::Ui::Text::Shell

The shell class provides a command-prompt style interface in a generic fashion.

Attributes

disable_output[RW]

Whether or not output has been disabled.

framework[RW]
hist_last_saved[RW]
input[R]

The input handle to read user input from.

on_command_proc[RW]
on_print_proc[RW]
output[R]

The output handle to write output to.

Public Class Methods

new(prompt, prompt_char = '>', histfile = nil, framework = nil) click to toggle source

Initializes a shell that has a prompt and can be interacted with.

# File lib/rex/ui/text/shell.rb, line 40
def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
        # Set the stop flag to false
        self.stop_flag      = false
        self.disable_output = false
        self.stop_count           = 0

        # Initialize the prompt
        self.init_prompt = prompt
        self.prompt_char = prompt_char

        self.histfile = histfile
        self.hist_last_saved = 0

        self.framework = framework
end

Public Instance Methods

init_tab_complete() click to toggle source
# File lib/rex/ui/text/shell.rb, line 56
def init_tab_complete
        if (self.input and self.input.supports_readline)
                self.input = Input::Readline.new(lambda { |str| tab_complete(str) })
                if Readline::HISTORY.length == 0 and histfile and File.exists?(histfile)
                        File.readlines(histfile).each { |e|
                                Readline::HISTORY << e.chomp
                        }
                        self.hist_last_saved = Readline::HISTORY.length
                end
                self.input.output = self.output
                update_prompt(input.prompt)
        end
end
init_ui(in_input = nil, in_output = nil) click to toggle source

Initializes the user interface input/output classes.

# File lib/rex/ui/text/shell.rb, line 73
def init_ui(in_input = nil, in_output = nil)
        # Initialize the input and output methods
        self.input  = in_input
        self.output = in_output

        if (self.input)
                # Extend the input medium as an input shell if the input medium
                # isn't intrinsicly a shell.
                if (self.input.intrinsic_shell? == false)
                        self.input.extend(InputShell)
                end

                self.input.output = self.output
        end
        update_prompt('')
end
reset_ui() click to toggle source

Resets the user interface handles.

# File lib/rex/ui/text/shell.rb, line 93
def reset_ui
        init_ui
end
run(&block) click to toggle source

Run the command processing loop.

# File lib/rex/ui/text/shell.rb, line 121
def run(&block)

        begin

                while true
                        # If the stop flag was set or we've hit EOF, break out
                        break if (self.stop_flag or self.stop_count > 1)

                        init_tab_complete

                        if framework
                                if input.prompt.include?("%T")
                                        t = Time.now
                                        if framework.datastore['PromptTimeFormat']
                                                t = t.strftime(framework.datastore['PromptTimeFormat'])
                                        end
                                        input.prompt.gsub!(/%T/, t.to_s)
                                end

                                if input.prompt.include?("%H")
                                        hostname = ENV['HOSTNAME']
                                        if hostname.nil?
                                                hostname = `hostname`.split('.')[0]
                                        end

                                        # check if hostname is still nil
                                        if hostname.nil?
                                                hostname = ENV['COMPUTERNAME']
                                        end

                                        if hostname.nil?
                                                hostname = 'unknown'
                                        end

                                        input.prompt.gsub!(/%H/, hostname.chomp)
                                end

                                if input.prompt.include?("%U")
                                        user = ENV['USER']
                                        if user.nil?
                                                user = `whoami`
                                        end

                                        # check if username is still nil
                                        if user.nil?
                                                user = ENV['USERNAME']
                                        end

                                        if user.nil?
                                                user = 'unknown'
                                        end

                                        input.prompt.gsub!(/%U/, user.chomp)
                                end

                                input.prompt.gsub!(/%S/, framework.sessions.length.to_s)
                                input.prompt.gsub!(/%J/, framework.jobs.length.to_s)
                                input.prompt.gsub!(/%L/, Rex::Socket.source_address("50.50.50.50"))
                                input.prompt.gsub!(/%D/, ::Dir.getwd)
                                self.init_prompt = input.prompt
                        end

                        line = input.pgets()
                        log_output(input.prompt)

                        # If a block was passed in, pass the line to it.  If it returns true,
                        # break out of the shell loop.
                        if (block)
                                break if (line == nil or block.call(line))
                        elsif(input.eof? or line == nil)
                        # If you have sessions active, this will give you a shot to exit gravefully
                        # If you really are ambitious, 2 eofs will kick this out
                                self.stop_count += 1
                                next if(self.stop_count > 1)
                                run_single("quit")
                        else
                        # Otherwise, call what should be an overriden instance method to
                        # process the line.
                                ret = run_single(line)
                                # don't bother saving lines that couldn't be found as a
                                # command, create the file if it doesn't exist
                                if ret and self.histfile
                                        File.open(self.histfile, "a+") { |f|
                                                f.puts(line)
                                        }
                                end
                                self.stop_count = 0
                        end

                end
        # Prevent accidental console quits
        rescue ::Interrupt
                output.print("Interrupt: use the 'exit' command to quit\n")
                retry
        end
end
set_log_source(log_source) click to toggle source

Sets the log source that should be used for logging input and output.

# File lib/rex/ui/text/shell.rb, line 100
def set_log_source(log_source)
        self.log_source = log_source
end
stop() click to toggle source

Stop processing user input.

# File lib/rex/ui/text/shell.rb, line 221
def stop
        self.stop_flag = true
end
stopped?() click to toggle source

Checks to see if the shell has stopped.

# File lib/rex/ui/text/shell.rb, line 228
def stopped?
        self.stop_flag
end
tab_complete(str) click to toggle source

Performs tab completion on the supplied string.

# File lib/rex/ui/text/shell.rb, line 114
def tab_complete(str)
        return tab_complete_proc(str) if (tab_complete_proc)
end
unset_log_source() click to toggle source

Unsets the log source so that logging becomes disabled.

# File lib/rex/ui/text/shell.rb, line 107
def unset_log_source
        set_log_source(nil)
end
update_prompt(prompt = nil, new_prompt_char = nil, mode = false) click to toggle source

Change the input prompt.

prompt - the actual prompt new_prompt_char the char to append to the prompt mode - append or not to append - false = append true = make a new prompt

# File lib/rex/ui/text/shell.rb, line 238
def update_prompt(prompt = nil, new_prompt_char = nil, mode = false)
        if (self.input)
                if prompt
                        new_prompt = self.init_prompt + ' ' + prompt + prompt_char + ' '
                else
                        new_prompt = self.prompt || ''
                end

                if mode
                  new_prompt = prompt + (new_prompt_char || prompt_char) + ' '
                end

                # Save the prompt before any substitutions
                self.prompt = new_prompt

                # Set the actual prompt to the saved prompt with any substitutions
                # or updates from our output driver, be they color or whatever
                self.input.prompt = self.output.update_prompt(new_prompt)
                self.prompt_char  = new_prompt_char if (new_prompt_char)
        end
end

Protected Instance Methods

_print_prompt(prompt) click to toggle source

Print the prompt, but do not log it.

# File lib/rex/ui/text/shell.rb, line 353
def _print_prompt(prompt)
        output.print(prompt)
end
log_input(buf) click to toggle source

Writes the supplied input to the log source if one has been registered.

# File lib/rex/ui/text/shell.rb, line 360
def log_input(buf)
        rlog(buf, log_source) if (log_source)
end
log_output(buf) click to toggle source

Writes the supplied output to the log source if one has been registered.

# File lib/rex/ui/text/shell.rb, line 367
def log_output(buf)
        rlog(buf, log_source) if (log_source)
end
parse_line(line) click to toggle source

Parse a line into an array of arguments.

# File lib/rex/ui/text/shell.rb, line 336
def parse_line(line)
        log_input(line)

        line.gsub!(/(\r|\n)/, '')

        begin
                return args = Rex::Parser::Arguments.from_s(line)
        rescue ::ArgumentError
                print_error("Parse error: #{$!}")
        end

        return []
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.