fix FT proxy testing. We needed a receiver to connect to proxy to really test it
This commit is contained in:
parent
95b6855aa3
commit
9618bb77a4
|
@ -834,7 +834,10 @@ class ConnectionDisco:
|
||||||
track, self.name)
|
track, self.name)
|
||||||
break
|
break
|
||||||
if features.__contains__(common.xmpp.NS_BYTESTREAM):
|
if features.__contains__(common.xmpp.NS_BYTESTREAM):
|
||||||
gajim.proxy65_manager.resolve(jid, self.connection, self.name)
|
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name) +\
|
||||||
|
'/' + self.server_resource)
|
||||||
|
gajim.proxy65_manager.resolve(jid, self.connection, our_jid,
|
||||||
|
self.name)
|
||||||
if features.__contains__(common.xmpp.NS_MUC) and is_muc:
|
if features.__contains__(common.xmpp.NS_MUC) and is_muc:
|
||||||
type_ = transport_type or 'jabber'
|
type_ = transport_type or 'jabber'
|
||||||
self.muc_jid[type_] = jid
|
self.muc_jid[type_] = jid
|
||||||
|
@ -2242,10 +2245,12 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
def discover_ft_proxies(self):
|
def discover_ft_proxies(self):
|
||||||
cfg_proxies = gajim.config.get_per('accounts', self.name,
|
cfg_proxies = gajim.config.get_per('accounts', self.name,
|
||||||
'file_transfer_proxies')
|
'file_transfer_proxies')
|
||||||
|
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name) + '/' +\
|
||||||
|
self.server_resource)
|
||||||
if cfg_proxies:
|
if cfg_proxies:
|
||||||
proxies = map(lambda e:e.strip(), cfg_proxies.split(','))
|
proxies = map(lambda e:e.strip(), cfg_proxies.split(','))
|
||||||
for proxy in proxies:
|
for proxy in proxies:
|
||||||
gajim.proxy65_manager.resolve(proxy, self.connection)
|
gajim.proxy65_manager.resolve(proxy, self.connection, our_jid)
|
||||||
|
|
||||||
def _on_roster_set(self, roster):
|
def _on_roster_set(self, roster):
|
||||||
raw_roster = roster.getRaw()
|
raw_roster = roster.getRaw()
|
||||||
|
|
|
@ -50,13 +50,13 @@ class Proxy65Manager:
|
||||||
# dict {account: proxy} default proxy for account
|
# dict {account: proxy} default proxy for account
|
||||||
self.default_proxies = {}
|
self.default_proxies = {}
|
||||||
|
|
||||||
def resolve(self, proxy, connection, default = None):
|
def resolve(self, proxy, connection, sender_jid, default=None):
|
||||||
''' start '''
|
''' start '''
|
||||||
if self.proxies.has_key(proxy):
|
if self.proxies.has_key(proxy):
|
||||||
resolver = self.proxies[proxy]
|
resolver = self.proxies[proxy]
|
||||||
else:
|
else:
|
||||||
# proxy is being ressolved for the first time
|
# proxy is being ressolved for the first time
|
||||||
resolver = ProxyResolver(proxy)
|
resolver = ProxyResolver(proxy, sender_jid)
|
||||||
self.proxies[proxy] = resolver
|
self.proxies[proxy] = resolver
|
||||||
resolver.add_connection(connection)
|
resolver.add_connection(connection)
|
||||||
if default:
|
if default:
|
||||||
|
@ -101,12 +101,19 @@ class Proxy65Manager:
|
||||||
class ProxyResolver:
|
class ProxyResolver:
|
||||||
def resolve_result(self, host, port, jid):
|
def resolve_result(self, host, port, jid):
|
||||||
''' test if host has a real proxy65 listening on port '''
|
''' test if host has a real proxy65 listening on port '''
|
||||||
self.host = unicode(host)
|
self.host = str(host)
|
||||||
self.port = int(port)
|
self.port = int(port)
|
||||||
self.jid = unicode(jid)
|
self.jid = unicode(jid)
|
||||||
self.state = S_RESOLVED
|
self.state = S_RESOLVED
|
||||||
|
self.receiver_tester = ReceiverTester(self.host, self.port, self.jid,
|
||||||
|
self.sid, self.sender_jid, self._on_receiver_success,
|
||||||
|
self._on_connect_failure)
|
||||||
|
self.receiver_tester.connect()
|
||||||
|
|
||||||
|
def _on_receiver_success(self):
|
||||||
self.host_tester = HostTester(self.host, self.port, self.jid,
|
self.host_tester = HostTester(self.host, self.port, self.jid,
|
||||||
self._on_connect_success, self._on_connect_failure)
|
self.sid, self.sender_jid, self._on_connect_success,
|
||||||
|
self._on_connect_failure)
|
||||||
self.host_tester.connect()
|
self.host_tester.connect()
|
||||||
|
|
||||||
def _on_connect_success(self):
|
def _on_connect_success(self):
|
||||||
|
@ -116,15 +123,16 @@ class ProxyResolver:
|
||||||
query.setAttr('sid', self.sid)
|
query.setAttr('sid', self.sid)
|
||||||
|
|
||||||
activate = query.setTag('activate')
|
activate = query.setTag('activate')
|
||||||
activate.setData(self.jid + "/" + self.sid)
|
activate.setData('test@gajim.org/test2')
|
||||||
|
|
||||||
if self.active_connection:
|
if self.active_connection:
|
||||||
self.active_connection.send(iq)
|
self.active_connection.SendAndCallForResponse(iq, self.keep_conf)
|
||||||
self.state = S_ACTIVATED
|
self.state = S_ACTIVATED
|
||||||
else:
|
else:
|
||||||
self.state = S_INITIAL
|
self.state = S_INITIAL
|
||||||
|
|
||||||
def keep_conf(self):
|
def keep_conf(self, data=None):
|
||||||
|
self.disconnect(self.active_connection)
|
||||||
self.state = S_FINISHED
|
self.state = S_FINISHED
|
||||||
|
|
||||||
def _on_connect_failure(self):
|
def _on_connect_failure(self):
|
||||||
|
@ -137,6 +145,9 @@ class ProxyResolver:
|
||||||
if self.host_tester:
|
if self.host_tester:
|
||||||
self.host_tester.disconnect()
|
self.host_tester.disconnect()
|
||||||
self.host_tester = None
|
self.host_tester = None
|
||||||
|
if self.receiver_tester:
|
||||||
|
self.receiver_tester.disconnect()
|
||||||
|
self.receiver_tester = None
|
||||||
try:
|
try:
|
||||||
self.connections.remove(connection)
|
self.connections.remove(connection)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -168,20 +179,22 @@ class ProxyResolver:
|
||||||
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
query.setNamespace(common.xmpp.NS_BYTESTREAM)
|
||||||
connection.send(iq)
|
connection.send(iq)
|
||||||
|
|
||||||
def __init__(self, proxy):
|
def __init__(self, proxy, sender_jid):
|
||||||
self.proxy = proxy
|
self.proxy = proxy
|
||||||
self.state = S_INITIAL
|
self.state = S_INITIAL
|
||||||
self.active_connection = None
|
self.active_connection = None
|
||||||
self.connections = []
|
self.connections = []
|
||||||
self.host_tester = None
|
self.host_tester = None
|
||||||
|
self.receiver_tester = None
|
||||||
self.jid = None
|
self.jid = None
|
||||||
self.host = None
|
self.host = None
|
||||||
self.port = None
|
self.port = None
|
||||||
self.sid = helpers.get_random_string_16()
|
self.sid = helpers.get_random_string_16()
|
||||||
|
self.sender_jid = sender_jid
|
||||||
|
|
||||||
class HostTester(Socks5, IdleObject):
|
class HostTester(Socks5, IdleObject):
|
||||||
''' fake proxy tester. '''
|
''' fake proxy tester. '''
|
||||||
def __init__(self, host, port, jid, on_success, on_failure):
|
def __init__(self, host, port, jid, sid, sender_jid, on_success, on_failure):
|
||||||
''' try to establish and auth to proxy at (host, port)
|
''' try to establish and auth to proxy at (host, port)
|
||||||
call on_success, or on_failure according to the result'''
|
call on_success, or on_failure according to the result'''
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -190,8 +203,11 @@ class HostTester(Socks5, IdleObject):
|
||||||
self.on_success = on_success
|
self.on_success = on_success
|
||||||
self.on_failure = on_failure
|
self.on_failure = on_failure
|
||||||
self._sock = None
|
self._sock = None
|
||||||
self.file_props = {}
|
self.file_props = {'is_a_proxy': True,
|
||||||
|
'proxy_sender': sender_jid,
|
||||||
|
'proxy_receiver': 'test@gajim.org/test2'}
|
||||||
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
||||||
|
self.sid = sid
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
''' create the socket and plug it to the idlequeue '''
|
''' create the socket and plug it to the idlequeue '''
|
||||||
|
@ -246,10 +262,13 @@ class HostTester(Socks5, IdleObject):
|
||||||
version, method = struct.unpack('!BB', buff[:2])
|
version, method = struct.unpack('!BB', buff[:2])
|
||||||
if version != 0x05 or method == 0xff:
|
if version != 0x05 or method == 0xff:
|
||||||
self.pollend()
|
self.pollend()
|
||||||
self.disconnect()
|
return
|
||||||
|
data = self._get_request_buff(self._get_sha1_auth())
|
||||||
|
self.send_raw(data)
|
||||||
|
self.state += 1
|
||||||
|
elif self.state == 3:
|
||||||
self.on_success()
|
self.on_success()
|
||||||
else:
|
self.state += 1
|
||||||
self.disconnect()
|
|
||||||
|
|
||||||
def do_connect(self):
|
def do_connect(self):
|
||||||
try:
|
try:
|
||||||
|
@ -277,5 +296,116 @@ class HostTester(Socks5, IdleObject):
|
||||||
self.idlequeue.plug_idle(self, True, False)
|
self.idlequeue.plug_idle(self, True, False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
class ReceiverTester(Socks5, IdleObject):
|
||||||
|
''' fake proxy tester. '''
|
||||||
|
def __init__(self, host, port, jid, sid, sender_jid, on_success, on_failure):
|
||||||
|
''' try to establish and auth to proxy at (host, port)
|
||||||
|
call on_success, or on_failure according to the result'''
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
self.jid = jid
|
||||||
|
self.on_success = on_success
|
||||||
|
self.on_failure = on_failure
|
||||||
|
self._sock = None
|
||||||
|
self.file_props = {'is_a_proxy': True,
|
||||||
|
'proxy_sender': sender_jid,
|
||||||
|
'proxy_receiver': 'test@gajim.org/test2'}
|
||||||
|
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
||||||
|
self.sid = sid
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
''' create the socket and plug it to the idlequeue '''
|
||||||
|
if self.host is None:
|
||||||
|
self.on_failure()
|
||||||
|
return None
|
||||||
|
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self._sock.setblocking(False)
|
||||||
|
self.fd = self._sock.fileno()
|
||||||
|
self.state = 0 # about to be connected
|
||||||
|
gajim.idlequeue.plug_idle(self, True, False)
|
||||||
|
self.do_connect()
|
||||||
|
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def read_timeout(self):
|
||||||
|
self.idlequeue.remove_timeout(self.fd)
|
||||||
|
self.pollend()
|
||||||
|
|
||||||
|
def pollend(self):
|
||||||
|
self.disconnect()
|
||||||
|
self.on_failure()
|
||||||
|
|
||||||
|
def pollout(self):
|
||||||
|
self.idlequeue.remove_timeout(self.fd)
|
||||||
|
if self.state == 0:
|
||||||
|
self.do_connect()
|
||||||
|
return
|
||||||
|
elif self.state == 1: # send initially: version and auth types
|
||||||
|
data = self._get_auth_buff()
|
||||||
|
self.send_raw(data)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
self.state += 1
|
||||||
|
# unplug and plug for reading
|
||||||
|
gajim.idlequeue.plug_idle(self, False, True)
|
||||||
|
gajim.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
|
||||||
|
|
||||||
|
def pollin(self):
|
||||||
|
self.idlequeue.remove_timeout(self.fd)
|
||||||
|
if self.state in (2, 3):
|
||||||
|
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
|
||||||
|
# begin negotiation. on success 'address' != 0
|
||||||
|
buff = self.receive()
|
||||||
|
if buff == '':
|
||||||
|
# end connection
|
||||||
|
self.pollend()
|
||||||
|
return
|
||||||
|
if self.state == 2:
|
||||||
|
# read auth response
|
||||||
|
if buff is None or len(buff) != 2:
|
||||||
|
return None
|
||||||
|
version, method = struct.unpack('!BB', buff[:2])
|
||||||
|
if version != 0x05 or method == 0xff:
|
||||||
|
self.pollend()
|
||||||
|
return
|
||||||
|
data = self._get_request_buff(self._get_sha1_auth())
|
||||||
|
self.send_raw(data)
|
||||||
|
self.state += 1
|
||||||
|
elif self.state == 3:
|
||||||
|
# read connect response
|
||||||
|
if buff is None or len(buff) < 2:
|
||||||
|
return None
|
||||||
|
version, reply = struct.unpack('!BB', buff[:2])
|
||||||
|
if version != 0x05 or reply != 0x00:
|
||||||
|
self.pollend()
|
||||||
|
return
|
||||||
|
self.on_success()
|
||||||
|
self.state += 1
|
||||||
|
|
||||||
|
def do_connect(self):
|
||||||
|
try:
|
||||||
|
self._sock.connect((self.host, self.port))
|
||||||
|
self._sock.setblocking(False)
|
||||||
|
self._send = self._sock.send
|
||||||
|
self._recv = self._sock.recv
|
||||||
|
except Exception, ee:
|
||||||
|
(errnum, errstr) = ee
|
||||||
|
# 56 is for freebsd
|
||||||
|
if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK):
|
||||||
|
# still trying to connect
|
||||||
|
return
|
||||||
|
# win32 needs this
|
||||||
|
if errnum not in (0, 10056, errno.EISCONN):
|
||||||
|
# connection failed
|
||||||
|
self.on_failure()
|
||||||
|
return
|
||||||
|
# socket is already connected
|
||||||
|
self._sock.setblocking(False)
|
||||||
|
self._send = self._sock.send
|
||||||
|
self._recv = self._sock.recv
|
||||||
|
self.buff = ''
|
||||||
|
self.state = 1 # connected
|
||||||
|
self.idlequeue.plug_idle(self, True, False)
|
||||||
|
return
|
||||||
|
|
||||||
# vim: se ts=3:
|
# vim: se ts=3:
|
||||||
|
|
Loading…
Reference in New Issue