An Workaround for ‘sslwrap’ Problem in event


Currently I have update the python to 2.7.9. Everything seems ok until I found that GoAgent couldn’t work properly.

After checking the GoAgent log file, I found that it kept complaining the ‘missing module sslwrap’ issue:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
    result = self._run(*self.args, **self.kwargs)
  File "/Users/rex/CS/repos/goagent/local/proxylib.py", line 1777, in create_connection
    ssl_sock.connect(ipaddr)
  File "/usr/local/lib/python2.7/site-packages/gevent/ssl.py", line 330, in connect
    self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile,
AttributeError: 'module' object has no attribute 'sslwrap'
<Greenlet at 0x104a23190: create_connection(('64.233.178.83', 443), 4, <Queue.Queue instance at 0x10429c128>)> failed with AttributeError

After somewhile of googling, I figured out that the python 2.7.9 had removed the ‘sslwrap’ function. Then I tried to update gevent to the latest version(from github gevent) but without luck.

Finally I found a solution from gevent issue 447. The solution from Eugeny works for me:

# Re-add sslwrap to Python 2.7.9
import inspect
__ssl__ = __import__('ssl')

try:
    _ssl = __ssl__._ssl
except AttributeError:
    _ssl = __ssl__._ssl2


def new_sslwrap(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=__ssl__.CERT_NONE, ssl_version=__ssl__.PROTOCOL_SSLv23, ca_certs=None, ciphers=None):
    context = __ssl__.SSLContext(ssl_version)
    context.verify_mode = cert_reqs or __ssl__.CERT_NONE
    if ca_certs:
        context.load_verify_locations(ca_certs)
    if certfile:
        context.load_cert_chain(certfile, keyfile)
    if ciphers:
        context.set_ciphers(ciphers)

    caller_self = inspect.currentframe().f_back.f_locals['self']
    return context._wrap_socket(sock, server_side=server_side, ssl_sock=caller_self)

if not hasattr(_ssl, 'sslwrap'):
    _ssl.sslwrap = new_sslwrap

Here’s the patch to gevent-1.0.1:

--- old_ssl.py  2015-03-13 05:44:39.000000000 +0800
+++ /usr/local/lib/python2.7/site-packages/gevent/ssl.py        2015-03-13 05:44:24.000000000 +0800
@@ -19,6 +19,25 @@
 except AttributeError:
     _ssl = __ssl__._ssl2

+import inspect
+
+
+def new_sslwrap(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=__ssl__.CERT_NONE, ssl_version=__ssl__.PROTOCOL_SSLv23, ca_certs=None, ciphers=None):
+    context = __ssl__.SSLContext(ssl_version)
+    context.verify_mode = cert_reqs or __ssl__.CERT_NONE
+    if ca_certs:
+        context.load_verify_locations(ca_certs)
+    if certfile:
+        context.load_cert_chain(certfile, keyfile)
+    if ciphers:
+        context.set_ciphers(ciphers)
+
+    caller_self = inspect.currentframe().f_back.f_locals['self']
+    return context._wrap_socket(sock, server_side=server_side, ssl_sock=caller_self)
+
+if not hasattr(_ssl, 'sslwrap'):
+    _ssl.sslwrap = new_sslwrap
+
 import sys
 import errno
 from gevent.socket import socket, _fileobject, timeout_default

And here’s the patch to gevent-1.1(latest version from github):

--- _ssl2.py    2015-03-13 05:53:31.000000000 +0800
+++ /usr/local/lib/python2.7/site-packages/gevent/_ssl2.py      2015-03-13 06:15:42.000000000 +0800
@@ -15,6 +15,24 @@
 except AttributeError:
     _ssl = __ssl__._ssl2

+import inspect
+
+def new_sslwrap(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=__ssl__.CERT_NONE, ssl_version=__ssl__.PROTOCOL_SSLv23, ca_certs=None, ciphers=None):
+    context = __ssl__.SSLContext(ssl_version)
+    context.verify_mode = cert_reqs or __ssl__.CERT_NONE
+    if ca_certs:
+        context.load_verify_locations(ca_certs)
+    if certfile:
+        context.load_cert_chain(certfile, keyfile)
+    if ciphers:
+        context.set_ciphers(ciphers)
+
+    caller_self = inspect.currentframe().f_back.f_locals['self']
+    return context._wrap_socket(sock, server_side=server_side, ssl_sock=caller_self)
+
+if not hasattr(_ssl, 'sslwrap'):
+    _ssl.sslwrap = new_sslwrap
+
 import sys
 import errno
 from gevent.socket import socket, _fileobject, timeout_default

Note that the two patches are almost identified except the files to patch are different.

Author: Rex Shen

Created: 2015-03-13 Fri 06:20

Emacs 24.4.1 (Org mode 8.2.10)

Leave a comment

Your email address will not be published. Required fields are marked *