Show More
@@ -12,6 +12,7 b' import hashlib' | |||||
12 | import os |
|
12 | import os | |
13 | import re |
|
13 | import re | |
14 | import ssl |
|
14 | import ssl | |
|
15 | import warnings | |||
15 |
|
16 | |||
16 | from .i18n import _ |
|
17 | from .i18n import _ | |
17 | from .pycompat import getattr |
|
18 | from .pycompat import getattr | |
@@ -308,12 +309,43 b' def wrapsocket(sock, keyfile, certfile, ' | |||||
308 | # bundle with a specific CA cert removed. If the system/default CA bundle |
|
309 | # bundle with a specific CA cert removed. If the system/default CA bundle | |
309 | # is loaded and contains that removed CA, you've just undone the user's |
|
310 | # is loaded and contains that removed CA, you've just undone the user's | |
310 | # choice. |
|
311 | # choice. | |
311 | # |
|
312 | ||
312 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both |
|
313 | if util.safehasattr(ssl, 'PROTOCOL_TLS_CLIENT'): | |
313 | # ends support, including TLS protocols. commonssloptions() restricts the |
|
314 | # python 3.7+ | |
314 | # set of allowed protocols. |
|
315 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | |
315 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) |
|
316 | minimumprotocol = settings[b'minimumprotocol'] | |
316 | sslcontext.options |= commonssloptions(settings[b'minimumprotocol']) |
|
317 | if minimumprotocol == b'tls1.0': | |
|
318 | with warnings.catch_warnings(): | |||
|
319 | warnings.filterwarnings( | |||
|
320 | 'ignore', | |||
|
321 | 'ssl.TLSVersion.TLSv1 is deprecated', | |||
|
322 | DeprecationWarning, | |||
|
323 | ) | |||
|
324 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1 | |||
|
325 | elif minimumprotocol == b'tls1.1': | |||
|
326 | with warnings.catch_warnings(): | |||
|
327 | warnings.filterwarnings( | |||
|
328 | 'ignore', | |||
|
329 | 'ssl.TLSVersion.TLSv1_1 is deprecated', | |||
|
330 | DeprecationWarning, | |||
|
331 | ) | |||
|
332 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1_1 | |||
|
333 | elif minimumprotocol == b'tls1.2': | |||
|
334 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1_2 | |||
|
335 | else: | |||
|
336 | raise error.Abort(_(b'this should not happen')) | |||
|
337 | # Prevent CRIME. | |||
|
338 | # There is no guarantee this attribute is defined on the module. | |||
|
339 | sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) | |||
|
340 | else: | |||
|
341 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both | |||
|
342 | # ends support, including TLS protocols. commonssloptions() restricts the | |||
|
343 | # set of allowed protocols. | |||
|
344 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | |||
|
345 | sslcontext.options |= commonssloptions(settings[b'minimumprotocol']) | |||
|
346 | ||||
|
347 | # We check the hostname ourselves in _verifycert | |||
|
348 | sslcontext.check_hostname = False | |||
317 | sslcontext.verify_mode = settings[b'verifymode'] |
|
349 | sslcontext.verify_mode = settings[b'verifymode'] | |
318 |
|
350 | |||
319 | if settings[b'ciphers']: |
|
351 | if settings[b'ciphers']: | |
@@ -509,37 +541,77 b' def wrapserversocket(' | |||||
509 | _(b'referenced certificate file (%s) does not exist') % f |
|
541 | _(b'referenced certificate file (%s) does not exist') % f | |
510 | ) |
|
542 | ) | |
511 |
|
543 | |||
512 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both |
|
544 | if util.safehasattr(ssl, 'PROTOCOL_TLS_SERVER'): | |
513 | # ends support, including TLS protocols. commonssloptions() restricts the |
|
545 | # python 3.7+ | |
514 | # set of allowed protocols. |
|
546 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) | |
515 | protocol = ssl.PROTOCOL_SSLv23 |
|
547 | sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) | |
516 | options = commonssloptions(b'tls1.0') |
|
|||
517 |
|
548 | |||
518 | # This config option is intended for use in tests only. It is a giant |
|
549 | # This config option is intended for use in tests only. It is a giant | |
519 | # footgun to kill security. Don't define it. |
|
550 | # footgun to kill security. Don't define it. | |
520 | exactprotocol = ui.config(b'devel', b'serverexactprotocol') |
|
551 | exactprotocol = ui.config(b'devel', b'serverexactprotocol') | |
521 | if exactprotocol == b'tls1.0': |
|
552 | if exactprotocol == b'tls1.0': | |
522 | if b'tls1.0' not in supportedprotocols: |
|
553 | if b'tls1.0' not in supportedprotocols: | |
523 | raise error.Abort(_(b'TLS 1.0 not supported by this Python')) |
|
554 | raise error.Abort(_(b'TLS 1.0 not supported by this Python')) | |
524 | protocol = ssl.PROTOCOL_TLSv1 |
|
555 | with warnings.catch_warnings(): | |
525 | elif exactprotocol == b'tls1.1': |
|
556 | warnings.filterwarnings( | |
526 | if b'tls1.1' not in supportedprotocols: |
|
557 | 'ignore', | |
527 | raise error.Abort(_(b'TLS 1.1 not supported by this Python')) |
|
558 | 'ssl.TLSVersion.TLSv1 is deprecated', | |
528 | protocol = ssl.PROTOCOL_TLSv1_1 |
|
559 | DeprecationWarning, | |
529 | elif exactprotocol == b'tls1.2': |
|
560 | ) | |
530 | if b'tls1.2' not in supportedprotocols: |
|
561 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1 | |
531 | raise error.Abort(_(b'TLS 1.2 not supported by this Python')) |
|
562 | sslcontext.maximum_version = ssl.TLSVersion.TLSv1 | |
532 | protocol = ssl.PROTOCOL_TLSv1_2 |
|
563 | elif exactprotocol == b'tls1.1': | |
533 | elif exactprotocol: |
|
564 | if b'tls1.1' not in supportedprotocols: | |
534 | raise error.Abort( |
|
565 | raise error.Abort(_(b'TLS 1.1 not supported by this Python')) | |
535 | _(b'invalid value for serverexactprotocol: %s') % exactprotocol |
|
566 | with warnings.catch_warnings(): | |
536 | ) |
|
567 | warnings.filterwarnings( | |
|
568 | 'ignore', | |||
|
569 | 'ssl.TLSVersion.TLSv1_1 is deprecated', | |||
|
570 | DeprecationWarning, | |||
|
571 | ) | |||
|
572 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1_1 | |||
|
573 | sslcontext.maximum_version = ssl.TLSVersion.TLSv1_1 | |||
|
574 | elif exactprotocol == b'tls1.2': | |||
|
575 | if b'tls1.2' not in supportedprotocols: | |||
|
576 | raise error.Abort(_(b'TLS 1.2 not supported by this Python')) | |||
|
577 | sslcontext.minimum_version = ssl.TLSVersion.TLSv1_2 | |||
|
578 | sslcontext.maximum_version = ssl.TLSVersion.TLSv1_2 | |||
|
579 | elif exactprotocol: | |||
|
580 | raise error.Abort( | |||
|
581 | _(b'invalid value for serverexactprotocol: %s') % exactprotocol | |||
|
582 | ) | |||
|
583 | else: | |||
|
584 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both | |||
|
585 | # ends support, including TLS protocols. commonssloptions() restricts the | |||
|
586 | # set of allowed protocols. | |||
|
587 | protocol = ssl.PROTOCOL_SSLv23 | |||
|
588 | options = commonssloptions(b'tls1.0') | |||
537 |
|
589 | |||
538 | # We /could/ use create_default_context() here since it doesn't load |
|
590 | # This config option is intended for use in tests only. It is a giant | |
539 | # CAs when configured for client auth. However, it is hard-coded to |
|
591 | # footgun to kill security. Don't define it. | |
540 | # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
|
592 | exactprotocol = ui.config(b'devel', b'serverexactprotocol') | |
541 | sslcontext = ssl.SSLContext(protocol) |
|
593 | if exactprotocol == b'tls1.0': | |
542 | sslcontext.options |= options |
|
594 | if b'tls1.0' not in supportedprotocols: | |
|
595 | raise error.Abort(_(b'TLS 1.0 not supported by this Python')) | |||
|
596 | protocol = ssl.PROTOCOL_TLSv1 | |||
|
597 | elif exactprotocol == b'tls1.1': | |||
|
598 | if b'tls1.1' not in supportedprotocols: | |||
|
599 | raise error.Abort(_(b'TLS 1.1 not supported by this Python')) | |||
|
600 | protocol = ssl.PROTOCOL_TLSv1_1 | |||
|
601 | elif exactprotocol == b'tls1.2': | |||
|
602 | if b'tls1.2' not in supportedprotocols: | |||
|
603 | raise error.Abort(_(b'TLS 1.2 not supported by this Python')) | |||
|
604 | protocol = ssl.PROTOCOL_TLSv1_2 | |||
|
605 | elif exactprotocol: | |||
|
606 | raise error.Abort( | |||
|
607 | _(b'invalid value for serverexactprotocol: %s') % exactprotocol | |||
|
608 | ) | |||
|
609 | ||||
|
610 | # We /could/ use create_default_context() here since it doesn't load | |||
|
611 | # CAs when configured for client auth. However, it is hard-coded to | |||
|
612 | # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. | |||
|
613 | sslcontext = ssl.SSLContext(protocol) | |||
|
614 | sslcontext.options |= options | |||
543 |
|
615 | |||
544 | # Improve forward secrecy. |
|
616 | # Improve forward secrecy. | |
545 | sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
|
617 | sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
General Comments 0
You need to be logged in to leave comments.
Login now