Moved GreenSSLObject into eventlet.green.socket, cleaned up imports slightly, removed PyOpenSSL dependency -- it will warn you if you need to install it.
This commit is contained in:
@@ -9,10 +9,8 @@ except AttributeError:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
from eventlet.api import get_hub
|
from eventlet.api import get_hub
|
||||||
from eventlet.util import wrap_ssl_obj
|
|
||||||
from eventlet.greenio import GreenSocket as socket
|
from eventlet.greenio import GreenSocket as socket
|
||||||
from eventlet.greenio import GreenSSL as _GreenSSL
|
from eventlet.greenio import SSL as _SSL
|
||||||
from eventlet.greenio import GreenSSLObject as _GreenSSLObject
|
|
||||||
|
|
||||||
def fromfd(*args):
|
def fromfd(*args):
|
||||||
return socket(__socket.fromfd(*args))
|
return socket(__socket.fromfd(*args))
|
||||||
@@ -78,5 +76,73 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
|||||||
raise error, msg
|
raise error, msg
|
||||||
|
|
||||||
|
|
||||||
def ssl(sock, certificate=None, private_key=None):
|
def _convert_to_sslerror(ex):
|
||||||
return wrap_ssl_obj(sock, certificate, private_key)
|
""" Transliterates SSL.SysCallErrors to socket.sslerrors"""
|
||||||
|
return socket.sslerror((ex[0], ex[1]))
|
||||||
|
|
||||||
|
|
||||||
|
class GreenSSLObject(object):
|
||||||
|
""" Wrapper object around the SSLObjects returned by socket.ssl, which have a
|
||||||
|
slightly different interface from SSL.Connection objects. """
|
||||||
|
def __init__(self, green_ssl_obj):
|
||||||
|
""" Should only be called by a 'green' socket.ssl """
|
||||||
|
self.connection = green_ssl_obj
|
||||||
|
try:
|
||||||
|
# if it's already connected, do the handshake
|
||||||
|
self.connection.getpeername()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
self.connection.do_handshake()
|
||||||
|
except _SSL.SysCallError, e:
|
||||||
|
raise _convert_to_sslerror(e)
|
||||||
|
|
||||||
|
def read(self, n=None):
|
||||||
|
"""If n is provided, read n bytes from the SSL connection, otherwise read
|
||||||
|
until EOF. The return value is a string of the bytes read."""
|
||||||
|
if n is None:
|
||||||
|
# don't support this until someone needs it
|
||||||
|
raise NotImplementedError("GreenSSLObject does not support "\
|
||||||
|
" unlimited reads until we hear of someone needing to use them.")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return self.connection.read(n)
|
||||||
|
except _SSL.ZeroReturnError:
|
||||||
|
return ''
|
||||||
|
except _SSL.SysCallError, e:
|
||||||
|
raise _convert_to_sslerror(e)
|
||||||
|
|
||||||
|
def write(self, s):
|
||||||
|
"""Writes the string s to the on the object's SSL connection.
|
||||||
|
The return value is the number of bytes written. """
|
||||||
|
try:
|
||||||
|
return self.connection.write(s)
|
||||||
|
except _SSL.SysCallError, e:
|
||||||
|
raise _convert_to_sslerror(e)
|
||||||
|
|
||||||
|
def server(self):
|
||||||
|
""" Returns a string describing the server's certificate. Useful for debugging
|
||||||
|
purposes; do not parse the content of this string because its format can't be
|
||||||
|
parsed unambiguously. """
|
||||||
|
return str(self.connection.get_peer_certificate().get_subject())
|
||||||
|
|
||||||
|
def issuer(self):
|
||||||
|
"""Returns a string describing the issuer of the server's certificate. Useful
|
||||||
|
for debugging purposes; do not parse the content of this string because its
|
||||||
|
format can't be parsed unambiguously."""
|
||||||
|
return str(self.connection.get_peer_certificate().get_issuer())
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from eventlet.green import ssl
|
||||||
|
def ssl(sock, certificate=None, private_key=None):
|
||||||
|
warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
|
return ssl.sslwrap_simple(sock, keyfile, certfile)
|
||||||
|
except ImportError:
|
||||||
|
def ssl(sock, certificate=None, private_key=None):
|
||||||
|
from eventlet import util
|
||||||
|
wrapped = util.wrap_ssl(sock, certificate, private_key)
|
||||||
|
return GreenSSLObject(wrapped)
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ import time
|
|||||||
|
|
||||||
from eventlet.api import trampoline, getcurrent
|
from eventlet.api import trampoline, getcurrent
|
||||||
from thread import get_ident
|
from thread import get_ident
|
||||||
from eventlet.greenio import set_nonblocking, GreenSocket, GreenSSLObject, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
from eventlet.greenio import set_nonblocking, GreenSocket, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
||||||
orig_socket = __import__('socket')
|
orig_socket = __import__('socket')
|
||||||
socket = orig_socket.socket
|
socket = orig_socket.socket
|
||||||
|
|
||||||
@@ -290,6 +290,7 @@ def sslwrap_simple(sock, keyfile=None, certfile=None):
|
|||||||
"""A replacement for the old socket.ssl function. Designed
|
"""A replacement for the old socket.ssl function. Designed
|
||||||
for compability with Python 2.5 and earlier. Will disappear in
|
for compability with Python 2.5 and earlier. Will disappear in
|
||||||
Python 3.0."""
|
Python 3.0."""
|
||||||
|
from eventlet.green.socket import GreenSSLObject
|
||||||
ssl_sock = GreenSSLSocket(sock, 0, keyfile, certfile, CERT_NONE,
|
ssl_sock = GreenSSLSocket(sock, 0, keyfile, certfile, CERT_NONE,
|
||||||
PROTOCOL_SSLv23, None)
|
PROTOCOL_SSLv23, None)
|
||||||
return GreenSSLObject(ssl_sock)
|
return GreenSSLObject(ssl_sock)
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
from eventlet.api import trampoline, get_hub
|
from eventlet.api import trampoline, get_hub
|
||||||
from eventlet import util
|
|
||||||
|
|
||||||
|
|
||||||
BUFFER_SIZE = 4096
|
BUFFER_SIZE = 4096
|
||||||
|
|
||||||
@@ -712,67 +710,3 @@ def shutdown_safe(sock):
|
|||||||
if e[0] != errno.ENOTCONN:
|
if e[0] != errno.ENOTCONN:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def _convert_to_sslerror(ex):
|
|
||||||
""" Transliterates SSL.SysCallErrors to socket.sslerrors"""
|
|
||||||
return socket.sslerror((ex[0], ex[1]))
|
|
||||||
|
|
||||||
|
|
||||||
class GreenSSLObject(object):
|
|
||||||
""" Wrapper object around the SSLObjects returned by socket.ssl, which have a
|
|
||||||
slightly different interface from SSL.Connection objects. """
|
|
||||||
def __init__(self, green_ssl_obj):
|
|
||||||
""" Should only be called by a 'green' socket.ssl """
|
|
||||||
try:
|
|
||||||
from eventlet.green.ssl import GreenSSLSocket
|
|
||||||
except ImportError:
|
|
||||||
class GreenSSLSocket(object):
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert isinstance(green_ssl_obj, (GreenSSL, GreenSSLSocket))
|
|
||||||
self.connection = green_ssl_obj
|
|
||||||
try:
|
|
||||||
# if it's already connected, do the handshake
|
|
||||||
self.connection.getpeername()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
self.connection.do_handshake()
|
|
||||||
except SSL.SysCallError, e:
|
|
||||||
raise _convert_to_sslerror(e)
|
|
||||||
|
|
||||||
def read(self, n=None):
|
|
||||||
"""If n is provided, read n bytes from the SSL connection, otherwise read
|
|
||||||
until EOF. The return value is a string of the bytes read."""
|
|
||||||
if n is None:
|
|
||||||
# don't support this until someone needs it
|
|
||||||
raise NotImplementedError("GreenSSLObject does not support "\
|
|
||||||
" unlimited reads until we hear of someone needing to use them.")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
return self.connection.read(n)
|
|
||||||
except SSL.ZeroReturnError:
|
|
||||||
return ''
|
|
||||||
except SSL.SysCallError, e:
|
|
||||||
raise _convert_to_sslerror(e)
|
|
||||||
|
|
||||||
def write(self, s):
|
|
||||||
"""Writes the string s to the on the object's SSL connection.
|
|
||||||
The return value is the number of bytes written. """
|
|
||||||
try:
|
|
||||||
return self.connection.write(s)
|
|
||||||
except SSL.SysCallError, e:
|
|
||||||
raise _convert_to_sslerror(e)
|
|
||||||
|
|
||||||
def server(self):
|
|
||||||
""" Returns a string describing the server's certificate. Useful for debugging
|
|
||||||
purposes; do not parse the content of this string because its format can't be
|
|
||||||
parsed unambiguously. """
|
|
||||||
return str(self.connection.get_peer_certificate().get_subject())
|
|
||||||
|
|
||||||
def issuer(self):
|
|
||||||
"""Returns a string describing the issuer of the server's certificate. Useful
|
|
||||||
for debugging purposes; do not parse the content of this string because its
|
|
||||||
format can't be parsed unambiguously."""
|
|
||||||
return str(self.connection.get_peer_certificate().get_issuer())
|
|
||||||
|
@@ -3,6 +3,8 @@ import select
|
|||||||
import socket
|
import socket
|
||||||
import errno
|
import errno
|
||||||
|
|
||||||
|
from eventlet import greenio
|
||||||
|
|
||||||
def g_log(*args):
|
def g_log(*args):
|
||||||
import sys
|
import sys
|
||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
@@ -37,27 +39,21 @@ def tcp_socket():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# if ssl is available, use eventlet.green.ssl for our ssl implementation
|
# if ssl is available, use eventlet.green.ssl for our ssl implementation
|
||||||
import ssl as _ssl
|
from eventlet.green import ssl
|
||||||
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||||
from eventlet.green import ssl
|
|
||||||
return ssl.wrap_socket(sock,
|
return ssl.wrap_socket(sock,
|
||||||
keyfile=private_key, certfile=certificate,
|
keyfile=private_key, certfile=certificate,
|
||||||
server_side=server_side, cert_reqs=ssl.CERT_NONE,
|
server_side=server_side, cert_reqs=ssl.CERT_NONE,
|
||||||
ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=None,
|
ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=None,
|
||||||
do_handshake_on_connect=True,
|
do_handshake_on_connect=True,
|
||||||
suppress_ragged_eofs=True)
|
suppress_ragged_eofs=True)
|
||||||
|
|
||||||
def wrap_ssl_obj(sock, certificate=None, private_key=None):
|
|
||||||
from eventlet import ssl
|
|
||||||
warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.",
|
|
||||||
DeprecationWarning, stacklevel=2)
|
|
||||||
return ssl.sslwrap_simple(sock, keyfile, certfile)
|
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# if ssl is not available, use PyOpenSSL
|
# if ssl is not available, use PyOpenSSL
|
||||||
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||||
from OpenSSL import SSL
|
try:
|
||||||
from eventlet import greenio
|
from OpenSSL import SSL
|
||||||
|
except ImportError:
|
||||||
|
raise ImportError("To use SSL with Eventlet, you must install PyOpenSSL or use Python 2.6 or later.")
|
||||||
context = SSL.Context(SSL.SSLv23_METHOD)
|
context = SSL.Context(SSL.SSLv23_METHOD)
|
||||||
if certificate is not None:
|
if certificate is not None:
|
||||||
context.use_certificate_file(certificate)
|
context.use_certificate_file(certificate)
|
||||||
@@ -72,25 +68,15 @@ except ImportError:
|
|||||||
connection.set_connect_state()
|
connection.set_connect_state()
|
||||||
return greenio.GreenSSL(connection)
|
return greenio.GreenSSL(connection)
|
||||||
|
|
||||||
def wrap_ssl_obj(sock, certificate=None, private_key=None):
|
|
||||||
""" For 100% compatibility with the socket module, this wraps and handshakes an
|
|
||||||
open connection, returning a SSLObject."""
|
|
||||||
from eventlet import greenio
|
|
||||||
wrapped = wrap_ssl(sock, certificate, private_key)
|
|
||||||
return greenio.GreenSSLObject(wrapped)
|
|
||||||
|
|
||||||
socket_already_wrapped = False
|
socket_already_wrapped = False
|
||||||
def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
||||||
global socket_already_wrapped
|
global socket_already_wrapped
|
||||||
if socket_already_wrapped:
|
if socket_already_wrapped:
|
||||||
return
|
return
|
||||||
|
|
||||||
def new_socket(*args, **kw):
|
import eventlet.green.socket
|
||||||
from eventlet import greenio
|
socket.socket = eventlet.green.socket.socket
|
||||||
return greenio.GreenSocket(__original_socket__(*args, **kw))
|
socket.ssl = eventlet.green.socket.ssl
|
||||||
socket.socket = new_socket
|
|
||||||
|
|
||||||
socket.ssl = wrap_ssl_obj
|
|
||||||
try:
|
try:
|
||||||
import ssl as _ssl
|
import ssl as _ssl
|
||||||
from eventlet.green import ssl
|
from eventlet.green import ssl
|
||||||
@@ -115,7 +101,6 @@ def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
|||||||
|
|
||||||
if __original_fromfd__ is not None:
|
if __original_fromfd__ is not None:
|
||||||
def new_fromfd(*args, **kw):
|
def new_fromfd(*args, **kw):
|
||||||
from eventlet import greenio
|
|
||||||
return greenio.GreenSocket(__original_fromfd__(*args, **kw))
|
return greenio.GreenSocket(__original_fromfd__(*args, **kw))
|
||||||
socket.fromfd = new_fromfd
|
socket.fromfd = new_fromfd
|
||||||
|
|
||||||
@@ -136,7 +121,6 @@ def wrap_pipes_with_coroutine_pipes():
|
|||||||
if pipes_already_wrapped:
|
if pipes_already_wrapped:
|
||||||
return
|
return
|
||||||
def new_fdopen(*args, **kw):
|
def new_fdopen(*args, **kw):
|
||||||
from eventlet import greenio
|
|
||||||
return greenio.GreenPipe(__original_fdopen__(*args, **kw))
|
return greenio.GreenPipe(__original_fdopen__(*args, **kw))
|
||||||
def new_read(fd, *args, **kw):
|
def new_read(fd, *args, **kw):
|
||||||
from eventlet import api
|
from eventlet import api
|
||||||
|
3
setup.py
3
setup.py
@@ -6,8 +6,7 @@ from eventlet import __version__
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
requirements = []
|
requirements = []
|
||||||
for flag, req in [('--without-greenlet','greenlet >= 0.2'),
|
for flag, req in [('--without-greenlet','greenlet >= 0.2')]:
|
||||||
('--without-pyopenssl', 'pyopenssl')]:
|
|
||||||
if flag in sys.argv:
|
if flag in sys.argv:
|
||||||
sys.argv.remove(flag)
|
sys.argv.remove(flag)
|
||||||
else:
|
else:
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from tests import skipped, LimitedTestCase, skip_with_libevent, TestIsTakingTooLong
|
from tests import skipped, LimitedTestCase, skip_with_libevent, TestIsTakingTooLong
|
||||||
from unittest import main
|
from unittest import main
|
||||||
from eventlet import api, util, coros, proc, greenio
|
from eventlet import api, util, coros, proc, greenio
|
||||||
|
from eventlet.green.socket import GreenSSLObject
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
@@ -282,7 +283,7 @@ class SSLTest(LimitedTestCase):
|
|||||||
self.private_key_file)
|
self.private_key_file)
|
||||||
killer = api.spawn(serve, listener)
|
killer = api.spawn(serve, listener)
|
||||||
client = util.wrap_ssl(api.connect_tcp(('localhost', listener.getsockname()[1])))
|
client = util.wrap_ssl(api.connect_tcp(('localhost', listener.getsockname()[1])))
|
||||||
client = greenio.GreenSSLObject(client)
|
client = GreenSSLObject(client)
|
||||||
self.assertEquals(client.read(1024), 'content')
|
self.assertEquals(client.read(1024), 'content')
|
||||||
self.assertEquals(client.read(1024), '')
|
self.assertEquals(client.read(1024), '')
|
||||||
|
|
||||||
@@ -290,7 +291,10 @@ class SSLTest(LimitedTestCase):
|
|||||||
def serve(listener):
|
def serve(listener):
|
||||||
sock, addr = listener.accept()
|
sock, addr = listener.accept()
|
||||||
stuff = sock.read(8192)
|
stuff = sock.read(8192)
|
||||||
empt = sock.read(8192)
|
try:
|
||||||
|
self.assertEquals("", sock.read(8192))
|
||||||
|
except greenio.SSL.ZeroReturnError:
|
||||||
|
pass
|
||||||
|
|
||||||
sock = api.ssl_listener(('127.0.0.1', 0), self.certificate_file, self.private_key_file)
|
sock = api.ssl_listener(('127.0.0.1', 0), self.certificate_file, self.private_key_file)
|
||||||
server_coro = coros.execute(serve, sock)
|
server_coro = coros.execute(serve, sock)
|
||||||
|
Reference in New Issue
Block a user