Skip to content
Snippets Groups Projects
Commit ae97a3ed authored by Zhenchao Li's avatar Zhenchao Li
Browse files

wrap IO operations on SSL.Connection objects in try, catch SSL exceptions...

wrap IO operations on SSL.Connection objects in try, catch SSL exceptions caused by SSL rehandshake request and simply ignore, retrying the IO should succeed.
parent 2b603fd7
No related branches found
No related tags found
No related merge requests found
......@@ -39,13 +39,16 @@ def get_context(fingerprint, verify_cb=None):
constructs and returns the context objects
"""
ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb or default_callback)
# TODO: set private key, set certificate, set verification path
if fingerprint == 'server': # for testing purposes only
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb or default_callback)
ctx.use_privatekey_file (os.path.expanduser('~/certs/server.pkey'))
ctx.use_certificate_file(os.path.expanduser('~/certs/server.cert'))
ctx.load_verify_locations(os.path.expanduser('~/certs/CA.cert'))
elif fingerprint == 'client':
elif fingerprint == 'client':
ctx.set_verify(SSL.VERIFY_PEER, verify_cb or default_callback)
ctx.use_privatekey_file (os.path.expanduser('~/certs/client.pkey'))
ctx.use_certificate_file(os.path.expanduser('~/certs/client.cert'))
ctx.load_verify_locations(os.path.expanduser('~/certs/CA.cert'))
......
......@@ -317,7 +317,7 @@ class SocksQueue:
sock_hash = sock.__hash__()
if sock_hash not in self.senders:
self.senders[sock_hash] = Socks5Sender(self.idlequeue, sock_hash, self,
sock[0], sock[1][0], sock[1][1])
sock[0], sock[1][0], sock[1][1], fingerprint='server')
self.connected += 1
def process_result(self, result, actor):
......@@ -453,6 +453,10 @@ class Socks5:
received = ''
try:
add = self._recv(64)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('SSL rehandshake request : ' + repr(e))
raise e
except Exception:
add = ''
received += add
......@@ -466,7 +470,11 @@ class Socks5:
"""
try:
self._send(raw_data)
except Exception:
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('SSL rehandshake request :' + repr(e))
raise e
except Exception, e:
self.disconnect()
return len(raw_data)
......@@ -487,6 +495,10 @@ class Socks5:
lenn = 0
try:
lenn = self._send(buff)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('SSL rehandshake request :' + repr(e))
raise e
except Exception, e:
if e.args[0] not in (EINTR, ENOBUFS, EWOULDBLOCK):
# peer stopped reading
......@@ -557,6 +569,10 @@ class Socks5:
return 0
try:
buff = self._recv(MAX_BUFF_LEN)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('SSL rehandshake request :' + repr(e))
raise e
except Exception:
buff = ''
current_time = self.idlequeue.current_time()
......@@ -682,7 +698,12 @@ class Socks5:
"""
Connect response: version, auth method
"""
buff = self._recv()
try:
buff = self._recv()
except (SSL.WantReadError, SSL.WantWriteError,
SSL.WantX509LookupError), e:
log.info("SSL rehandshake request : " + repr(e))
raise e
try:
version, method = struct.unpack('!BB', buff)
except Exception:
......@@ -716,11 +737,15 @@ class Socks5Sender(Socks5, IdleObject):
"""
def __init__(self, idlequeue, sock_hash, parent, _sock, host=None,
port=None):
port=None, fingerprint = None):
self.fingerprint = fingerprint
self.queue_idx = sock_hash
self.queue = parent
Socks5.__init__(self, idlequeue, host, port, None, None, None)
self._sock = _sock
if not self.fingerprint is None:
self._sock = OpenSSL.SSL.Connection(
jingle_xtls.get_context('server'), self._sock)
self._sock.setblocking(False)
self.fd = _sock.fileno()
self._recv = _sock.recv
......@@ -782,17 +807,21 @@ class Socks5Sender(Socks5, IdleObject):
def pollin(self):
if self.connected:
if self.state < 5:
result = self.main()
if self.state == 4:
self.queue.result_sha(self.sha_msg, self.queue_idx)
if result == -1:
self.disconnect()
elif self.state == 5:
if self.file_props is not None and self.file_props['type'] == 'r':
result = self.get_file_contents(0)
self.queue.process_result(result, self)
try:
if self.state < 5:
result = self.main()
if self.state == 4:
self.queue.result_sha(self.sha_msg, self.queue_idx)
if result == -1:
self.disconnect()
elif self.state == 5:
if self.file_props is not None and self.file_props['type'] == 'r':
result = self.get_file_contents(0)
self.queue.process_result(result, self)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('caught SSL exception, ignored')
else:
self.disconnect()
......@@ -1028,19 +1057,24 @@ class Socks5Receiver(Socks5, IdleObject):
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
self.send_raw(self._get_auth_buff())
elif self.state == 3: # send 'connect' request
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
elif self.file_props['type'] != 'r':
if self.file_props['paused']:
self.idlequeue.plug_idle(self, False, False)
try:
if self.state == 0:
self.do_connect()
return
result = self.write_next()
self.queue.process_result(result, self)
elif self.state == 1: # send initially: version and auth types
self.send_raw(self._get_auth_buff())
elif self.state == 3: # send 'connect' request
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
elif self.file_props['type'] != 'r':
if self.file_props['paused']:
self.idlequeue.plug_idle(self, False, False)
return
result = self.write_next()
self.queue.process_result(result, self)
return
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('caught SSL exception, ignored')
return
self.state += 1
# unplug and plug for reading
......@@ -1059,19 +1093,24 @@ class Socks5Receiver(Socks5, IdleObject):
def pollin(self):
self.idlequeue.remove_timeout(self.fd)
if self.connected:
if self.file_props['paused']:
self.idlequeue.plug_idle(self, False, False)
try:
if self.file_props['paused']:
self.idlequeue.plug_idle(self, False, False)
return
if self.state < 5:
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
result = self.main(0)
self.queue.process_result(result, self)
elif self.state == 5: # wait for proxy reply
pass
elif self.file_props['type'] == 'r':
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
result = self.get_file_contents(0)
self.queue.process_result(result, self)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError,
OpenSSL.SSL.WantX509LookupError), e:
log.info('caught SSL exception, ignored')
return
if self.state < 5:
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
result = self.main(0)
self.queue.process_result(result, self)
elif self.state == 5: # wait for proxy reply
pass
elif self.file_props['type'] == 'r':
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
result = self.get_file_contents(0)
self.queue.process_result(result, self)
else:
self.disconnect()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment