Socket driver: Add support for Socks proxies.

This commit is contained in:
Valentin Lorentz 2012-10-07 13:13:08 +02:00
parent 364a3e50e8
commit 156b3d93e1
3 changed files with 32 additions and 2 deletions

View File

@ -254,6 +254,18 @@ class Servers(registry.SpaceSeparatedListOfStrings):
L = registry.SpaceSeparatedListOfStrings.__call__(self) L = registry.SpaceSeparatedListOfStrings.__call__(self)
L.append(s) L.append(s)
class SocksProxy(registry.String):
"""Value must be a valid hostname:port string."""
def setValue(self, v):
# TODO: improve checks
if ':' not in v:
self.error()
try:
int(v.rsplit(':'))
except ValueError:
self.error()
super(SocksProxy, self).setValue(v)
class SpaceSeparatedSetOfChannels(registry.SpaceSeparatedListOf): class SpaceSeparatedSetOfChannels(registry.SpaceSeparatedListOf):
sorted = True sorted = True
List = ircutils.IrcSet List = ircutils.IrcSet
@ -301,6 +313,9 @@ def registerNetwork(name, password='', ssl=False, sasl_username='',
registerGlobalValue(sasl, 'password', registry.String(sasl_password, registerGlobalValue(sasl, 'password', registry.String(sasl_password,
_("""Determines what SASL password will be used on %s.""") \ _("""Determines what SASL password will be used on %s.""") \
% name, private=True)) % name, private=True))
registerGlobalValue(network, 'socksproxy', registry.String('',
_("""If not empty, determines the hostname of the socks proxy that
will be used to connect to this network.""")))
return network return network
# Let's fill our networks. # Let's fill our networks.

View File

@ -183,7 +183,16 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
server = self._getNextServer() server = self._getNextServer()
drivers.log.connect(self.currentServer) drivers.log.connect(self.currentServer)
try: try:
self.conn = utils.net.getSocket(server[0]) socks_proxy = getattr(conf.supybot.networks, self.irc.network) \
.socksproxy()
try:
if socks_proxy:
import socks
except ImportError:
log.error('Cannot use socks proxy (SocksiPy not installed), '
'using direct connection instead.')
socks_proxy = ''
self.conn = utils.net.getSocket(server[0], socks_proxy)
vhost = conf.supybot.protocols.irc.vhost() vhost = conf.supybot.protocols.irc.vhost()
self.conn.bind((vhost, 0)) self.conn.bind((vhost, 0))
except socket.error, e: except socket.error, e:

View File

@ -80,12 +80,18 @@ class EmailRe:
return count >= 1 return count >= 1
emailRe = EmailRe() emailRe = EmailRe()
def getSocket(host): def getSocket(host, socks_proxy=None):
"""Returns a socket of the correct AF_INET type (v4 or v6) in order to """Returns a socket of the correct AF_INET type (v4 or v6) in order to
communicate with host. communicate with host.
""" """
addrinfo = socket.getaddrinfo(host, None) addrinfo = socket.getaddrinfo(host, None)
host = addrinfo[0][4][0] host = addrinfo[0][4][0]
if socks_proxy:
import socks
s = socks.socksocket()
hostname, port = socks_proxy.rsplit(':', 1)
s.setproxy(socks.PROXY_TYPE_SOCKS5, hostname, int(port))
return s
if isIPV4(host): if isIPV4(host):
return socket.socket(socket.AF_INET, socket.SOCK_STREAM) return socket.socket(socket.AF_INET, socket.SOCK_STREAM)
elif isIPV6(host): elif isIPV6(host):