diff -ur m2crypto/M2Crypto/BIO.py m2crypto-0.16/M2Crypto/BIO.py --- m2crypto/M2Crypto/BIO.py 2006-03-25 20:59:13.000000000 +0100 +++ m2crypto-0.16/M2Crypto/BIO.py 2010-12-06 22:45:54.876037674 +0100 @@ -272,6 +272,8 @@ """ self._pyfree = 0 m2.bio_set_ssl(self.bio, conn.ssl, close_flag) + if close_flag == m2.bio_noclose: + conn.set_ssl_close_flag(m2.bio_close) def do_handshake(self): """ diff -ur m2crypto/M2Crypto/SSL/Connection.py m2crypto-0.16/M2Crypto/SSL/Connection.py --- m2crypto/M2Crypto/SSL/Connection.py 2010-12-06 21:32:53.751877386 +0100 +++ m2crypto-0.16/M2Crypto/SSL/Connection.py 2010-12-06 22:50:55.668703111 +0100 @@ -26,7 +26,8 @@ serverPostConnectionCheck = _serverPostConnectionCheck m2_bio_free = m2.bio_free - + m2_ssl_free = m2.ssl_free + def __init__(self, ctx, sock=None): self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) @@ -41,6 +42,8 @@ if self._timeout is None: self._timeout = -1.0 + self.ssl_close_flag = m2.bio_noclose + if self.ctx.post_connection_check is not None: self.set_post_connection_check_callback \ (self.ctx.post_connection_check) @@ -50,6 +53,8 @@ self.m2_bio_free(self.sslbio) if getattr(self, 'sockbio', None): self.m2_bio_free(self.sockbio) + if self.ssl_close_flag == m2.bio_noclose and getattr(self, 'ssl', None): + self.m2_ssl_free(self.ssl) self.socket.close() def close(self): @@ -109,6 +114,15 @@ def setup_addr(self, addr): self.addr = addr + def set_ssl_close_flag(self, flag): + """ + By default, SSL struct will be freed in __del__. Call with + m2.bio_close to override this default. + """ + if flag not in (m2.bio_close, m2.bio_noclose): + raise ValueError("flag must be m2.bio_close or m2.bio_noclose") + self.ssl_close_flag = flag + def setup_ssl(self): # Make a BIO_s_socket. self.sockbio = m2.bio_new_socket(self.socket.fileno(), 0) @@ -117,7 +131,7 @@ # Make a BIO_f_ssl. self.sslbio = m2.bio_new(m2.bio_f_ssl()) # Link BIO_f_ssl with the SSL struct. - m2.bio_set_ssl(self.sslbio, self.ssl, 1) + m2.bio_set_ssl(self.sslbio, self.ssl, m2.bio_noclose) def _setup_ssl(self, addr): """Deprecated""" Pouze v m2crypto-0.16/M2Crypto/SSL: Connection.py~ diff -ur m2crypto/M2Crypto/SSL/TwistedProtocolWrapper.py m2crypto-0.16/M2Crypto/SSL/TwistedProtocolWrapper.py --- m2crypto/M2Crypto/SSL/TwistedProtocolWrapper.py 2006-05-09 22:07:00.000000000 +0200 +++ m2crypto-0.16/M2Crypto/SSL/TwistedProtocolWrapper.py 2010-12-06 22:49:06.108802425 +0100 @@ -122,6 +122,25 @@ self.m2_bio_free_all(self.sslBio) +class _SSLProxy: + """ + The purpose of this class is to eliminate the __del__ method from + TLSProtocolWrapper, and thus letting it be garbage collected. + """ + + m2_ssl_free = m2.ssl_free + + def __init__(self, ssl): + self.ssl = ssl + + def _ptr(self): + return self.ssl + + def __del__(self): + if self.ssl is not None: + self.m2_ssl_free(self.ssl) + + class TLSProtocolWrapper(ProtocolWrapper): """ A SSL/TLS protocol wrapper to be used with Twisted. Typically @@ -132,8 +151,6 @@ implements(ITLSTransport) - m2_bio_free_all = m2.bio_free_all - def __init__(self, factory, wrappedProtocol, startPassThrough, client, contextFactory, postConnectionCheck): """ @@ -188,8 +205,8 @@ if debug: print 'TwistedProtocolWrapper.clear' if getattr(self, 'tlsStarted', 0): - del self.sslBio self.sslBio = None + self.ssl = None self.internalBio = None self.networkBio = None self.data = '' @@ -225,19 +242,19 @@ self.sslBio = _SSLBioProxy(m2.bio_new(m2.bio_f_ssl())) - self.ssl = m2.ssl_new(self.ctx.ctx) + self.ssl = _SSLProxy(m2.ssl_new(self.ctx.ctx)) if self.isClient: - m2.ssl_set_connect_state(self.ssl) + m2.ssl_set_connect_state(self.ssl._ptr()) else: - m2.ssl_set_accept_state(self.ssl) + m2.ssl_set_accept_state(self.ssl._ptr()) - m2.ssl_set_bio(self.ssl, self.internalBio, self.internalBio) - m2.bio_set_ssl(self.sslBio._ptr(), self.ssl, 1) + m2.ssl_set_bio(self.ssl._ptr(), self.internalBio, self.internalBio) + m2.bio_set_ssl(self.sslBio._ptr(), self.ssl._ptr(), m2.bio_noclose) # Need this for writes that are larger than BIO pair buffers - mode = m2.ssl_get_mode(self.ssl) - m2.ssl_set_mode(self.ssl, + mode = m2.ssl_get_mode(self.ssl._ptr()) + m2.ssl_set_mode(self.ssl._ptr(), mode | m2.SSL_MODE_ENABLE_PARTIAL_WRITE | m2.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) @@ -263,7 +280,7 @@ except M2Crypto.BIO.BIOError, e: # See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS # for the error codes returned by SSL_get_verify_result. - e.args = (m2.ssl_get_verify_result(self.ssl), e.args[0]) + e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0]) raise e def writeSequence(self, data): @@ -278,7 +295,7 @@ def loseConnection(self): if debug: print 'TwistedProtocolWrapper.loseConnection' - # XXX Do we need to do m2.ssl_shutdown(self.ssl)? + # XXX Do we need to do m2.ssl_shutdown(self.ssl._ptr())? ProtocolWrapper.loseConnection(self) def registerProducer(self, producer, streaming): @@ -328,7 +345,7 @@ except M2Crypto.BIO.BIOError, e: # See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS # for the error codes returned by SSL_get_verify_result. - e.args = (m2.ssl_get_verify_result(self.ssl), e.args[0]) + e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0]) raise e def connectionLost(self, reason): @@ -341,8 +358,8 @@ if debug: print 'TwistedProtocolWrapper._check' - if not self.checked and m2.ssl_is_init_finished(self.ssl): - x = m2.ssl_get_peer_cert(self.ssl) + if not self.checked and m2.ssl_is_init_finished(self.ssl._ptr()): + x = m2.ssl_get_peer_cert(self.ssl._ptr()) if x: x509 = X509.X509(x, 1) else: @@ -368,7 +385,7 @@ except M2Crypto.BIO.BIOError, e: # See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS # for the error codes returned by SSL_get_verify_result. - e.args = (m2.ssl_get_verify_result(self.ssl), e.args[0]) + e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0]) raise e def _encrypt(self, data='', clientHello=0): Pouze v m2crypto-0.16/M2Crypto/SSL: TwistedProtocolWrapper.py~ diff -ur m2crypto/tests/test_ssl.py m2crypto-0.16/tests/test_ssl.py --- m2crypto/tests/test_ssl.py 2010-12-06 21:32:53.592877380 +0100 +++ m2crypto-0.16/tests/test_ssl.py 2010-12-06 22:47:56.489871872 +0100 @@ -84,6 +84,10 @@ global srv_port srv_port = srv_port - 1 + def test_no_connection(self): + ctx = SSL.Context() + s = SSL.Connection(ctx) + def test_server_simple(self): pid = self.start_server(self.args) try: Pouze v m2crypto-0.16/tests: test_ssl.py~