def connect(self): """ Connect to a host on a given (SSL) port. If ca_file is pointing somewhere, use it to check Server Certificate. Redefined/copied and extended from httplib.py:1105 (Python 2.6.x). This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter to ssl.wrap_socket(), which forces SSL to check server certificate against our client certificate. """ sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() # Check CA file unless 'insecure' is specificed if self.insecure is True: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) else: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED)
def connect(self): """ Connect to a host on a given (SSL) port. If ca_file is pointing somewhere, use it to check Server Certificate. Redefined/copied and extended from httplib.py:1105 (Python 2.6.x). This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter to ssl.wrap_socket(), which forces SSL to check server certificate against our client certificate. """ sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() # Check CA file unless 'insecure' is specificed if self.insecure is True: self.sock = ssl.wrap_socket( sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) else: self.sock = ssl.wrap_socket( sock, self.key_file, self.cert_file, ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED)
def test_regression_gh_17(self): def serve(listener): sock, addr = listener.accept() # to simulate condition mentioned in GH-17 sock._sslobj = None sock.sendall(b'some data') greenio.shutdown_safe(sock) sock.close() listener = listen_ssl_socket(('', 0)) eventlet.spawn(serve, listener) ssl.wrap_socket(eventlet.connect(('localhost', listener.getsockname()[1])))
def test_regression_gh_17(self): def serve(listener): sock, addr = listener.accept() # to simulate condition mentioned in GH-17 sock._sslobj = None sock.sendall(b'some data') greenio.shutdown_safe(sock) sock.close() listener = listen_ssl_socket(('', 0)) eventlet.spawn(serve, listener) ssl.wrap_socket( eventlet.connect(('localhost', listener.getsockname()[1])))
def _tlsstartup(cnn): authname = None cnn = ssl.wrap_socket(cnn, keyfile="/etc/confluent/privkey.pem", certfile="/etc/confluent/srvcert.pem", ssl_version=ssl.PROTOCOL_TLSv1, server_side=True) sessionhdl(cnn, authname)
def get_socket(conf, default_port=8080): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get("bind_ip", "0.0.0.0"), int(conf.get("bind_port", default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get("backlog", 4096)), family=address_family) if "cert_file" in conf: sock = ssl.wrap_socket(sock, certfile=conf["cert_file"], keyfile=conf["key_file"]) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False): return ssl.wrap_socket(sock, keyfile=private_key, certfile=certificate, server_side=server_side, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True)
def test_connect_ssl(self): def accept_once(listenfd): try: conn, addr = listenfd.accept() conn.write(b'hello\r\n') greenio.shutdown_safe(conn) conn.close() finally: greenio.shutdown_safe(listenfd) listenfd.close() server = eventlet.wrap_ssl(eventlet.listen(('0.0.0.0', 0)), self.private_key_file, self.certificate_file, server_side=True) eventlet.spawn_n(accept_once, server) raw_client = eventlet.connect(('127.0.0.1', server.getsockname()[1])) client = ssl.wrap_socket(raw_client) fd = client.makefile('rb', 8192) assert fd.readline() == b'hello\r\n' try: self.assertEqual(b'', fd.read(10)) except greenio.SSL.ZeroReturnError: # if it's a GreenSSL object it'll do this pass greenio.shutdown_safe(client) client.close() check_hub()
def test_recv_after_ssl_connect(self): def serve(listener): sock, addr = listener.accept() sock.sendall(b'hjk') sock = listen_ssl_socket() server_coro = eventlet.spawn(serve, sock) raw_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssl_client = ssl.wrap_socket(raw_client) # Important: We need to call connect() on an SSL socket, not a plain one. # The bug was affecting that particular combination (create plain socket, # wrap, call connect() on the SSL socket and try to recv) on Python 3.5. ssl_client.connect(sock.getsockname()) # The call to recv used to fail with: # Traceback (most recent call last): # File "tests/ssl_test.py", line 99, in test_recv_after_ssl_connect # self.assertEqual(ssl_client.recv(3), b'hjk') # File "eventlet/green/ssl.py", line 194, in recv # return self._base_recv(buflen, flags, into=False) # File "eventlet/green/ssl.py", line 227, in _base_recv # read = self.read(nbytes) # File "eventlet/green/ssl.py", line 139, in read # super(GreenSSLSocket, self).read, *args, **kwargs) # File "eventlet/green/ssl.py", line 113, in _call_trampolining # return func(*a, **kw) # File "PYTHONLIB/python3.5/ssl.py", line 791, in read # return self._sslobj.read(len, buffer) # TypeError: read() argument 2 must be read-write bytes-like object, not None self.assertEqual(ssl_client.recv(3), b'hjk') greenio.shutdown_safe(ssl_client) ssl_client.close() server_coro.wait()
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(bind_addr)s" "after trying for 30 seconds") % {'bind_addr': bind_addr}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) return sock
def __init__(self): """ initialize a bunch of config crap. """ logger.info('initializing uplink and protocol..') self.protocol = protocol.Protocol() self.conf = { 'server': var.Configuration['server'], 'port': int(var.Configuration['port']), 'ssl': var.Configuration['ssl'], 'password': var.Configuration['password'], 'host': var.c.get('uplink', 'host'), 'bind': var.c.get('main', 'bind'), 'serverid': var.c.get('uplink', 'SID'), 'mnick': var.Configuration['nick'], 'mident': var.Configuration['ident'], 'mgecos': var.Configuration['gecos'], 'mhost': var.Configuration['host'] } self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if ssl and self.conf['ssl'] == 'True': self.connection = ssl.wrap_socket(self.socket) logger.info('<-> connection type: ssl') else: self.connection = self.socket logger.info('<-> conection type: plain') var.core = ((self, event.Events())) var.protocol = self.protocol var.database = database.Database()
def test_connect_ssl(self): def accept_once(listenfd): try: conn, addr = listenfd.accept() conn.write(b'hello\r\n') greenio.shutdown_safe(conn) conn.close() finally: greenio.shutdown_safe(listenfd) listenfd.close() server = eventlet.wrap_ssl( eventlet.listen(('0.0.0.0', 0)), self.private_key_file, self.certificate_file, server_side=True ) eventlet.spawn_n(accept_once, server) raw_client = eventlet.connect(('127.0.0.1', server.getsockname()[1])) client = ssl.wrap_socket(raw_client) fd = client.makefile('rb', 8192) assert fd.readline() == b'hello\r\n' try: self.assertEqual(b'', fd.read(10)) except greenio.SSL.ZeroReturnError: # if it's a GreenSSL object it'll do this pass greenio.shutdown_safe(client) client.close() check_hub()
def attachsession(self, session): self.clisession = session self.data_handler = session.data_handler termreq = { 'proxyconsole': { 'name': self.myname, 'user': self.user, 'tenant': self.cfm.tenant, 'node': self.node, 'skipreplay': self.skipreplay, 'width': self.initsize[0], 'height': self.initsize[1], #TODO(jjohnson2): declare myself as a proxy, #facilitate redirect rather than relay on manager change }, } try: remote = socket.create_connection((self.managerinfo['address'], 13001)) remote = ssl.wrap_socket(remote, cert_reqs=ssl.CERT_NONE, keyfile='/etc/confluent/privkey.pem', certfile='/etc/confluent/srvcert.pem') if not util.cert_matches(self.managerinfo['fingerprint'], remote.getpeercert(binary_form=True)): raise Exception('Invalid peer certificate') except Exception: eventlet.sleep(3) if self.clisession: self.clisession.detach() self.detachsession(None) return tlvdata.recv(remote) tlvdata.recv(remote) tlvdata.send(remote, termreq) self.remote = remote eventlet.spawn(self.relay_data)
def get_socket(conf, default_port=8080): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get('bind_ip', '0.0.0.0'), int(conf.get('bind_port', default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def client(addr): client_tls = ssl.wrap_socket( eventlet.connect(addr), cert_reqs=ssl.CERT_REQUIRED, ca_certs=tests.certificate_file, ) client_tls.send(expected)
def listen_ssl_socket(address=('127.0.0.1', 0)): sock = ssl.wrap_socket( socket.socket(), private_key_file, certificate_file, server_side=True) sock.bind(address) sock.listen(50) return sock
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _( "When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file" ) ) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(bind_addr)s" "after trying for 30 seconds") % {"bind_addr": bind_addr} ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, "TCP_KEEPIDLE"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) return sock
def test_receiving_doesnt_block_if_there_is_already_decrypted_buffered_data(self): # Here's what could (and would) happen before the relevant bug was fixed (assuming method # M was trampolining unconditionally before actually reading): # 1. One side sends n bytes, leaves connection open (important) # 2. The other side uses method M to read m (where m < n) bytes, the underlying SSL # implementation reads everything from the underlying socket, decrypts all n bytes, # returns m of them and buffers n-m to be read later. # 3. The other side tries to read the remainder of the data (n-m bytes), this blocks # because M trampolines uncoditionally and trampoline will hang because reading from # the underlying socket would block. It would block because there's no data to be read # and the connection is still open; leaving the connection open /mentioned in 1./ is # important because otherwise trampoline would return immediately and the test would pass # even with the bug still present in the code). # # The solution is to first request data from the underlying SSL implementation and only # trampoline if we actually need to read some data from the underlying socket. # # GreenSSLSocket.recv() wasn't broken but I've added code to test it as well for # completeness. content = b'xy' def recv(sock, expected): assert sock.recv(len(expected)) == expected def recv_into(sock, expected): buf = bytearray(len(expected)) assert sock.recv_into(buf, len(expected)) == len(expected) assert buf == expected for read_function in [recv, recv_into]: print('Trying %s...' % (read_function,)) listener = listen_ssl_socket() def accept(listener): sock, addr = listener.accept() sock.sendall(content) return sock accepter = eventlet.spawn(accept, listener) client_to_server = None try: client_to_server = ssl.wrap_socket(eventlet.connect(listener.getsockname())) for character in six.iterbytes(content): character = six.int2byte(character) print('We have %d already decrypted bytes pending, expecting: %s' % ( client_to_server.pending(), character)) read_function(client_to_server, character) finally: if client_to_server is not None: client_to_server.close() server_to_client = accepter.wait() # Very important: we only want to close the socket *after* the other side has # read the data it wanted already, otherwise this would defeat the purpose of the # test (see the comment at the top of this test). server_to_client.close() listener.close()
def wrap_ssl(sock): ssl_kwargs = {"server_side": True, "certfile": cert_file, "keyfile": key_file, "cert_reqs": ssl.CERT_NONE} if CONF.ca_file: ssl_kwargs["ca_certs"] = CONF.ca_file ssl_kwargs["cert_reqs"] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs)
def listen_ssl_socket(address=('127.0.0.1', 0)): sock = ssl.wrap_socket(socket.socket(), private_key_file, certificate_file, server_side=True) sock.bind(address) sock.listen(50) return sock
def get_socket(conf): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :returns: a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ try: bind_port = int(conf['bind_port']) except (ValueError, KeyError, TypeError): raise ConfigFilePortError() bind_addr = (conf.get('bind_ip', '0.0.0.0'), bind_port) address_family = [addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6)][0] sock = None bind_timeout = int(conf.get('bind_timeout', 30)) retry_until = time.time() + bind_timeout warn_ssl = False try: keepidle = int(conf.get('keep_idle', 600)) if keepidle <= 0 or keepidle >= 2 ** 15 - 1: raise ValueError() except (ValueError, KeyError, TypeError): raise ConfigFileError() while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception(_('Could not bind to %(addr)s:%(port)s ' 'after trying for %(timeout)s seconds') % { 'addr': bind_addr[0], 'port': bind_addr[1], 'timeout': bind_timeout}) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, keepidle) if warn_ssl: ssl_warning_message = _('WARNING: SSL should only be enabled for ' 'testing purposes. Use external SSL ' 'termination for a production deployment.') get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def listen_ssl_socket(address=('localhost', 0), **kwargs): sock = ssl.wrap_socket(socket.socket(), tests.private_key_file, tests.certificate_file, server_side=True, **kwargs) sock.bind(address) sock.listen(50) return sock
def filter(self): """ this will create a filter on the socket (eg., ssl) """ if ssl is True: self.connection = ssl.wrap_socket(self.socket) elif ssl is False: self.connection = self.socket else: self.connection = self.socket
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False): warnings.warn("eventlet.util.wrap_ssl is deprecated. " "Please use the eventlet.green.ssl.wrap_socket()", DeprecationWarning, stacklevel=2) return ssl.wrap_socket( sock, keyfile=private_key, certfile=certificate, server_side=server_side, )
def test_regression_gh_17(self): # https://github.com/eventlet/eventlet/issues/17 # ssl wrapped but unconnected socket methods go special code path # test that path at least for syntax/typo errors sock = ssl.wrap_socket(socket.socket()) sock.settimeout(0.01) try: sock.sendall(b'') except ssl.SSLError as e: assert 'timed out' in str(e)
def serve(): sock, addr = listener.accept() self.assertEqual(sock.recv(6), b'before') sock_ssl = ssl.wrap_socket(sock, private_key_file, certificate_file, server_side=True) sock_ssl.do_handshake() self.assertEqual(sock_ssl.read(6), b'during') sock2 = sock_ssl.unwrap() self.assertEqual(sock2.recv(5), b'after') sock2.close()
def serve(): sock, addr = listener.accept() self.assertEqual(sock.recv(6), b'before') sock_ssl = ssl.wrap_socket(sock, tests.private_key_file, tests.certificate_file, server_side=True) sock_ssl.do_handshake() self.assertEqual(sock_ssl.recv(6), b'during') sock2 = sock_ssl.unwrap() self.assertEqual(sock2.recv(5), b'after') sock2.close()
def get_socket(conf, default_port=61005): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get('bind_ip', '0.0.0.0'), int(conf.get('bind_port', default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None bind_timeout = int(conf.get('bind_timeout', 30)) so_rcvbuf = conf.get('so_rcvbuf', None) retry_until = time.time() + bind_timeout warn_ssl = False while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception( _('Could not bind to %s:%s ' 'after trying for %s seconds') % (bind_addr[0], bind_addr[1], bind_timeout)) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) if so_rcvbuf: sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, int(so_rcvbuf)) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) if warn_ssl: ssl_warning_message = _('WARNING: SSL should only be enabled for ' 'testing purposes. Use external SSL ' 'termination for a production deployment.') get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def test_greensslobject(self): def serve(listener): sock, addr = listener.accept() sock.sendall(b'content') greenio.shutdown_safe(sock) sock.close() listener = listen_ssl_socket() eventlet.spawn(serve, listener) client = ssl.wrap_socket(eventlet.connect(listener.getsockname())) self.assertEqual(client.recv(1024), b'content') self.assertEqual(client.recv(1024), b'')
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False): warnings.warn( "eventlet.util.wrap_ssl is deprecated. " "Please use the eventlet.green.ssl.wrap_socket()", DeprecationWarning, stacklevel=2) return ssl.wrap_socket( sock, keyfile=private_key, certfile=certificate, server_side=server_side, )
def wrap_ssl(self): if self.ssl: # Wrapped already return False self._socket = self.socket self.socket = ssl.wrap_socket(self.socket) self.socket.do_handshake() self.ssl = True return True
def listen_ssl_socket(address=('localhost', 0), **kwargs): sock = ssl.wrap_socket( socket.socket(), tests.private_key_file, tests.certificate_file, server_side=True, **kwargs ) sock.bind(address) sock.listen(50) return sock
def test_greensslobject(self): def serve(listener): sock, addr = listener.accept() sock.write(b'content') greenio.shutdown_safe(sock) sock.close() listener = listen_ssl_socket(('', 0)) eventlet.spawn(serve, listener) client = ssl.wrap_socket( eventlet.connect(('localhost', listener.getsockname()[1]))) self.assertEqual(client.read(1024), b'content') self.assertEqual(client.read(1024), b'')
def _socket_bind(self): """Bind to socket on a host. From network config bind_host and bind_port will be used as the socket the WSGI server will be bound too. The method will attempt to bind to the socket for 30 seconds. If the socket is unusable after 30 seconds an exception is raised. :return sock: ``object`` """ tcp_listener = ( str(self.net_cfg.get('bind_host', '127.0.0.1')), int(self.net_cfg.get('bind_port', 8080)) ) self.log.debug(tcp_listener) wsgi_backlog = self.net_cfg.get('backlog', 128) if wsgi_backlog < 1: raise SystemExit('the backlog value must be >= 1') sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen( tcp_listener, family=socket.AF_INET, backlog=wsgi_backlog ) if self.ssl_cfg.get('use_ssl', False) is True: sock = wsgi_ssl.wrap_socket( sock, **self._ssl_kwargs() ) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise ewsgi.WSGIServerFailure( 'Not able to bind to socket %s %s' % tcp_listener ) retry_time_left = retry_until - time.time() self.log.warn( 'Waiting for socket to become available... Time available' ' for retry %s', int(retry_time_left) ) eventlet.sleep(1) else: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) return sock else: raise ewsgi.WSGIServerFailure('Socket Bind Failure.')
def wrap_ssl(sock): ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs)
def connect(self): # pylint: disable=no-member if self.ssl is True: self.socket = ssl.wrap_socket(self.socket) elif isinstance(self.ssl, ssl.SSLContext): self.socket = self.ssl.wrap_socket(self.socket) elif self.ssl is not (None, False): raise TypeError("ssl must be an SSLContext, bool, or None") self.socket.settimeout(self.kwargs.get("socket_timeout", 10)) self.socket.connect((self.server, self.port)) super().connect()
def get_socket(conf): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ try: bind_port = int(conf["bind_port"]) except (ValueError, KeyError, TypeError): raise ConfigFilePortError() bind_addr = (conf.get("bind_ip", "0.0.0.0"), bind_port) address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None bind_timeout = int(conf.get("bind_timeout", 30)) retry_until = time.time() + bind_timeout warn_ssl = False while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get("backlog", 4096)), family=address_family) if "cert_file" in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf["cert_file"], keyfile=conf["key_file"]) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception( _("Could not bind to %s:%s " "after trying for %s seconds") % (bind_addr[0], bind_addr[1], bind_timeout) ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, "TCP_KEEPIDLE"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) if warn_ssl: ssl_warning_message = _( "WARNING: SSL should only be enabled for " "testing purposes. Use external SSL " "termination for a production deployment." ) get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def create_connection(member): remote = None try: remote = socket.create_connection((member, 13001), 2) remote.settimeout(15) # TLS cert validation is custom and will not pass normal CA vetting # to override completely in the right place requires enormous effort, so just defer until after connect remote = ssl.wrap_socket(remote, cert_reqs=ssl.CERT_NONE, keyfile='/etc/confluent/privkey.pem', certfile='/etc/confluent/srvcert.pem') except Exception as e: return member, e return member, remote
def test_ssl_connect(self): def serve(listener): sock, addr = listener.accept() sock.recv(8192) sock = listen_ssl_socket() server_coro = eventlet.spawn(serve, sock) raw_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssl_client = ssl.wrap_socket(raw_client) ssl_client.connect(sock.getsockname()) ssl_client.sendall(b'abc') greenio.shutdown_safe(ssl_client) ssl_client.close() server_coro.wait()
def __init__(self, address, server): self.socket, address = address self.ip = address[0] self.server = server self.infos = [] self.gzip_enabled = False self.gzip_encode = False if self.server.certfile: from eventlet.green.ssl import wrap_socket self.socket = wrap_socket(self.socket, server_side=True, certfile=self.server.certfile, keyfile=self.server.keyfile) logging.info("%s connected" % (address, ))
def test_ssl_connect(self): def serve(listener): sock, addr = listener.accept() sock.read(8192) sock = listen_ssl_socket() server_coro = eventlet.spawn(serve, sock) raw_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssl_client = ssl.wrap_socket(raw_client) ssl_client.connect(('127.0.0.1', sock.getsockname()[1])) ssl_client.write(b'abc') greenio.shutdown_safe(ssl_client) ssl_client.close() server_coro.wait()
def test_duplex_response(self): def serve(listener): sock, addr = listener.accept() sock.recv(8192) sock.sendall(b'response') sock = listen_ssl_socket() server_coro = eventlet.spawn(serve, sock) client = ssl.wrap_socket(eventlet.connect(sock.getsockname())) client.sendall(b'line 1\r\nline 2\r\n\r\n') self.assertEqual(client.recv(8192), b'response') server_coro.wait()
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] conf.register_opts(socket_opts) cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1)
def connect_to_collective(cert, member): remote = socket.create_connection((member, 13001)) # TLS cert validation is custom and will not pass normal CA vetting # to override completely in the right place requires enormous effort, so just defer until after connect remote = ssl.wrap_socket(remote, cert_reqs=ssl.CERT_NONE, keyfile='/etc/confluent/privkey.pem', certfile='/etc/confluent/srvcert.pem') if cert: fprint = cert else: collent = cfm.get_collective_member_by_address(member) fprint = collent['fingerprint'] if not util.cert_matches(fprint, remote.getpeercert(binary_form=True)): # probably Janeway up to something raise Exception("Certificate mismatch in the collective") return remote
def __init__(self, address, server): self.socket, address = address self.ip = address[0] self.server = server self.infos = [] self.gzip_enabled = False self.gzip_encode = False if self.server.certfile: from eventlet.green.ssl import wrap_socket self.socket = wrap_socket( self.socket, server_side=True, certfile=self.server.certfile, keyfile=self.server.keyfile) logging.info("%s connected" % (address,))
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] conf.register_opts(socket_opts) cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _( "When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file" ) ) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1)
def ssl_wrap_socket(sock): """ Wrap an existing socket in SSL :param sock: non-SSL socket to wrap :returns: An SSL wrapped socket """ utils.validate_key_cert(CONF.key_file, CONF.cert_file) ssl_kwargs = {"server_side": True, "certfile": CONF.cert_file, "keyfile": CONF.key_file, "cert_reqs": ssl.CERT_NONE} if CONF.ca_file: ssl_kwargs["ca_certs"] = CONF.ca_file ssl_kwargs["cert_reqs"] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs)
def _tlsstartup(cnn): authname = None cert = None if libssl: # most fully featured SSL function ctx = libssl.Context(libssl.SSLv23_METHOD) ctx.set_options(libssl.OP_NO_SSLv2 | libssl.OP_NO_SSLv3 | libssl.OP_NO_TLSv1 | libssl.OP_NO_TLSv1_1 | libssl.OP_CIPHER_SERVER_PREFERENCE) ctx.set_cipher_list( 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:' 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384') ctx.set_tmp_ecdh(crypto.get_elliptic_curve('secp384r1')) ctx.use_certificate_file('/etc/confluent/srvcert.pem') ctx.use_privatekey_file('/etc/confluent/privkey.pem') ctx.set_verify(libssln.VERIFY_PEER, lambda *args: True) libssln._lib.SSL_CTX_set_cert_verify_callback(ctx._context, verify_stub, ffi.NULL) cnn = libssl.Connection(ctx, cnn) cnn.set_accept_state() cnn.do_handshake() cert = cnn.get_peer_certificate() else: try: # Try relatively newer python TLS function ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ctx.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ctx.options |= ssl.OP_CIPHER_SERVER_PREFERENCE ctx.set_ciphers( 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:' 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384') ctx.load_cert_chain('/etc/confluent/srvcert.pem', '/etc/confluent/privkey.pem') cnn = ctx.wrap_socket(cnn, server_side=True) except AttributeError: # Python 2.6 era, go with best effort cnn = ssl.wrap_socket(cnn, keyfile="/etc/confluent/privkey.pem", certfile="/etc/confluent/srvcert.pem", ssl_version=ssl.PROTOCOL_TLSv1, server_side=True) sessionhdl(cnn, authname, cert=cert)