Files
metasploit-gs/lib/msf/core/session/basic.rb
T
Matt Miller 46c2cd2ac1 added ui subscriber stuff
git-svn-id: file:///home/svn/incoming/trunk@2775 4d416f70-5f16-0410-b530-b9f4589650da
2005-07-17 07:06:05 +00:00

152 lines
2.6 KiB
Ruby

module Msf
module Session
###
#
# Basic
# -----
#
# This class implements an interactive session using raw input/output in
# only the most basic fashion.
#
###
module Basic
include Session
include Interactive
#
# Initialize's the raw session
#
def initialize(rstream)
self.rstream = rstream
end
#
# Returns that, yes, indeed, this session supports going interactive with
# the user.
#
def interactive?
true
end
#
# Description of the session
#
def desc
"Basic I/O"
end
#
# Basic session
#
def type
"basic"
end
#
# Returns the local information
#
def tunnel_local
rstream.localinfo
end
#
# Returns the remote peer information
#
def tunnel_peer
rstream.peerinfo
end
#
# Closes rstream.
#
def cleanup
rstream.close if (rstream)
rstream = nil
end
#
# 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
# Call the parent in case it has some work to do
super
eof = false
# Handle suspend notifications
handle_suspend
callcc { |ctx|
# As long as we're interacting...
while (self.interacting == true)
begin
_interact
# 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.
rescue Interrupt
if (user_want_abort? == true)
eof = true
ctx.call
end
rescue EOFError
dlog("Session #{name} got EOF, closing.", 'core', LEV_1)
eof = true
ctx.call
end
end
}
# Restore the suspend handler
restore_suspend
# If we hit end-of-file, then that means we should finish off this
# session and call it a day.
framework.sessions.deregister(self) if (eof == true)
# Return whether or not EOF was reached
return eof
end
#
# The remote stream handle. Must inherit from Rex::IO::Stream.
#
attr_accessor :rstream
protected
#
# Performs the actual raw interaction with the remote side. This can be
# overriden by derived classes if they wish to do this another way.
#
def _interact
while self.interacting
# Select input and rstream
sd = Rex::ThreadSafe.select([ user_input.fd, rstream.fd ])
# Cycle through the items that have data
# From the rstream? Write to user_output.
sd[0].each { |s|
if (s == rstream.fd)
data = rstream.get
user_output.print(data)
# From user_input? Write to rstream.
elsif (s == user_input.fd)
data = user_input.gets
rstream.put(data)
end
} if (sd)
end
end
end
end
end