def __init__(self, ctx, sock=None, family=socket.AF_INET): # type: (Context, socket.socket, int) -> None """ :param ctx: SSL.Context :param sock: socket to be used :param family: socket family """ self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) if sock is not None: self.socket = sock else: self.socket = socket.socket(family, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self._timeout = self.socket.gettimeout() 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)
def __init__(self, ctx, sock=None, family=socket.AF_INET): # type: (Context, socket.socket, int) -> None """ :param ctx: SSL.Context :param sock: socket to be used :param family: socket family """ # The Checker needs to be an instance attribute # and not a class attribute for thread safety reason self.clientPostConnectionCheck = Checker.Checker() self._bio_freed = False self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) # type: bytes if sock is not None: self.socket = sock else: self.socket = socket.socket(family, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self._timeout = self.socket.gettimeout() 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) self.host = None
def __init__(self, ctx, sock=None, family=socket.AF_INET): # type: (Context, socket.socket, int) -> None """ :param ctx: SSL.Context :param sock: socket to be used :param family: socket family """ self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) # type: bytes if sock is not None: self.socket = sock else: self.socket = socket.socket(family, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self._timeout = self.socket.gettimeout() 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) self.host = None
def __init__(self, ctx, sock=None): self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) if sock is not None: self.socket = sock else: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self.blocking = self.socket.gettimeout() self.ssl_close_flag = m2.bio_noclose
def __init__(self, ctx, sock=None, family=socket.AF_INET): self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) if sock is not None: self.socket = sock else: self.socket = socket.socket(family, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self._timeout = self.socket.gettimeout() 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)
def __init__(self, ctx, sock=None): self.ctx = ctx self.ssl = m2.ssl_new(self.ctx.ctx) if sock is not None: self.socket = sock else: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._fileno = self.socket.fileno() self._timeout = self.socket.gettimeout() 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)
def startTLS(self, ctx): """ Start SSL/TLS. If this is not called, this instance just passes data through untouched. """ # NOTE: This method signature must match the startTLS() method Twisted # expects transports to have. This will be called automatically # by Twisted in STARTTLS situations, for example with SMTP. if self.tlsStarted: raise Exception, 'TLS already started' if debug: print 'TwistedProtocolWrapper.startTLS' self.ctx = ctx self.internalBio = m2.bio_new(m2.bio_s_bio()) m2.bio_set_write_buf_size(self.internalBio, 0) self.networkBio = _BioProxy(m2.bio_new(m2.bio_s_bio())) m2.bio_set_write_buf_size(self.networkBio._ptr(), 0) m2.bio_make_bio_pair(self.internalBio, self.networkBio._ptr()) self.sslBio = _BioProxy(m2.bio_new(m2.bio_f_ssl())) self.ssl = _SSLProxy(m2.ssl_new(self.ctx.ctx)) if self.isClient: m2.ssl_set_connect_state(self.ssl._ptr()) else: m2.ssl_set_accept_state(self.ssl._ptr()) 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._ptr()) m2.ssl_set_mode(self.ssl._ptr(), mode | m2.SSL_MODE_ENABLE_PARTIAL_WRITE | m2.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) self.tlsStarted = 1
def startTLS(self, ctx): """ Start SSL/TLS. If this is not called, this instance just passes data through untouched. """ # NOTE: This method signature must match the startTLS() method Twisted # expects transports to have. This will be called automatically # by Twisted in STARTTLS situations, for example with SMTP. if self.tlsStarted: raise Exception, 'TLS already started' if debug: print 'TwistedProtocolWrapper.startTLS' self.ctx = ctx self.internalBio = m2.bio_new(m2.bio_s_bio()) m2.bio_set_write_buf_size(self.internalBio, 0) self.networkBio = m2.bio_new(m2.bio_s_bio()) m2.bio_set_write_buf_size(self.networkBio, 0) m2.bio_make_bio_pair(self.internalBio, self.networkBio) self.sslBio = _SSLBioProxy(m2.bio_new(m2.bio_f_ssl())) self.ssl = _SSLProxy(m2.ssl_new(self.ctx.ctx)) if self.isClient: m2.ssl_set_connect_state(self.ssl._ptr()) else: m2.ssl_set_accept_state(self.ssl._ptr()) 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._ptr()) m2.ssl_set_mode( self.ssl._ptr(), mode | m2.SSL_MODE_ENABLE_PARTIAL_WRITE | m2.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) self.tlsStarted = 1
def c_style(HOST, PORT, req): # Set up SSL context. ctx = m2.ssl_ctx_new(m2.sslv3_method()) m2.ssl_ctx_use_cert(ctx, 'client.pem') m2.ssl_ctx_use_privkey(ctx, 'client.pem') # Make the socket connection. s = socket(AF_INET, SOCK_STREAM) s.connect((HOST, PORT)) # Set up the SSL connection. sbio = m2.bio_new_socket(s.fileno(), 0) ssl = m2.ssl_new(ctx) m2.ssl_set_bio(ssl, sbio, sbio) m2.ssl_connect(ssl) sslbio = m2.bio_new(m2.bio_f_ssl()) m2.bio_set_ssl(sslbio, ssl, 0) # Push a buffering BIO over the SSL BIO. iobuf = m2.bio_new(m2.bio_f_buffer()) topbio = m2.bio_push(iobuf, sslbio) # Send the request. m2.bio_write(sslbio, req) # Receive the response. while 1: data = m2.bio_gets(topbio, 4096) if not data: break sys.stdout.write(data) # Cleanup. May be missing some necessary steps. ;-| m2.bio_pop(topbio) m2.bio_free(iobuf) m2.ssl_shutdown(ssl) m2.ssl_free(ssl) m2.ssl_ctx_free(ctx) s.close()
# "cert already in hash table" error (perhaps my distro's # CA bundle has duplicate certs?). It doesn't seem there's # anything that can be done about it, so just eat it. # (There may be multiple such errors, so clear them all.) while True: err = m2.err_get_error() if not err: break # The magic number is X509_R_CERT_ALREADY_IN_HASH_TABLE, which # is a constant that m2crypto doesn't export. :/ if err != 185057381: raise TLSError(m2.err_reason_error_string(err)) # Create a lower level (SWIG) SSL object using this context. self._ssl = _SSLWrapper(m2.ssl_new(ctx.ctx)) if kwargs['client']: self._m2_check_err(m2.ssl_set_connect_state(self._ssl.obj)) else: self._m2_check_err(m2.ssl_set_accept_state(self._ssl.obj)) # Setup the BIO pair. This diagram is instructive: # # Application | TLS layer # | # Your Code | # /\ || | # || \/ | # Application buffer <===> TLS read/write/etc # | /\ || # | || \/
# least on my system it yields the delightfully inscrutable # "cert already in hash table" error (perhaps my distro's # CA bundle has duplicate certs?). It doesn't seem there's # anything that can be done about it, so just eat it. # (There may be multiple such errors, so clear them all.) while True: err = m2.err_get_error() if not err: break # The magic number is X509_R_CERT_ALREADY_IN_HASH_TABLE, which # is a constant that m2crypto doesn't export. :/ if err != 185057381: raise TLSError(m2.err_reason_error_string(err)) # Create a lower level (SWIG) SSL object using this context. self._ssl = _SSLWrapper(m2.ssl_new(ctx.ctx)) if kwargs['client']: self._m2_check_err(m2.ssl_set_connect_state(self._ssl.obj)) else: self._m2_check_err(m2.ssl_set_accept_state(self._ssl.obj)) # Setup the BIO pair. This diagram is instructive: # # Application | TLS layer # | # Your Code | # /\ || | # || \/ | # Application buffer <===> TLS read/write/etc # | /\ || # | || \/