lib/rex/ui/interactive.rb in librex-0.0.68 vs lib/rex/ui/interactive.rb in librex-0.0.70
- old
+ new
@@ -8,295 +8,295 @@
# user interface that is backed against something arbitrary.
#
###
module Interactive
- #
- # Interactive sessions by default may interact with the local user input
- # and output.
- #
- include Rex::Ui::Subscriber
+ #
+ # Interactive sessions by default may interact with the local user input
+ # and output.
+ #
+ include Rex::Ui::Subscriber
- #
- # 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.
- #
- def interact(user_input, user_output)
+ #
+ # 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.
+ #
+ def interact(user_input, user_output)
- # Detach from any existing console
- if(self.interacting)
- detach()
- end
+ # Detach from any existing console
+ if(self.interacting)
+ detach()
+ end
- init_ui(user_input, user_output)
+ init_ui(user_input, user_output)
- self.interacting = true
- self.completed = false
+ self.interacting = true
+ self.completed = false
- eof = false
+ eof = false
- # Start the readline stdin monitor
- # XXX disabled
- # user_input.readline_start() if user_input.supports_readline
+ # Start the readline stdin monitor
+ # XXX disabled
+ # user_input.readline_start() if user_input.supports_readline
- # Handle suspend notifications
- handle_suspend
+ # Handle suspend notifications
+ handle_suspend
- # As long as we're interacting...
- while (self.interacting == true)
+ # As long as we're interacting...
+ while (self.interacting == true)
- begin
- _interact
+ 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 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
+ rescue EOFError, Errno::ECONNRESET, IOError
+ # If we reach EOF or the connection is reset...
+ eof = true
- end
+ end
- break if eof
- end
+ break if eof
+ end
- begin
+ begin
- # Restore the suspend handler
- restore_suspend
+ # Restore the suspend handler
+ restore_suspend
- # If we've hit eof, call the interact complete handler
- _interact_complete if (eof == true)
+ # If we've hit eof, call the interact complete handler
+ _interact_complete if (eof == true)
- # Shutdown the readline thread
+ # Shutdown the readline thread
# XXX disabled
- # user_input.readline_stop() if user_input.supports_readline
+ # user_input.readline_stop() if user_input.supports_readline
- # Detach from the input/output handles
- reset_ui()
+ # Detach from the input/output handles
+ reset_ui()
- ensure
- # Mark this as completed
- self.completed = true
- end
+ ensure
+ # Mark this as completed
+ self.completed = true
+ end
- # Return whether or not EOF was reached
- return eof
- end
+ # Return whether or not EOF was reached
+ return eof
+ end
- #
- # Stops the current interaction
- #
- def detach
- if (self.interacting)
- self.interacting = false
- while(not self.completed)
- ::IO.select(nil, nil, nil, 0.25)
- end
- end
- end
+ #
+ # Stops the current interaction
+ #
+ def detach
+ if (self.interacting)
+ self.interacting = false
+ while(not self.completed)
+ ::IO.select(nil, nil, nil, 0.25)
+ end
+ end
+ end
- #
- # Whether or not the session is currently being interacted with
- #
- attr_accessor :interacting
+ #
+ # Whether or not the session is currently being interacted with
+ #
+ attr_accessor :interacting
- #
- # Whether or not the session has completed interaction
- #
- attr_accessor :completed
+ #
+ # Whether or not the session has completed interaction
+ #
+ attr_accessor :completed
- attr_accessor :on_print_proc
- attr_accessor :on_command_proc
+ attr_accessor :on_print_proc
+ attr_accessor :on_command_proc
protected
- #
- # The original suspend proc.
- #
- attr_accessor :orig_suspend
+ #
+ # The original suspend proc.
+ #
+ attr_accessor :orig_suspend
- #
- # Stub method that is meant to handler interaction
- #
- def _interact
- end
+ #
+ # Stub method that is meant to handler interaction
+ #
+ def _interact
+ end
- #
- # Called when an interrupt is sent.
- #
- def _interrupt
- true
- end
+ #
+ # Called when an interrupt is sent.
+ #
+ def _interrupt
+ true
+ end
- #
- # Called when a suspend is sent.
- #
- def _suspend
- false
- end
+ #
+ # Called when a suspend is sent.
+ #
+ def _suspend
+ false
+ end
- #
- # Called when interaction has completed and one of the sides has closed.
- #
- def _interact_complete
- true
- end
+ #
+ # Called when interaction has completed and one of the sides has closed.
+ #
+ def _interact_complete
+ true
+ end
- #
- # Read from remote and write to local.
- #
- def _stream_read_remote_write_local(stream)
- data = stream.get
+ #
+ # Read from remote and write to local.
+ #
+ 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
+ self.on_print_proc.call(data) if self.on_print_proc
+ user_output.print(data)
+ end
- #
- # Read from local and write to remote.
- #
- def _stream_read_local_write_remote(stream)
- data = user_input.gets
+ #
+ # Read from local and write to remote.
+ #
+ 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
+ self.on_command_proc.call(data) if self.on_command_proc
+ stream.put(data)
+ end
- #
- # The local file descriptor handle.
- #
- def _local_fd
- user_input.fd
- end
+ #
+ # The local file descriptor handle.
+ #
+ def _local_fd
+ user_input.fd
+ end
- #
- # The remote file descriptor handle.
- #
- def _remote_fd(stream)
- stream.fd
- end
+ #
+ # The remote file descriptor handle.
+ #
+ def _remote_fd(stream)
+ stream.fd
+ end
- #
- # Interacts with two streaming connections, reading data from one and
- # writing it to the other. Both are expected to implement Rex::IO::Stream.
- #
- def interact_stream(stream)
- while self.interacting
+ #
+ # Interacts with two streaming connections, reading data from one and
+ # writing it to the other. Both are expected to implement Rex::IO::Stream.
+ #
+ def interact_stream(stream)
+ while self.interacting
- # Select input and rstream
- sd = Rex::ThreadSafe.select([ _local_fd, _remote_fd(stream) ], nil, nil, 0.25)
+ # 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)
+ # 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
+ Thread.pass
+ end
+ end
- #
- # 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
- #
- def interact_ring(ring)
- begin
+ #
+ # 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
+ #
+ def interact_ring(ring)
+ begin
- rdr = Rex::ThreadFactory.spawn("RingMonitor", false) do
- seq = nil
- while self.interacting
+ 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)
+ # Look for any pending data from the remote ring
+ nseq,data = ring.read_data(seq)
- # Update the sequence number if necessary
- seq = nseq || seq
+ # Update the sequence number if necessary
+ seq = nseq || seq
- # Write output to the local stream if successful
- user_output.print(data) if data
+ # 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
+ # Wait for new data to arrive on this session
+ ring.wait(seq)
+ end
+ end
- while self.interacting
+ while self.interacting
- # Look for any pending input from the local stream
- sd = Rex::ThreadSafe.select([ _local_fd ], nil, [_local_fd], 5.0)
+ # 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
+ # Write input to the ring's input mechanism
+ if sd
+ data = user_input.gets
+ ring.put(data)
+ end
+ end
- ensure
- rdr.kill
- end
- end
+ ensure
+ rdr.kill
+ end
+ end
- #
- # Installs a signal handler to monitor suspend signal notifications.
- #
- def handle_suspend
- if (orig_suspend == nil)
- begin
- self.orig_suspend = Signal.trap("TSTP") {
- _suspend
- }
- rescue
- end
- end
- end
+ #
+ # Installs a signal handler to monitor suspend signal notifications.
+ #
+ def handle_suspend
+ if (orig_suspend == nil)
+ begin
+ self.orig_suspend = Signal.trap("TSTP") {
+ _suspend
+ }
+ rescue
+ end
+ end
+ end
- #
- # Restores the previously installed signal handler for suspend
- # notifications.
- #
- 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
+ #
+ # Restores the previously installed signal handler for suspend
+ # notifications.
+ #
+ 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
- #
- # Prompt the user for input if possible.
- # XXX: This is not thread-safe on Windows
- #
- def prompt(query)
- if (user_output and user_input)
- user_output.print("\n" + query)
- user_input.sysread(2)
- end
- end
+ #
+ # Prompt the user for input if possible.
+ # XXX: This is not thread-safe on Windows
+ #
+ def prompt(query)
+ if (user_output and user_input)
+ user_output.print("\n" + query)
+ user_input.sysread(2)
+ end
+ end
- #
- # Check the return value of a yes/no prompt
- #
- def prompt_yesno(query)
- (prompt(query + " [y/N] ") =~ /^y/i) ? true : false
- end
+ #
+ # Check the return value of a yes/no prompt
+ #
+ def prompt_yesno(query)
+ (prompt(query + " [y/N] ") =~ /^y/i) ? true : false
+ end
end
end
end