Included Modules

Class/Module Index [+]

Quicksearch

Rex::Ui::Interactive

This class implements the stubs that are needed to provide an interactive user interface that is backed against something arbitrary.

Attributes

completed[RW]

Whether or not the session has completed interaction

interacting[RW]

Whether or not the session is currently being interacted with

on_command_proc[RW]
on_print_proc[RW]
orig_suspend[RW]

The original suspend proc.

Public Instance Methods

detach() click to toggle source

Stops the current interaction

# File lib/rex/ui/interactive.rb, line 92
def detach
        if (self.interacting)
                self.interacting = false
                while(not self.completed)
                        ::IO.select(nil, nil, nil, 0.25)
                end
        end
end
interact(user_input, user_output) click to toggle source

Starts interacting with the session at the most raw level, simply forwarding input from user_input to rstream and forwarding input from rstream to user_output.

# File lib/rex/ui/interactive.rb, line 23
def interact(user_input, user_output)

        # Detach from any existing console
        if(self.interacting)
                detach()
        end

        init_ui(user_input, user_output)

        self.interacting = true
        self.completed = false

        eof = false

        # Start the readline stdin monitor
        # XXX disabled
        # user_input.readline_start() if user_input.supports_readline

        # Handle suspend notifications
        handle_suspend

        # As long as we're interacting...
        while (self.interacting == true)

                begin
                        _interact

                rescue Interrupt
                        # If we get an interrupt exception, ask the user if they want to
                        # abort the interaction.  If they do, then we return out of
                        # the interact function and call it a day.
                        eof = true if (_interrupt)

                rescue EOFError, Errno::ECONNRESET, IOError
                        # If we reach EOF or the connection is reset...
                        eof = true

                end

                break if eof
        end

        begin

                # Restore the suspend handler
                restore_suspend

                # If we've hit eof, call the interact complete handler
                _interact_complete if (eof == true)

                # Shutdown the readline thread
                # XXX disabled
                # user_input.readline_stop() if user_input.supports_readline

                # Detach from the input/output handles
                reset_ui()

        ensure
                # Mark this as completed
                self.completed = true
        end

        # Return whether or not EOF was reached
        return eof
end

Protected Instance Methods

_interact() click to toggle source

Stub method that is meant to handler interaction

# File lib/rex/ui/interactive.rb, line 124
def _interact
end
_interact_complete() click to toggle source

Called when interaction has completed and one of the sides has closed.

# File lib/rex/ui/interactive.rb, line 144
def _interact_complete
        true
end
_interrupt() click to toggle source

Called when an interrupt is sent.

# File lib/rex/ui/interactive.rb, line 130
def _interrupt
        true
end
_local_fd() click to toggle source

The local file descriptor handle.

# File lib/rex/ui/interactive.rb, line 171
def _local_fd
        user_input.fd
end
_remote_fd(stream) click to toggle source

The remote file descriptor handle.

# File lib/rex/ui/interactive.rb, line 178
def _remote_fd(stream)
        stream.fd
end
_stream_read_local_write_remote(stream) click to toggle source

Read from local and write to remote.

# File lib/rex/ui/interactive.rb, line 161
def _stream_read_local_write_remote(stream)
        data = user_input.gets

        self.on_command_proc.call(data) if self.on_command_proc
        stream.put(data)
end
_stream_read_remote_write_local(stream) click to toggle source

Read from remote and write to local.

# File lib/rex/ui/interactive.rb, line 151
def _stream_read_remote_write_local(stream)
        data = stream.get

        self.on_print_proc.call(data) if self.on_print_proc
        user_output.print(data)
end
_suspend() click to toggle source

Called when a suspend is sent.

# File lib/rex/ui/interactive.rb, line 137
def _suspend
        false
end
handle_suspend() click to toggle source

Installs a signal handler to monitor suspend signal notifications.

# File lib/rex/ui/interactive.rb, line 254
def handle_suspend
        if (orig_suspend == nil)
                begin
                        self.orig_suspend = Signal.trap("TSTP") {
                                _suspend
                        }
                rescue
                end
        end
end
interact_ring(ring) click to toggle source

Interacts between a local stream and a remote ring buffer. This has to use a secondary thread to prevent the select on the local stream from blocking

# File lib/rex/ui/interactive.rb, line 212
def interact_ring(ring)
        begin

        rdr = Rex::ThreadFactory.spawn("RingMonitor", false) do
                seq = nil
                while self.interacting

                        # Look for any pending data from the remote ring
                        nseq,data = ring.read_data(seq)

                        # Update the sequence number if necessary
                        seq = nseq || seq

                        # Write output to the local stream if successful
                        user_output.print(data) if data

                        # Wait for new data to arrive on this session
                        ring.wait(seq)
                end
        end

        while self.interacting

                # Look for any pending input from the local stream
                sd = Rex::ThreadSafe.select([ _local_fd ], nil, [_local_fd], 5.0)

                # Write input to the ring's input mechanism
                if sd
                        data = user_input.gets
                        ring.put(data)
                end
        end

        ensure
                rdr.kill
        end
end
interact_stream(stream) click to toggle source

Interacts with two streaming connections, reading data from one and writing it to the other. Both are expected to implement Rex::IO::Stream.

# File lib/rex/ui/interactive.rb, line 186
def interact_stream(stream)
        while self.interacting

                # Select input and rstream
                sd = Rex::ThreadSafe.select([ _local_fd, _remote_fd(stream) ], nil, nil, 0.25)

                # Cycle through the items that have data
                # From the stream?  Write to user_output.
                sd[0].each { |s|
                        if (s == _remote_fd(stream))
                                _stream_read_remote_write_local(stream)
                        # From user_input?  Write to stream.
                        elsif (s == _local_fd)
                                _stream_read_local_write_remote(stream)
                        end
                } if (sd)

                Thread.pass
        end
end
prompt(query) click to toggle source

Prompt the user for input if possible. XXX: This is not thread-safe on Windows

# File lib/rex/ui/interactive.rb, line 285
def prompt(query)
        if (user_output and user_input)
                user_output.print("\n" + query)
                user_input.sysread(2)
        end
end
prompt_yesno(query) click to toggle source

Check the return value of a yes/no prompt

# File lib/rex/ui/interactive.rb, line 295
def prompt_yesno(query)
        (prompt(query + " [y/N]  ") =~ /^y/) ? true : false
end
restore_suspend() click to toggle source

Restores the previously installed signal handler for suspend notifications.

# File lib/rex/ui/interactive.rb, line 269
def restore_suspend
        begin
                if (orig_suspend)
                        Signal.trap("TSTP", orig_suspend)
                else
                        Signal.trap("TSTP", "DEFAULT")
                end
                self.orig_suspend = nil
        rescue
        end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.