|
| 1 | +import logging |
1 | 2 | from OpenSSL import SSL
|
2 | 3 |
|
3 | 4 |
|
| 5 | +logger = logging.getLogger(__name__) |
| 6 | + |
4 | 7 | METHOD_SSLv3 = 'SSLv3'
|
5 | 8 | METHOD_TLS = 'TLS'
|
6 | 9 | METHOD_TLSv10 = 'TLSv1.0'
|
|
14 | 17 | METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5), # TLS 1.1 only
|
15 | 18 | METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6), # TLS 1.2 only
|
16 | 19 | }
|
| 20 | + |
| 21 | +# ClientTLSOptions requires a recent-enough version of Twisted |
| 22 | +try: |
| 23 | + |
| 24 | + # taken from twisted/twisted/internet/_sslverify.py |
| 25 | + try: |
| 26 | + from OpenSSL.SSL import SSL_CB_HANDSHAKE_DONE, SSL_CB_HANDSHAKE_START |
| 27 | + except ImportError: |
| 28 | + SSL_CB_HANDSHAKE_START = 0x10 |
| 29 | + SSL_CB_HANDSHAKE_DONE = 0x20 |
| 30 | + |
| 31 | + from twisted.internet._sslverify import (ClientTLSOptions, |
| 32 | + _maybeSetHostNameIndication, |
| 33 | + verifyHostname, |
| 34 | + VerificationError) |
| 35 | + |
| 36 | + class ScrapyClientTLSOptions(ClientTLSOptions): |
| 37 | + # same as Twisted's ClientTLSOptions, |
| 38 | + # except that VerificationError is caught |
| 39 | + # and doesn't close the connection |
| 40 | + def _identityVerifyingInfoCallback(self, connection, where, ret): |
| 41 | + if where & SSL_CB_HANDSHAKE_START: |
| 42 | + _maybeSetHostNameIndication(connection, self._hostnameBytes) |
| 43 | + elif where & SSL_CB_HANDSHAKE_DONE: |
| 44 | + try: |
| 45 | + verifyHostname(connection, self._hostnameASCII) |
| 46 | + except VerificationError as e: |
| 47 | + logger.warning(e) |
| 48 | + |
| 49 | +except ImportError: |
| 50 | + # ImportError should not matter for older Twisted versions |
| 51 | + # as the above is not used in the fallback ScrapyClientContextFactory |
| 52 | + pass |
0 commit comments