def writeSomeData(self, data):
try:
return Connection.writeSomeData(self, data)
except SSL.WantWriteError:
return 0
except SSL.WantReadError:
self.writeBlockedOnRead = 1
Connection.stopWriting(self)
Connection.startReading(self)
return 0
except SSL.ZeroReturnError:
return main.CONNECTION_LOST
except SSL.SysCallError, e:
if e[0] == -1 and data == "":
# errors when writing empty strings are expected
# and can be ignored
return 0
else:
return main.CONNECTION_LOST
except SSL.Error, e:
return e
python类WantReadError()的实例源码
def socketRecv(self, packetSize):
data = self.socket.recv(packetSize)
if self.tlsSocket is not None:
dd = ''
self.tlsSocket.bio_write(data)
while True:
try:
dd += self.tlsSocket.read(packetSize)
except SSL.WantReadError:
data2 = self.socket.recv(packetSize - len(data) )
self.tlsSocket.bio_write(data2)
pass
else:
data = dd
break
return data
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def send(self, data, flags=0, timeout=timeout_default):
if timeout is timeout_default:
timeout = self.timeout
while True:
try:
return self._sock.send(data, flags)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_write(self.fileno(), timeout=timeout)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=timeout)
except SSL.SysCallError, ex:
if ex[0] == -1 and data == "":
# errors when writing empty strings are expected and can be ignored
return 0
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def recv(self, buflen):
pending = self._sock.pending()
if pending:
return self._sock.recv(min(pending, buflen))
while True:
try:
return self._sock.recv(buflen)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.ZeroReturnError:
return ''
except SSL.SysCallError, ex:
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def send(self, data, flags=0, timeout=timeout_default):
if timeout is timeout_default:
timeout = self.timeout
while True:
try:
return self._sock.send(data, flags)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_write(self.fileno(), timeout=timeout)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=timeout)
except SSL.SysCallError, ex:
if ex[0] == -1 and data == "":
# errors when writing empty strings are expected and can be ignored
return 0
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def recv(self, buflen):
pending = self._sock.pending()
if pending:
return self._sock.recv(min(pending, buflen))
while True:
try:
return self._sock.recv(buflen)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.ZeroReturnError:
return ''
except SSL.SysCallError, ex:
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def send_all(self, data):
print(" --> transport_stream.send_all")
async with self._send_all_conflict_detector:
await _core.checkpoint()
await self.sleeper("send_all")
self._conn.bio_write(data)
while True:
await self.sleeper("send_all")
try:
data = self._conn.recv(1)
except SSL.ZeroReturnError:
self._conn.shutdown()
print("renegotiations:", self._conn.total_renegotiations())
break
except SSL.WantReadError:
break
else:
self._pending_cleartext += data
self._lot.unpark_all()
await self.sleeper("send_all")
print(" <-- transport_stream.send_all finished")
def unwrap(self, encrypted_data):
"""
Decrypts the data send by the server using the TLS channel negotiated
between the client and the server.
:param encrypted_data: the byte string of the encrypted data
:return: a byte string of the decrypted data
"""
length = self.tls_connection.bio_write(encrypted_data)
data = b''
counter = 0
while True:
try:
data_chunk = self.tls_connection.recv(self.BIO_BUFFER_SIZE)
except SSL.WantReadError:
break
data += data_chunk
counter += self.BIO_BUFFER_SIZE
if counter > length:
break
return data
def socketRecv(self, packetSize):
data = self.socket.recv(packetSize)
if self.tlsSocket is not None:
dd = ''
self.tlsSocket.bio_write(data)
while True:
try:
dd += self.tlsSocket.read(packetSize)
except SSL.WantReadError:
data2 = self.socket.recv(packetSize - len(data) )
self.tlsSocket.bio_write(data2)
pass
else:
data = dd
break
return data
def writeSomeData(self, data):
try:
return Connection.writeSomeData(self, data)
except SSL.WantWriteError:
return 0
except SSL.WantReadError:
self.writeBlockedOnRead = 1
Connection.stopWriting(self)
Connection.startReading(self)
return 0
except SSL.ZeroReturnError:
return main.CONNECTION_LOST
except SSL.SysCallError, e:
if e[0] == -1 and data == "":
# errors when writing empty strings are expected
# and can be ignored
return 0
else:
return main.CONNECTION_LOST
except SSL.Error, e:
return e
def _fill_recv_buf(self):
self.ssl_write = None
start_len = len(self.recv_buf)
while True:
try:
nbuf = self.sock.recv(16384)
if len(nbuf) == 0:
break
else:
self.recv_buf += nbuf
except SSL.WantReadError:
start_len = -1
break
except SSL.WantWriteError:
self.ssl_write = True
break
except:
break
if len(self.recv_buf) == start_len:
self.close()
def do_handshake(self):
self.update_flags()
if not isinstance(self.sock, SSL.Connection):
return
self.handshaking = True
self.ssl_write = None
try:
self.sock.do_handshake()
except SSL.WantWriteError:
self.ssl_write = True
except SSL.WantReadError:
pass
except SSL.Error:
self.close()
else:
self.handshaking = False
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def send(self, data, flags=0, timeout=timeout_default):
if timeout is timeout_default:
timeout = self.timeout
while True:
try:
return self._sock.send(data, flags)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_write(self.fileno(), timeout=timeout)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=timeout)
except SSL.SysCallError, ex:
if ex[0] == -1 and data == "":
# errors when writing empty strings are expected and can be ignored
return 0
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def recv(self, buflen):
pending = self._sock.pending()
if pending:
return self._sock.recv(min(pending, buflen))
while True:
try:
return self._sock.recv(buflen)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.ZeroReturnError:
return ''
except SSL.SysCallError, ex:
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def socketRecv(self, packetSize):
data = self.socket.recv(packetSize)
if self.tlsSocket is not None:
dd = ''
self.tlsSocket.bio_write(data)
while True:
try:
dd += self.tlsSocket.read(packetSize)
except SSL.WantReadError:
data2 = self.socket.recv(packetSize - len(data) )
self.tlsSocket.bio_write(data2)
pass
else:
data = dd
break
return data
def _checkHandshakeStatus(self):
"""
Ask OpenSSL to proceed with a handshake in progress.
Initially, this just sends the ClientHello; after some bytes have been
stuffed in to the C{Connection} object by C{dataReceived}, it will then
respond to any C{Certificate} or C{KeyExchange} messages.
"""
# The connection might already be aborted (eg. by a callback during
# connection setup), so don't even bother trying to handshake in that
# case.
if self._aborted:
return
try:
self._tlsConnection.do_handshake()
except WantReadError:
self._flushSendBIO()
except Error:
self._tlsShutdownFinished(Failure())
else:
self._handshakeDone = True
if IHandshakeListener.providedBy(self.wrappedProtocol):
self.wrappedProtocol.handshakeCompleted()
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def send(self, data, flags=0, timeout=timeout_default):
if timeout is timeout_default:
timeout = self.timeout
while True:
try:
return self._sock.send(data, flags)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_write(self.fileno(), timeout=timeout)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=timeout)
except SSL.SysCallError, ex:
if ex[0] == -1 and data == "":
# errors when writing empty strings are expected and can be ignored
return 0
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def recv(self, buflen):
pending = self._sock.pending()
if pending:
return self._sock.recv(min(pending, buflen))
while True:
try:
return self._sock.recv(buflen)
except SSL.WantReadError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.WantWriteError, ex:
if self.timeout == 0.0:
raise timeout(str(ex))
else:
sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout)
except SSL.ZeroReturnError:
return ''
except SSL.SysCallError, ex:
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def request(self, buf):
try:
self.sock.send(buf)
except SSL.Error as exc:
raise_from(Error("SSL Error"), exc)
else:
try:
#peek_bytes = self.sock.recv(8, socket.MSG_PEEK) # peeky no worky?!
peek_bytes = self.sock.recv(8)
except SSL.WantReadError as exc:
# SSL timeout does not work properly. If no data is available from server,
# we'll get this error
pass
except SSL.Error as exc:
raise
#raise_from(Error("SSL Error"), exc)
else:
(ver, type_, length) = struct.unpack('>HHL', peek_bytes)
return bytearray(peek_bytes + self.sock.recv(length))
def test_set_info_callback(self):
"""
L{Context.set_info_callback} accepts a callable which will be invoked
when certain information about an SSL connection is available.
"""
(server, client) = socket_pair()
clientSSL = Connection(Context(TLSv1_METHOD), client)
clientSSL.set_connect_state()
called = []
def info(conn, where, ret):
called.append((conn, where, ret))
context = Context(TLSv1_METHOD)
context.set_info_callback(info)
context.use_certificate(
load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
context.use_privatekey(
load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
serverSSL = Connection(context, server)
serverSSL.set_accept_state()
while not called:
for ssl in clientSSL, serverSSL:
try:
ssl.do_handshake()
except WantReadError:
pass
# Kind of lame. Just make sure it got called somehow.
self.assertTrue(called)
def _load_verify_locations_test(self, *args):
(server, client) = socket_pair()
clientContext = Context(TLSv1_METHOD)
clientContext.load_verify_locations(*args)
# Require that the server certificate verify properly or the
# connection will fail.
clientContext.set_verify(
VERIFY_PEER,
lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
clientSSL = Connection(clientContext, client)
clientSSL.set_connect_state()
serverContext = Context(TLSv1_METHOD)
serverContext.use_certificate(
load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
serverContext.use_privatekey(
load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
serverSSL = Connection(serverContext, server)
serverSSL.set_accept_state()
for i in range(3):
for ssl in clientSSL, serverSSL:
try:
# Without load_verify_locations above, the handshake
# will fail:
# Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE',
# 'certificate verify failed')]
ssl.do_handshake()
except WantReadError:
pass
cert = clientSSL.get_peer_certificate()
self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
def test_socketConnect(self):
"""
Just like L{test_memoryConnect} but with an actual socket.
This is primarily to rule out the memory BIO code as the source of
any problems encountered while passing data over a L{Connection} (if
this test fails, there must be a problem outside the memory BIO
code, as no memory BIO is involved here). Even though this isn't a
memory BIO test, it's convenient to have it here.
"""
(server, client) = socket_pair()
# Let the encryption begin...
client_conn = self._client(client)
server_conn = self._server(server)
# Establish the connection
established = False
while not established:
established = True # assume the best
for ssl in client_conn, server_conn:
try:
# Generally a recv() or send() could also work instead
# of do_handshake(), and we would stop on the first
# non-exception.
ssl.do_handshake()
except WantReadError:
established = False
important_message = "Help me Obi Wan Kenobi, you're my only hope."
client_conn.send(important_message)
msg = server_conn.recv(1024)
self.assertEqual(msg, important_message)
# Again in the other direction, just for fun.
important_message = important_message[::-1]
server_conn.send(important_message)
msg = client_conn.recv(1024)
self.assertEqual(msg, important_message)
def test_shutdown(self):
"""
L{Connection.bio_shutdown} signals the end of the data stream from
which the L{Connection} reads.
"""
server = self._server(None)
server.bio_shutdown()
e = self.assertRaises(Error, server.recv, 1024)
# We don't want WantReadError or ZeroReturnError or anything - it's a
# handshake failure.
self.assertEquals(e.__class__, Error)
def init_connection(self):
self.connect()
#This is copied from tds.py
resp = self.preLogin()
if resp['Encryption'] == TDS_ENCRYPT_REQ or resp['Encryption'] == TDS_ENCRYPT_OFF:
logging.info("Encryption required, switching to TLS")
# Switching to TLS now
ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_cipher_list('RC4')
tls = SSL.Connection(ctx,None)
tls.set_connect_state()
while True:
try:
tls.do_handshake()
except SSL.WantReadError:
data = tls.bio_read(4096)
self.sendTDS(TDS_PRE_LOGIN, data,0)
tds = self.recvTDS()
tls.bio_write(tds['Data'])
else:
break
# SSL and TLS limitation: Secure Socket Layer (SSL) and its replacement,
# Transport Layer Security(TLS), limit data fragments to 16k in size.
self.packetSize = 16*1024-1
self.tlsSocket = tls
self.resp = resp
def do_handshake(self):
while True:
try:
self._sock.do_handshake()
break
except SSL.WantReadError:
sys.exc_clear()
wait_read(self.fileno())
except SSL.WantWriteError:
sys.exc_clear()
wait_write(self.fileno())
except SSL.SysCallError, ex:
raise sslerror(SysCallError_code_mapping.get(ex.args[0], ex.args[0]), ex.args[1])
except SSL.Error, ex:
raise sslerror(str(ex))