module Rex::IO::StreamAbstraction
This class provides an abstraction to a stream based connection through the use of a streaming socketpair.
Attributes
lsock[RW]
The left side of the stream.
monitor_thread[RW]
rsock[RW]
The right side of the stream.
Public Instance Methods
cleanup_abstraction()
click to toggle source
This method cleans up the abstraction layer.
# File lib/ssl_scan/io/stream_abstraction.rb, line 61 def cleanup_abstraction self.lsock.close if (self.lsock) self.rsock.close if (self.rsock) self.lsock = nil self.rsock = nil end
close()
click to toggle source
Closes both sides of the stream abstraction.
# File lib/ssl_scan/io/stream_abstraction.rb, line 93 def close cleanup_abstraction end
initialize_abstraction()
click to toggle source
This method creates a streaming socket pair and initializes it.
# File lib/ssl_scan/io/stream_abstraction.rb, line 49 def initialize_abstraction self.lsock, self.rsock = Rex::Socket.tcp_socket_pair() self.lsock.extend(Rex::IO::Stream) self.lsock.extend(Ext) self.rsock.extend(Rex::IO::Stream) self.monitor_rsock end
localinfo()
click to toggle source
Symbolic local information.
# File lib/ssl_scan/io/stream_abstraction.rb, line 107 def localinfo "Local-side of Pipe" end
peerinfo()
click to toggle source
Symbolic peer information.
# File lib/ssl_scan/io/stream_abstraction.rb, line 100 def peerinfo "Remote-side of Pipe" end
shutdown(how)
click to toggle source
Shuts down the local side of the stream abstraction.
# File lib/ssl_scan/io/stream_abstraction.rb, line 86 def shutdown(how) lsock.shutdown(how) end
sysread(length)
click to toggle source
Low-level read from the local side.
# File lib/ssl_scan/io/stream_abstraction.rb, line 79 def sysread(length) lsock.sysread(length) end
syswrite(buffer)
click to toggle source
Low-level write to the local side.
# File lib/ssl_scan/io/stream_abstraction.rb, line 72 def syswrite(buffer) lsock.syswrite(buffer) end
Protected Instance Methods
monitor_rsock()
click to toggle source
# File lib/ssl_scan/io/stream_abstraction.rb, line 122 def monitor_rsock self.monitor_thread = Rex::ThreadFactory.spawn("StreamMonitorRemote", false) { loop do closed = false buf = nil if not self.rsock wlog("monitor_rsock: the remote socket is nil, exiting loop") break end begin s = Rex::ThreadSafe.select( [ self.rsock ], nil, nil, 0.2 ) if( s == nil || s[0] == nil ) next end rescue Exception => e wlog("monitor_rsock: exception during select: #{e.class} #{e}") closed = true end if( closed == false ) begin buf = self.rsock.sysread( 32768 ) if buf == nil closed = true wlog("monitor_rsock: closed remote socket due to nil read") end rescue EOFError => e closed = true dlog("monitor_rsock: EOF in rsock") rescue ::Exception => e closed = true wlog("monitor_rsock: exception during read: #{e.class} #{e}") end end if( closed == false ) total_sent = 0 total_length = buf.length while( total_sent < total_length ) begin data = buf[total_sent, buf.length] # Note that this must be write() NOT syswrite() or put() or anything like it. # Using syswrite() breaks SSL streams. sent = self.write( data ) # sf: Only remove the data off the queue is write was successfull. # This way we naturally perform a resend if a failure occured. # Catches an edge case with meterpreter TCP channels where remote send # failes gracefully and a resend is required. if (sent.nil?) closed = true wlog("monitor_rsock: failed writing, socket must be dead") break elsif (sent > 0) total_sent += sent end rescue ::IOError, ::EOFError => e closed = true wlog("monitor_rsock: exception during write: #{e.class} #{e}") break end end end if( closed ) begin self.close_write if self.respond_to?('close_write') rescue IOError end break end end } end