46c2cd2ac1
git-svn-id: file:///home/svn/incoming/trunk@2775 4d416f70-5f16-0410-b530-b9f4589650da
152 lines
2.6 KiB
Ruby
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
|