[PYTHON-CRYPTO] m2crypto blocking all other threads

Thomas D. Uram turam at MCS.ANL.GOV
Fri Sep 23 19:29:21 CEST 2005


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 <heikki at OSAFOUNDATION.ORG> 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 at GLIBC_2.0 () from /lib/tls/libpthread.so.0
> (gdb) where
> #0  0x00dbdb4a in sem_post at 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 at 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
> 
> 



More information about the python-crypto mailing list