Files
metasploit-gs/lib/rex/socket/parameters.rb
T
David Maloney ebb0f166ca Accept propper formats for SSL version
we were only accepting sloppy string values and not accepting input of
the actual symbols that OpenSSL expects in the first place. Allow the
user to enter it right themselves to be compat with OpenSSL
2013-02-09 00:40:58 -06:00

373 lines
7.2 KiB
Ruby

# -*- coding: binary -*-
require 'rex/socket'
###
#
# This class represents the set of parameters that are used to create
# a socket, whether it be a server or client socket.
#
###
class Rex::Socket::Parameters
##
#
# Factory
#
##
#
# Creates an instance of the Parameters class using the supplied hash.
#
def self.from_hash(hash)
return self.new(hash)
end
##
#
# Constructor
#
##
#
# Initializes the attributes from the supplied hash. The following hash
# keys can be specified.
#
# [PeerHost / PeerAddr]
#
# The remote host to connect to.
#
# [PeerPort]
#
# The remote port to connect to.
#
# [LocalHost / LocalAddr]
#
# The local host to communicate from, if any.
#
# [LocalPort]
#
# The local port to communicate from, if any.
#
# [Bare]
#
# Create a bare socket.
#
# [Server]
#
# Whether or not this should be a server.
#
# [SSL]
#
# Whether or not SSL should be used.
#
# [SSLVersion]
#
# Specify SSL2, SSL3, or TLS1 (SSL3 is default)
#
# [SSLCert]
#
# A file containing an SSL certificate (for server sockets)
#
# [Proxies]
#
# List of proxies to use.
#
# [Proto]
#
# The underlying protocol to use.
#
# [IPv6]
#
# Force the use of IPv6.
#
# [Comm]
#
# The underlying Comm class to use to create the socket for this parameter
# set.
#
# [Context]
#
# A context hash that can allow users of this parameter class instance to
# determine who is responsible for requesting that a socket be created.
#
# [Retries]
#
# The number of times a connection should be retried.
#
# [Timeout]
#
# The number of seconds before a connection should time out
#
def initialize(hash)
if (hash['PeerHost'])
self.peerhost = hash['PeerHost']
elsif (hash['PeerAddr'])
self.peerhost = hash['PeerAddr']
else
self.peerhost = nil
end
if (hash['LocalHost'])
self.localhost = hash['LocalHost']
elsif (hash['LocalAddr'])
self.localhost = hash['LocalAddr']
else
self.localhost = '0.0.0.0'
end
if (hash['PeerPort'])
self.peerport = hash['PeerPort'].to_i
else
self.peerport = 0
end
if (hash['LocalPort'])
self.localport = hash['LocalPort'].to_i
else
self.localport = 0
end
if (hash['Bare'])
self.bare = hash['Bare']
else
self.bare = false
end
if (hash['SSL'] and hash['SSL'].to_s =~ /^(t|y|1)/i)
self.ssl = true
else
self.ssl = false
end
supported_ssl_versions = ['SSL2', 'SSL23', 'TLS1', 'SSL3', :SSLv2, :SSLv3, :SSLv23, :TLSv1]
if (hash['SSLVersion'] and supported_ssl_versions.include? hash['SSLVersion'])
self.ssl_version = hash['SSLVersion']
end
if (hash['SSLCipher'])
self.ssl_cipher = hash['SSLCipher']
end
if (hash['SSLCert'] and ::File.file?(hash['SSLCert']))
begin
self.ssl_cert = ::File.read(hash['SSLCert'])
rescue ::Exception => e
elog("Failed to read cert: #{e.class}: #{e}", LogSource)
end
end
if hash['Proxies']
self.proxies = hash['Proxies'].split('-').map{|a| a.strip}.map{|a| a.split(':').map{|b| b.strip}}
end
# The protocol this socket will be using
if (hash['Proto'])
self.proto = hash['Proto'].downcase
else
self.proto = 'tcp'
end
# Whether or not the socket should be a server
self.server = hash['Server'] || false
# The communication subsystem to use to create the socket
self.comm = hash['Comm']
# The context that was passed in, if any.
self.context = hash['Context'] || {}
# If no comm was supplied, try to use the comm that is best fit to
# handle the provided host based on the current routing table.
if( self.server )
if (self.comm == nil and self.localhost)
self.comm = Rex::Socket::SwitchBoard.best_comm(self.localhost)
end
else
if (self.comm == nil and self.peerhost)
self.comm = Rex::Socket::SwitchBoard.best_comm(self.peerhost)
end
end
# If we still haven't found a comm, we default to the local comm.
self.comm = Rex::Socket::Comm::Local if (self.comm == nil)
# If we are a UDP server, turn off the server flag as it was only set when
# creating the UDP socket in order to avail of the switch board above.
if( self.server and self.proto == 'udp' )
self.server = false
end
# The number of connection retries to make (client only)
if hash['Retries']
self.retries = hash['Retries'].to_i
else
self.retries = 0
end
# The number of seconds before a connect attempt times out (client only)
if hash['Timeout']
self.timeout = hash['Timeout'].to_i
else
self.timeout = 5
end
# Whether to force IPv6 addressing
self.v6 = hash['IPv6'] || false
end
##
#
# Conditionals
#
##
#
# Returns true if this represents parameters for a server.
#
def server?
return (server == true)
end
#
# Returns true if this represents parameters for a client.
#
def client?
return (server == false)
end
#
# Returns true if the protocol for the parameters is TCP.
#
def tcp?
return (proto == 'tcp')
end
#
# Returns true if the protocol for the parameters is UDP.
#
def udp?
return (proto == 'udp')
end
#
# Returns true if the protocol for the parameters is IP.
#
def ip?
return (proto == 'ip')
end
#
# Returns true if the socket is a bare socket that does not inherit from
# any extended Rex classes.
#
def bare?
return (bare == true)
end
#
# Returns true if SSL has been requested.
#
def ssl?
return ssl
end
#
# Returns true if IPv6 has been enabled
#
def v6?
return v6
end
##
#
# Attributes
#
##
#
# The remote host information, equivalent to the PeerHost parameter hash
# key.
#
attr_accessor :peerhost
#
# The remote port. Equivalent to the PeerPort parameter hash key.
#
attr_accessor :peerport
#
# The local host. Equivalent to the LocalHost parameter hash key.
#
attr_accessor :localhost
#
# The local port. Equivalent to the LocalPort parameter hash key.
#
attr_accessor :localport
#
# The protocol to to use, such as TCP. Equivalent to the Proto parameter
# hash key.
#
attr_accessor :proto
#
# Whether or not this is a server. Equivalent to the Server parameter hash
# key.
#
attr_accessor :server
#
# The Comm class that should be used to create the underlying socket.
#
attr_accessor :comm
#
# The context hash that was passed in to the structure.
#
attr_accessor :context
#
# The number of attempts that should be made.
#
attr_accessor :retries
#
# The number of seconds before a connection attempt should time out.
#
attr_accessor :timeout
#
# Whether or not this is a bare (non-extended) socket instance that should
# be created.
#
attr_accessor :bare
#
# Whether or not SSL should be used to wrap the connection.
#
attr_accessor :ssl
#
# What version of SSL to use (SSL2, SSL3, TLS1)
#
attr_accessor :ssl_version
#
# What specific SSL Cipher(s) to use, may be a string containing the cipher name
# or an array of strings containing cipher names e.g. ["DHE-RSA-AES256-SHA", "DHE-DSS-AES256-SHA"]
#
attr_accessor :ssl_cipher
#
# The SSL certificate, in pem format, stored as a string. See +SslTcpServer#make_ssl+
#
attr_accessor :ssl_cert
#
# Whether we should use IPv6
#
attr_accessor :v6
attr_accessor :proxies
##
#
# Synonyms
#
##
alias peeraddr peerhost
alias localaddr localhost
end