Re: m2crypto blocking all other threads
"Thomas D. Uram" <[email protected]>
| Newsgroups | gmane.comp.python.cryptography |
|---|---|
| Message-ID | <[email protected]> |
I recall seeing the problem with load_verify_locations when using swig 1.3.21; it was resolved when I switched to swig 1.3.24. There is apparently a difference in the stock typemaps between the two versions. > TypeError: ssl_ctx_load_verify_locations() argument 3 must be string, not None Tom Uram On 9/23/05 4:22 AM, Rune Froysa wrote: > Heikki Toivonen <[email protected]> writes: > > >>Rune Froysa wrote: >> >>>I'm using m2crypto for a SSL-based xmlrpc service. This service is >>>frequently DOSed by what appears to be a bug in m2crypto: it blocks >> >>It seems like this is user error. In a multithreaded application you >>need to initialize M2Crypto for threading. With those changes your >>sample works for me. See below: > > > Sorry about that. Is this documented some place? For some reason, > demo/ssl/https_srv.py works without it (two "openssl s_client -connect > localhost:19443" can connect simultaneously without problems). > However, a "telnet localhost 19443"+<do nothing> first will prevent > any later s_clients from reaching past the "CONNECTED(00000003)" > state. > > The threading.init() trick seems to work for my previous example, but > if I add a threading.init() to line 135 (first in __main__) of > demo/ssl/https_srv.py, i get a segfault when a client connects (python > 2.3.4) (It works if I actually have created a separate thread): > > Starting program: /usr/bin/python https_srv.py > [Thread debugging using libthread_db enabled] > [New Thread -1208785216 (LWP 12122)] > > Program received signal SIGSEGV, Segmentation fault. > [Switching to Thread -1208785216 (LWP 12122)] > 0x00dbdb4a in sem_post@GLIBC_2.0 () from /lib/tls/libpthread.so.0 > (gdb) where > #0 0x00dbdb4a in sem_post@GLIBC_2.0 () from /lib/tls/libpthread.so.0 > #1 0x080cf636 in PyThread_release_lock (lock=0x0) at Python/thread_pthread.h:431 > #2 0x080ca519 in PyGILState_Release (oldstate=3080343864) at Python/pystate.c:473 > #3 0xb7ad39e8 in ssl_info_callback (s=0x81ef058, where=16, ret=1) at SWIG/_m2crypto.c:1058 > #4 0x00b251e2 in ssl23_accept () from /lib/libssl.so.4 > #5 0x00b2a093 in SSL_accept () from /lib/libssl.so.4 > #6 0xb7ad73b3 in ssl_accept (ssl=0x81ef058) at SWIG/_m2crypto.c:3492 > #7 0xb7ae2d23 in _wrap_ssl_accept (self=0x0, args=0xb79b310c) at SWIG/_m2crypto.c:11191 > #8 0x080ed9b0 in PyCFunction_Call (func=0xb7b2218c, arg=0xb79b310c, kw=0x1) at Objects/methodobject.c:108 > #9 0x080a4f67 in call_function (pp_stack=0xbfffee9c, oparg=135426480) at Python/ceval.c:3439 > ... > > >>>BTW: under 0.15, the https_srv.py complains from line 126 -> SSL/Context.py: 118: >>>TypeError: ssl_ctx_load_verify_locations() argument 3 must be string, not None >> >>This does not happen for me. > > > Strange. Latest version from svn: > > /tmp/m2/demo/ssl@dresden >PYTHONPATH=/tmp/m2/build/lib.linux-i686-2.3 python https_srv.py > Traceback (most recent call last): > File "https_srv.py", line 141, in ? > SSL.verify_none) > File "https_srv.py", line 126, in init_context > ctx.load_verify_info(cafile) > File "/tmp/m2/build/lib.linux-i686-2.3/M2Crypto/SSL/Context.py", line 121, in load_verify_locations > return m2.ssl_ctx_load_verify_locations(self.ctx, cafile, capath) > TypeError: ssl_ctx_load_verify_locations() argument 3 must be string, not None > > It would be great if there was some way to set a timeout value on > connected clients. With the below patch, https_srv.py could > instantiate the HTTPS_Server with a default_timeout=SSL.timeout(sec=4) > keyword argument to kill misbehaving clients (like the telnet above). > Could something like this be considered for future inclusion? (I don't > believe there is a standard pythonic way of setting timeout on client > sockets): > > Index: M2Crypto/SSL/SSLServer.py > =================================================================== > --- M2Crypto/SSL/SSLServer.py (revision 319) > +++ M2Crypto/SSL/SSLServer.py (working copy) > @@ -12,7 +12,7 @@ > > > class SSLServer(SocketServer.TCPServer): > - def __init__(self, server_address, RequestHandlerClass, ssl_context): > + def __init__(self, server_address, RequestHandlerClass, ssl_context, default_timeout=None): > """ > Superclass says: Constructor. May be extended, do not override. > This class says: Ho-hum. > @@ -21,6 +21,8 @@ > self.RequestHandlerClass=RequestHandlerClass > self.ssl_ctx=ssl_context > self.socket=Connection(self.ssl_ctx) > + if default_timeout is not None: > + self.socket.set_default_client_timeout(default_timeout) > self.server_bind() > self.server_activate() > > Index: M2Crypto/SSL/Connection.py > =================================================================== > --- M2Crypto/SSL/Connection.py (revision 319) > +++ M2Crypto/SSL/Connection.py (working copy) > @@ -38,6 +38,7 @@ > 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._default_client_timeout = None > > def __del__(self): > if getattr(self, 'sslbio', None): > @@ -102,16 +103,27 @@ > def accept_ssl(self): > return m2.ssl_accept(self.ssl) > > + def set_default_client_timeout(self, timeout): > + self._default_client_timeout = timeout > + > def accept(self): > """Accept an SSL connection. The return value is a pair (ssl, addr) where > ssl is a new SSL connection object and addr is the address bound to the > the other end of the SSL connection.""" > sock, addr = self.socket.accept() > + if self._default_client_timeout is not None: > + sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, > + self._default_client_timeout.pack()) > + sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, > + self._default_client_timeout.pack()) > + > ssl = Connection(self.ctx, sock) > ssl.addr = addr > ssl.setup_ssl() > ssl.set_accept_state() > - ssl.accept_ssl() > + if ssl.accept_ssl() != 1: > + raise SSLError(m2.err_reason_error_string(m2.err_get_error())) > + > check = getattr(self, 'postConnectionCheck', self.serverPostConnectionCheck) > if check is not None: > if not check(self.get_peer_cert(), ssl.addr[0]): > > > Regards, > Rune Frøysa > >