Merge pull request #100 from gizmoguy/py3.7-tls

Workaround eventlet Python3.7 SSLContext wrap issue
This commit is contained in:
Brad Cowie 2020-06-12 16:27:57 +12:00 committed by GitHub
commit 861587c8ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 12 deletions

View File

@ -30,6 +30,7 @@ from socket import TCP_NODELAY
from socket import SHUT_WR
from socket import timeout as SocketTimeout
import ssl
import sys
from ryu import cfg
from ryu.lib import hub
@ -67,6 +68,7 @@ CONF.register_cli_opts([
cfg.StrOpt('ctl-privkey', default=None, help='controller private key'),
cfg.StrOpt('ctl-cert', default=None, help='controller certificate'),
cfg.StrOpt('ca-certs', default=None, help='CA certificates'),
cfg.StrOpt('ciphers', default=None, help='list of ciphers to enable'),
cfg.ListOpt('ofp-switch-address-list', item_type=str, default=[],
help='list of IP address and port pairs (default empty). '
'e.g., "127.0.0.1:6653,[::1]:6653"'),
@ -169,6 +171,12 @@ class OpenFlowController(object):
# anything less than python 2.7.9 supports only TLSv1
# or less, thus we choose TLSv1
ssl_args = {'ssl_version': ssl.PROTOCOL_TLSv1}
elif sys.version_info >= (3, 7,):
# On Python3.7+ we can't wrap an SSLContext due to this bug:
# https://github.com/eventlet/eventlet/issues/526
# Lets assume the system has a new enough OpenSSL that
# SSL is fully disabled.
ssl_args = {'ssl_version': ssl.PROTOCOL_TLSv1}
else:
# from 2.7.9 and versions 3.4+ ssl context creation is
# supported. Protocol_TLS from 2.7.13 and from 3.5.3
@ -182,6 +190,9 @@ class OpenFlowController(object):
# Restrict non-safe versions
ssl_args['ssl_ctx'].options |= ssl.OP_NO_SSLv3 | ssl.OP_NO_SSLv2
if CONF.ciphers is not None:
ssl_args['ciphers'] = CONF.ciphers
if CONF.ca_certs is not None:
server = StreamServer((CONF.ofp_listen_host,
ofp_ssl_listen_port),

View File

@ -127,21 +127,25 @@ if HUB_TYPE == 'eventlet':
self.server = eventlet.listen(listen_info)
if ssl_args:
def wrap_and_handle(sock, addr):
ssl_args.setdefault('server_side', True)
if 'ssl_ctx' in ssl_args:
ctx = ssl_args.pop('ssl_ctx')
ctx.load_cert_chain(ssl_args.pop('certfile'),
ssl_args.pop('keyfile'))
if 'cert_reqs' in ssl_args:
ctx.verify_mode = ssl_args.pop('cert_reqs')
if 'ca_certs' in ssl_args:
ctx.load_verify_locations(ssl_args.pop('ca_certs'))
ssl_args.setdefault('server_side', True)
if 'ssl_ctx' in ssl_args:
ctx = ssl_args.pop('ssl_ctx')
ctx.load_cert_chain(ssl_args.pop('certfile'),
ssl_args.pop('keyfile'))
if 'cert_reqs' in ssl_args:
ctx.verify_mode = ssl_args.pop('cert_reqs')
if 'ca_certs' in ssl_args:
ctx.load_verify_locations(ssl_args.pop('ca_certs'))
def wrap_and_handle_ctx(sock, addr):
handle(ctx.wrap_socket(sock, **ssl_args), addr)
else:
self.handle = wrap_and_handle_ctx
else:
def wrap_and_handle_ssl(sock, addr):
handle(ssl.wrap_socket(sock, **ssl_args), addr)
self.handle = wrap_and_handle
self.handle = wrap_and_handle_ssl
else:
self.handle = handle

View File

@ -191,6 +191,7 @@ class TestOpenFlowController(unittest.TestCase):
conf_mock.ofp_ssl_listen_port = port
conf_mock.ofp_listen_host = "127.0.0.1"
conf_mock.ca_certs = None
conf_mock.ciphers = None
conf_mock.ctl_cert = os.path.join(this_dir, 'cert.crt')
conf_mock.ctl_privkey = os.path.join(this_dir, 'cert.key')
c = controller.OpenFlowController()