我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用OpenSSL.SSL.WantReadError()。
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 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 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 _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 _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 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))
def load_crt(self, crt): ''' Load certificate file content to openssl x509 object. :param crt: Certificate file path. :type crt: String. :returns: Informational result dict {'error': Boolean, 'message': if error String else x509 object} :rtype: Dict. ''' try: x509obj = crypto.load_certificate( crypto.FILETYPE_PEM, open(crt).read()) except SSL.SysCallError as e: res = {"error": True, "message": e.strerror + " " + e.filename} #print(ex.args, ex.errno, ex.filename, ex.strerror) except SSL.Error as f: res = {"error": True, "message": f.strerror + " " + f.filename} except SSL.WantReadError as r: res = {"error": True, "message": r.strerror + " " + r.filename} except SSL.WantWriteError as w: res = {"error": True, "message": w.strerror + " " + w.filename} except SSL.WantX509LookupError as x: res = {"error": True, "message": x.strerror + " " + x.filename} except Exception as ex: res = {"error": True, "message": ex.strerror + " " + ex.filename} except: res = {"error": True, "message": "Unexpected error"} else: res = {"error": False, "message": x509obj} finally: return(res)
def go(): port = socket() port.bind(('', 0)) port.listen(1) called = [] def info(conn, where, ret): print count.next() called.append(None) 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)) while 1: client = socket() client.setblocking(False) client.connect_ex(port.getsockname()) clientSSL = Connection(Context(TLSv1_METHOD), client) clientSSL.set_connect_state() server, ignored = port.accept() server.setblocking(False) serverSSL = Connection(context, server) serverSSL.set_accept_state() del called[:] while not called: for ssl in clientSSL, serverSSL: try: ssl.do_handshake() except WantReadError: pass
def go(): port = socket() port.bind(('', 0)) port.listen(1) called = [] def info(*args): print count.next() called.append(None) return 1 context = Context(TLSv1_METHOD) context.set_verify(VERIFY_PEER, info) context.use_certificate( load_certificate(FILETYPE_PEM, cleartextCertificatePEM)) context.use_privatekey( load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)) while 1: client = socket() client.setblocking(False) client.connect_ex(port.getsockname()) clientSSL = Connection(context, client) clientSSL.set_connect_state() server, ignored = port.accept() server.setblocking(False) serverSSL = Connection(context, server) serverSSL.set_accept_state() del called[:] while not called: for ssl in clientSSL, serverSSL: try: ssl.send('foo') except WantReadError, e: pass
def read_from_fd(self): if self._ssl_accepting: return None try: chunk = self.socket.read(self.read_chunk_size) except SSL.WantReadError: return None except SSL.ZeroReturnError: self.close(exc_info=True) return None except SSL.SysCallError as e: err_num = abs(e[0]) if err_num in (errno.EWOULDBLOCK, errno.EAGAIN): return None # NOTE: We will handle the self.close in here. # _read_to_buffer of BaseIOStream will not chceck SSL.SysCallError if err_num == errno.EPERM: self.close(exc_info=True) return None self.close(exc_info=True) raise # NOTE: Just in case we missed some SSL Error type. except SSL.Error as e: raise if not chunk: self.close() return None return chunk
def _start_tls_handshake(self, response, **kwargs): """ [MS-CSSP] v13.0 2016-07-14 3.1.5 Processing Events and Sequencing Rules - Step 1 This is the first step in a CredSSP auth sequence where the client and server complete the TLS handshake as specified in RFC2246. After the handshake is complete, all subsequent CredSSP Protocol messages are encrypted by the TLS channel. :param response: The original 401 response from the server :param kwargs: The requests kwargs from the original response """ # Check that the server support CredSSP authentication self._check_credssp_supported(response) self.tls_connection = SSL.Connection(self.tls_context) self.tls_connection.set_connect_state() log.debug("_start_tls_handshake(): Starting TLS handshake with server") while True: try: self.tls_connection.do_handshake() except SSL.WantReadError: request = response.request.copy() credssp_token = self.tls_connection.bio_read(self.BIO_BUFFER_SIZE) self._set_credssp_token(request, credssp_token) response = response.connection.send(request, **kwargs) response.content response.raw.release_conn() server_credssp_token = self._get_credssp_token(response) self.tls_connection.bio_write(server_credssp_token) else: break self.cipher_negotiated = self.tls_connection.get_cipher_name() log.debug("_start_tls_handshake(): Handshake complete. Protocol: %s, Cipher: %s" % ( self.tls_connection.get_protocol_version_name(), self.tls_connection.get_cipher_name()))
def wrap(self, data): """ Encrypts the data in preparation for sending to the server. The data is encrypted using the TLS channel negotiated between the client and the server. :param data: a byte string of data to encrypt :return: a byte string of the encrypted data """ length = self.tls_connection.send(data) encrypted_data = b'' counter = 0 while True: try: encrypted_chunk = self.tls_connection.bio_read(self.BIO_BUFFER_SIZE) except SSL.WantReadError: break encrypted_data += encrypted_chunk # in case of a borked TLS connection, break the loop if the current # buffer counter is > the length of the original message plus the # the size of the buffer (to be careful) counter += self.BIO_BUFFER_SIZE if counter > length + self.BIO_BUFFER_SIZE: break return encrypted_data
def _send_raw(self): while True: self.ssl_write = None slen = 0 try: slen = self.sock.send(self.send_buf) except (socket.error, OSError, SSL.ZeroReturnError, SSL.SysCallError, SSL.WantReadError): break except SSL.WantWriteError: self.ssl_write = True self.send_buf = self.send_buf[slen:] if len(self.send_buf) < 1: self.send_buf = None break
def _flushSendBIO(self): """ Read any bytes out of the send BIO and write them to the underlying transport. """ try: bytes = self._tlsConnection.bio_read(2 ** 15) except WantReadError: # There may be nothing in the send BIO right now. pass else: self.transport.write(bytes)
def _flushReceiveBIO(self): """ Try to receive any application-level bytes which are now available because of a previous write into the receive BIO. This will take care of delivering any application-level bytes which are received to the protocol, as well as handling of the various exceptions which can come from trying to get such bytes. """ # Keep trying this until an error indicates we should stop or we # close the connection. Looping is necessary to make sure we # process all of the data which was put into the receive BIO, as # there is no guarantee that a single recv call will do it all. while not self._lostTLSConnection: try: bytes = self._tlsConnection.recv(2 ** 15) except WantReadError: # The newly received bytes might not have been enough to produce # any application data. break except ZeroReturnError: # TLS has shut down and no more TLS data will be received over # this connection. self._shutdownTLS() # Passing in None means the user protocol's connnectionLost # will get called with reason from underlying transport: self._tlsShutdownFinished(None) except Error: # Something went pretty wrong. For example, this might be a # handshake failure during renegotiation (because there were no # shared ciphers, because a certificate failed to verify, etc). # TLS can no longer proceed. failure = Failure() self._tlsShutdownFinished(failure) else: if not self._aborted: ProtocolWrapper.dataReceived(self, bytes) # The received bytes might have generated a response which needs to be # sent now. For example, the handshake involves several round-trip # exchanges without ever producing application-bytes. self._flushSendBIO()
def _write(self, bytes): """ Process the given application bytes and send any resulting TLS traffic which arrives in the send BIO. This may be called by C{dataReceived} with bytes that were buffered before C{loseConnection} was called, which is why this function doesn't check for disconnection but accepts the bytes regardless. """ if self._lostTLSConnection: return # A TLS payload is 16kB max bufferSize = 2 ** 14 # How far into the input we've gotten so far alreadySent = 0 while alreadySent < len(bytes): toSend = bytes[alreadySent:alreadySent + bufferSize] try: sent = self._tlsConnection.send(toSend) except WantReadError: self._bufferedWrite(bytes[alreadySent:]) break except Error: # Pretend TLS connection disconnected, which will trigger # disconnect of underlying transport. The error will be passed # to the application protocol's connectionLost method. The # other SSL implementation doesn't, but losing helpful # debugging information is a bad idea. self._tlsShutdownFinished(Failure()) break else: # We've successfully handed off the bytes to the OpenSSL # Connection object. alreadySent += sent # See if OpenSSL wants to hand any bytes off to the underlying # transport as a result. self._flushSendBIO()
def __iowait(self, io_func, *args, **kwargs): timeout = self._sock.gettimeout() fd = self._sock while self._connection: try: return io_func(*args, **kwargs) except (SSL.WantReadError, SSL.WantX509LookupError): #exc_clear() rd, _, ed = select([fd], [], [fd], timeout) if ed: raise socket.error(ed) if not rd: raise socket.timeout('The read operation timed out') except SSL.WantWriteError: #exc_clear() _, wd, ed = select([], [fd], [fd], timeout) if ed: raise socket.error(ed) if not wd: raise socket.timeout('The write operation timed out') except SSL.SysCallError as e: if e.args[0] == errno.EWOULDBLOCK: #exc_clear() rd, wd, ed = select([fd], [fd], [fd], timeout) if ed: raise socket.error(ed) if not rd and not wd: raise socket.timeout('The socket operation timed out') elif e.args[0] == errno.EAGAIN: continue else: raise e
def _loopback(self, client_conn, server_conn): """ Try to read application bytes from each of the two L{Connection} objects. Copy bytes back and forth between their send/receive buffers for as long as there is anything to copy. When there is nothing more to copy, return C{None}. If one of them actually manages to deliver some application bytes, return a two-tuple of the connection from which the bytes were read and the bytes themselves. """ wrote = True while wrote: # Loop until neither side has anything to say wrote = False # Copy stuff from each side's send buffer to the other side's # receive buffer. for (read, write) in [(client_conn, server_conn), (server_conn, client_conn)]: # Give the side a chance to generate some more bytes, or # succeed. try: bytes = read.recv(2 ** 16) except WantReadError: # It didn't succeed, so we'll hope it generated some # output. pass else: # It did succeed, so we'll stop now and let the caller deal # with it. return (read, bytes) while True: # Keep copying as long as there's more stuff there. try: dirty = read.bio_read(4096) except WantReadError: # Okay, nothing more waiting to be sent. Stop # processing this send buffer. break else: # Keep track of the fact that someone generated some # output. wrote = True write.bio_write(dirty)