2005-07-09 21:18:49 +00:00
|
|
|
require 'rex/socket'
|
|
|
|
require 'rex/io/stream'
|
2005-06-02 07:52:17 +00:00
|
|
|
|
2005-06-03 07:32:17 +00:00
|
|
|
###
|
|
|
|
#
|
|
|
|
# Tcp
|
|
|
|
# ---
|
|
|
|
#
|
|
|
|
# This class provides methods for interacting with a TCP client connection.
|
|
|
|
#
|
|
|
|
###
|
2005-06-02 07:52:17 +00:00
|
|
|
class Rex::Socket::Tcp < Rex::Socket
|
2005-07-15 23:46:05 +00:00
|
|
|
|
|
|
|
SHUT_RDWR = 2
|
|
|
|
SHUT_WR = 1
|
|
|
|
SHUT_RD = 0
|
|
|
|
|
2005-06-02 07:52:17 +00:00
|
|
|
include Rex::IO::Stream
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
2005-06-03 07:13:15 +00:00
|
|
|
# Factory
|
2005-06-02 07:52:17 +00:00
|
|
|
#
|
|
|
|
##
|
2005-06-03 07:13:15 +00:00
|
|
|
|
2005-07-17 07:43:24 +00:00
|
|
|
#
|
|
|
|
# Creates the client using the supplied hash
|
|
|
|
#
|
|
|
|
def self.create(hash)
|
|
|
|
self.create_param(Rex::Socket::Parameters.from_hash(hash))
|
|
|
|
end
|
|
|
|
|
2005-06-03 07:13:15 +00:00
|
|
|
#
|
|
|
|
# Wrapper around the base socket class' creation method that automatically
|
|
|
|
# sets the parameter's protocol to TCP
|
|
|
|
#
|
|
|
|
def self.create_param(param)
|
|
|
|
param.proto = 'tcp'
|
|
|
|
|
2005-06-03 07:37:15 +00:00
|
|
|
super(param)
|
2005-06-02 07:52:17 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Stream mixin implementations
|
|
|
|
#
|
|
|
|
##
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Writes to the TCP connection.
|
|
|
|
#
|
2005-06-02 07:52:17 +00:00
|
|
|
def write(buf, opts = {})
|
|
|
|
return sock.syswrite(buf)
|
|
|
|
end
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
#
|
2005-07-16 08:12:58 +00:00
|
|
|
# Reads from the TCP connection and raises EOFError if there is no data
|
|
|
|
# left.
|
2005-07-16 07:32:11 +00:00
|
|
|
#
|
2005-06-02 07:52:17 +00:00
|
|
|
def read(length = nil, opts = {})
|
|
|
|
length = 16384 unless length
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
return sock.sysread(length)
|
2005-06-02 07:52:17 +00:00
|
|
|
end
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Calls shutdown on the TCP connection.
|
|
|
|
#
|
2005-06-03 05:21:49 +00:00
|
|
|
def shutdown(how = SHUT_RDWR)
|
2005-07-18 23:32:34 +00:00
|
|
|
begin
|
|
|
|
return (sock.shutdown(how) == 0)
|
|
|
|
rescue Errno::ENOTCONN
|
|
|
|
end
|
2005-06-02 07:52:17 +00:00
|
|
|
end
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Checks to see if the connection has read data.
|
|
|
|
#
|
|
|
|
def has_read_data?(timeout = nil)
|
2005-06-03 07:13:15 +00:00
|
|
|
timeout = timeout.to_i if (timeout)
|
2005-07-16 07:32:11 +00:00
|
|
|
|
2005-07-17 00:52:47 +00:00
|
|
|
return (Rex::ThreadSafe.select([ poll_fd ], nil, nil, timeout) != nil)
|
2005-06-02 07:52:17 +00:00
|
|
|
end
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Closes the connection.
|
|
|
|
#
|
2005-07-16 07:32:11 +00:00
|
|
|
def close
|
|
|
|
self.sock.close if (self.sock)
|
|
|
|
end
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Returns the file descriptor to use with calls to select.
|
|
|
|
#
|
2005-07-16 07:32:11 +00:00
|
|
|
def poll_fd
|
|
|
|
return self.sock
|
|
|
|
end
|
|
|
|
|
2005-07-16 08:12:58 +00:00
|
|
|
#
|
|
|
|
# Returns peer information (host + port) in host:port format.
|
|
|
|
#
|
|
|
|
def peerinfo
|
|
|
|
if (pi = getpeername)
|
|
|
|
return pi[1] + ':' + pi[2].to_s
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Returns local information (host + port) in host:port format.
|
|
|
|
#
|
|
|
|
def localinfo
|
|
|
|
if (pi = getlocalname)
|
|
|
|
return pi[1] + ':' + pi[2].to_s
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2005-06-02 07:52:17 +00:00
|
|
|
end
|