Commit 4eb5a81a by Yann Leboulanger

Merge branch 'socks5_v6' into 'master'

Correct handling of Socks5 server replies (gajim/#8914)

See merge request !15
parents cc2e4a26 6d7aecc7
Pipeline #1066 passed with stages
in 14 seconds
......@@ -470,7 +470,10 @@ class NonBlockingClient(object):
Raise event to connection instance. DATA_SENT and DATA_RECIVED events
are used in XML console to show XMPP traffic
"""
log.info('raising event from transport: :::::%s::::\n_____________\n%s\n_____________\n' % (event_type, data))
e_t = event_type
if type(event_type) != str:
e_t = event_type.encode('utf-8')
log.info('raising event from transport: :::::%s::::\n_____________\n%s\n_____________\n' % (e_t, data))
if hasattr(self, 'Dispatcher'):
self.Dispatcher.Event('', event_type, data)
......
......@@ -135,25 +135,30 @@ class SOCKS5Connector(ProxyConnector):
self.onreceive(self._on_greeting_sent)
self.send(to_send)
def _to_int(self, c):
if type(c) == str: # py2
return ord(c)
return c # py3
def _on_greeting_sent(self, reply):
if reply is None:
return
if len(reply) != 2:
self.on_failure('Invalid proxy reply')
return
if reply[0] != '\x05':
if self._to_int(reply[0]) != 5:
log.info('Invalid proxy reply')
self.on_failure('Invalid proxy reply')
return
if reply[1] == '\x00':
if self._to_int(reply[1]) == 0:
return self._on_proxy_auth('\x01\x00')
elif reply[1] == '\x02':
elif self._to_int(reply[1]) == 2:
to_send = '\x01' + chr(len(self.proxy_user)) + self.proxy_user +\
chr(len(self.proxy_pass)) + self.proxy_pass
self.onreceive(self._on_proxy_auth)
self.send(to_send)
else:
if reply[1] == '\xff':
if self._to_int(reply[1]) == 255:
log.error('Authentification to proxy impossible: no acceptable '
'auth method')
self.on_failure('Authentification to proxy impossible: no '
......@@ -208,13 +213,13 @@ class SOCKS5Connector(ProxyConnector):
log.error('Invalid proxy reply')
self.on_failure('Invalid proxy reply')
return
if reply[0] != '\x05':
if self._to_int(reply[0]) != 5:
log.error('Invalid proxy reply')
self.on_failure('Invalid proxy reply')
return
if reply[1] != '\x00':
if self._to_int(reply[1]) != 0:
# Connection failed
if ord(reply[1])<9:
if self._to_int(reply[1]) < 9:
errors = ['general SOCKS server failure',
'connection not allowed by ruleset',
'Network unreachable',
......@@ -224,18 +229,19 @@ class SOCKS5Connector(ProxyConnector):
'Command not supported',
'Address type not supported'
]
txt = errors[ord(reply[1])-1]
txt = errors[self._to_int(reply[1])-1]
else:
txt = 'Invalid proxy reply'
log.error(txt)
self.on_failure(txt)
return
# Get the bound address/port
elif reply[3] == '\x01':
elif self._to_int(reply[3]) == 1:
begin, end = 3, 7
elif reply[3] == '\x03':
# Socks5 is bound to domain name
pass
elif self._to_int(reply[3]) == 3:
begin, end = 4, 4 + self._to_int(reply[4])
elif self._to_int(reply[3]) == 4:
begin, end = 3, 19
else:
log.error('Invalid proxy reply')
self.on_failure('Invalid proxy reply')
......
......@@ -651,25 +651,21 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
received = self.received_bytes_buff + received
self.received_bytes_buff = b''
# try to decode data
try:
received = decode_py2(received, 'utf-8')
except UnicodeDecodeError:
if received.startswith(str('\x05\x00\x00\x03')):
# Received Socks5 reply with bind domain name
# Changing last 2 bytes (port) to \x00 to decode it correctly,
# since Socks5 bind address and port are not used elsewhere
received = received[:-2] + str('\x00\x00')
for i in range(-1, -4, -1):
char = received[i]
if sys.version_info[0] < 3: # with py2 we get a str
char = ord(char)
if char & 0xc0 == 0xc0:
self.received_bytes_buff = received[i:]
received = received[:i]
break
received = decode_py2(received, 'utf-8')
if self.state != PROXY_CONNECTING or self.proxy_dict['type'] != \
'socks5':
# try to decode data
try:
received = decode_py2(received, 'utf-8')
except UnicodeDecodeError:
for i in range(-1, -4, -1):
char = received[i]
if sys.version_info[0] < 3: # with py2 we get a str
char = ord(char)
if char & 0xc0 == 0xc0:
self.received_bytes_buff = received[i:]
received = received[:i]
break
received = decode_py2(received, 'utf-8')
# pass received data to owner
if self.on_receive:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment