Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#2765 closed bug (Fixed)

Add support for TLS SNI in httpdownloader

Reported by: Calum Owned by:
Priority: minor Milestone: 1.3.13
Component: Core Version: 1.3.11
Keywords: Cc:

Description

Sites that use cloudflare require TLSv1.2 and use SNI.

From forum: http://forum.deluge-torrent.org/viewtopic.php?f=7&p=218087#p218087

[DEBUG   ] 11:54:50 addtorrentdialog:715 Download failed: [Failure instance: Traceback: <class 'OpenSSL.SSL.Error'>: [('SSL routines', 'SSL23_GET_SERVER_HELLO', 'tlsv1 alert internal error')]
twisted/internet/selectreactor.py:149:_doReadOrWrite
twisted/internet/tcp.py:209:doRead
twisted/internet/tcp.py:215:_dataReceived
twisted/protocols/tls.py:415:dataReceived
--- <exception caught here> ---
twisted/protocols/tls.py:554:_write
OpenSSL/SSL.py:1271:send
OpenSSL/SSL.py:1187:_raise_ssl_error
OpenSSL/_util.py:48:exception_from_error_queue
]

As this is now supported in Twisted >= 14 we can add support.

To verify if this is the issue a simply test without the server name:

openssl s_client -connect www.seo.com:443
> ...
> 139785801238176:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:s23_clnt.c:770:
> ...

By adding the server name in the request it will now pass:

openssl s_client -connect www.seo.com:443 -servername seo.com

Change History (2)

comment:1 by Calum, 9 years ago

For reference here is the current working code:

  • deluge/httpdownloader.py

    diff --git a/deluge/httpdownloader.py b/deluge/httpdownloader.py
    index 14dcdc3..0b8d1af 100644
    a b def download_file(url, filename, callback=None, headers=None, force_filename=Fal  
    211211    factory = HTTPDownloader(url, filename, callback, headers, force_filename, allow_compression)
    212212    if scheme == "https":
    213213        from twisted.internet import ssl
    214         reactor.connectSSL(host, port, factory, ssl.ClientContextFactory())
     214        from twisted.internet._sslverify import ClientTLSOptions
     215
     216        class TLSSNIContextFactory(ssl.ClientContextFactory):
     217            def getContext(self, hostname=None, port=None):
     218                ctx = ssl.ClientContextFactory.getContext(self)
     219                ClientTLSOptions(host, ctx)
     220                return ctx
     221
     222        reactor.connectSSL(host, port, factory, TLSSNIContextFactory())
    215223    else:
    216224        reactor.connectTCP(host, port, factory)
    217225

comment:2 by Calum, 9 years ago

Resolution: Fixed
Status: newclosed

Fixed 1.3-stable: [697c22a46cfc]

Version 0, edited 9 years ago by Calum (next)
Note: See TracTickets for help on using tickets.