[Twisted-Python] Implementing STARTTLS in a protocol

Jean-Paul Calderone exarkun at divmod.com
Fri May 23 16:32:16 EDT 2008

On Fri, 23 May 2008 12:29:44 -0500, Kevin Horn <kevin.horn at gmail.com> wrote:
>Howdy list,
>I'm trying to implement a protocol using Twisted which has a "STARTTLS"
>command to switch the protocol from plain TCP to TCP over TLS.
>I've mostly been going by the way that the imap4.py module seems to do it,
>but I can't seem to get a handshake to complete.
>I found this page ( http://wiki.vislab.usyd.edu.au/moin.cgi/SSLCertNotes )
>which was helpful, but I don't want to force client cert authentication.
>In order to separate this problem from other issues, I've adapted the echo
>protocol code from above the above page to try and get a simple test case
>(my code below)
>I am recieving the following output and traceback when running the client
>code ( on both Windows and Linux ):
>using TLSv1:
>Sending: Hello, world!
>receive: ERROR: Must authenticate
>Sending: STARTTLS
>receive: READY
>Sending: Continuing
>connection lost (protocol)
>connection lost: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake
>failure'), ('SSL routines', 'SSL3_READ_BYTES', 'ssl handshake failure')]
>Traceback (most recent call last):
>  File "C:\Documents and
>line 58, in <module>
>    reactor.run()
>  File "C:\Python25\lib\site-packages\twisted\internet\posixbase.py", line
>223, in run
>    self.mainLoop()
>  File "C:\Python25\lib\site-packages\twisted\internet\posixbase.py", line
>234, in mainLoop
>    self.doIteration(t)
>  File "C:\Python25\lib\site-packages\twisted\internet\selectreactor.py",
>line 140, in doSelect
>    _logrun(selectable, _drdw, selectable, method, dict)
>--- <exception caught here> ---
>  File "C:\Python25\lib\site-packages\twisted\python\log.py", line 51, in
>    return callWithContext({"system": lp}, func, *args, **kw)
><< SNIP >>
>  File "C:\Python25\lib\site-packages\twisted\internet\base.py", line 490,
>in stop
>    "Can't stop reactor that isn't running.")
>twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't
>What am I doing wrong?  Is there a SSL config option I'm setting
>incorrectly?  Do I need to use a different SSL Context? Am I totally off

The traceback here is just because you're calling reactor.stop() twice,
once in Protocol.connectionLost, then again in Factory.clientConnectionLost.
Get rid of one of these and at least you'll get rid of some spurious noise.

As far as the TLS part of your code goes, it basically looks okay.  By doing
a sendLine immediately before you call startTLS, you risk running into #686,
but if you actually hit that, you should see a warning and the connection
should be closed without an OpenSSL error.

So I'm not exactly sure what problem you're encountering.  To further
complicate matters, when I run your code, TLS is successfully negotiated.


More information about the Twisted-Python mailing list