annotate mercurial/sslutil.py @ 52291:b65085c6d6ff

help: modernize the help text for `hostsecurity.minimumprotocol` Two issues here: 1) We're well past Pythons that only support TLSv1.0 (py27 supports v1.2) 2) It never occurred to me that this is a client-only setting
author Matt Harbison <matt_harbison@yahoo.com>
date Mon, 11 Nov 2024 13:03:13 -0500
parents 323e3626929a
children 085cc409847d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
1 # sslutil.py - SSL handling for mercurial
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46786
diff changeset
3 # Copyright 2005, 2006, 2007, 2008 Olivia Mackall <olivia@selenic.com>
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
6 #
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
7 # This software may be used and distributed according to the terms of the
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8 # GNU General Public License version 2 or any later version.
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
9
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
10 from __future__ import annotations
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
11
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29334
diff changeset
12 import hashlib
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
13 import os
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
14 import re
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
15 import ssl
49054
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
16 import warnings
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
17
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
18 from .i18n import _
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
19 from .node import hex
28577
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
20 from . import (
42269
c8d55ff80da1 sslutil: add support for SSLKEYLOGFILE to wrapsocket
Augie Fackler <augie@google.com>
parents: 42263
diff changeset
21 encoding,
28577
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
22 error,
30639
d524c88511a7 py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
23 pycompat,
28577
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
24 util,
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
25 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
26 from .utils import (
44061
cbc5755df6bf sslutil: migrate to hashutil.sha1 instead of hashlib.sha1
Augie Fackler <augie@google.com>
parents: 43671
diff changeset
27 hashutil,
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43506
diff changeset
28 resourceutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
29 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
30 )
24291
760a86865f80 ssl: load CA certificates from system's store by default on Python 2.7.9
Yuya Nishihara <yuya@tcha.org>
parents: 24290
diff changeset
31
28647
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
32 # Python 2.7.9+ overhauled the built-in SSL/TLS features of Python. It added
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
33 # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
34 # all exposed via the "ssl" module.
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
35 #
44875
7c19eb372438 sslutil: remove code checking for presence of ssl.SSLContext
Manuel Jacob <me@manueljacob.de>
parents: 44873
diff changeset
36 # We require in setup.py the presence of ssl.SSLContext, which indicates modern
7c19eb372438 sslutil: remove code checking for presence of ssl.SSLContext
Manuel Jacob <me@manueljacob.de>
parents: 44873
diff changeset
37 # SSL/TLS support.
28647
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
38
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32273
diff changeset
39 configprotocols = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
40 b'tls1.0',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
41 b'tls1.1',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
42 b'tls1.2',
52289
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
43 b'tls1.3',
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32273
diff changeset
44 }
26622
9e15286609ae sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
45
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
46 hassni = getattr(ssl, 'HAS_SNI', False)
28648
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
47
44898
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
48 # ssl.HAS_TLSv1* are preferred to check support but they were added in Python
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
49 # 3.7. Prior to CPython commit 6e8cda91d92da72800d891b2fc2073ecbc134d98
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
50 # (backported to the 3.7 branch), ssl.PROTOCOL_TLSv1_1 / ssl.PROTOCOL_TLSv1_2
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
51 # were defined only if compiled against a OpenSSL version with TLS 1.1 / 1.2
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
52 # support. At the mentioned commit, they were unconditionally defined.
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
53 supportedprotocols = set()
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50602
diff changeset
54 if getattr(ssl, 'HAS_TLSv1', hasattr(ssl, 'PROTOCOL_TLSv1')):
44898
d61c05450b37 sslutil: properly detect which TLS versions are supported by the ssl module
Manuel Jacob <me@manueljacob.de>
parents: 44897
diff changeset
55 supportedprotocols.add(b'tls1.0')
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50602
diff changeset
56 if getattr(ssl, 'HAS_TLSv1_1', hasattr(ssl, 'PROTOCOL_TLSv1_1')):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 supportedprotocols.add(b'tls1.1')
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50602
diff changeset
58 if getattr(ssl, 'HAS_TLSv1_2', hasattr(ssl, 'PROTOCOL_TLSv1_2')):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
59 supportedprotocols.add(b'tls1.2')
52289
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
60 if getattr(ssl, 'HAS_TLSv1_3', False):
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
61 supportedprotocols.add(b'tls1.3')
29601
6cff2ac0ccb9 sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29578
diff changeset
62
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
63
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
64 def _hostsettings(ui, hostname):
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
65 """Obtain security settings for a hostname.
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
66
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
67 Returns a dict of settings relevant to that hostname.
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
68 """
36745
424994a0adfd sslutil: lots of unicode/bytes cleanup
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
69 bhostname = pycompat.bytesurl(hostname)
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
70 s = {
29288
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
71 # Whether we should attempt to load default/available CA certs
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
72 # if an explicit ``cafile`` is not defined.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
73 b'allowloaddefaultcerts': True,
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
74 # List of 2-tuple of (hash algorithm, hash).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
75 b'certfingerprints': [],
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
76 # Path to file containing concatenated CA certs. Used by
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
77 # SSLContext.load_verify_locations().
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
78 b'cafile': None,
29287
fbccb334efe7 sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29286
diff changeset
79 # Whether certificate verification should be disabled.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
80 b'disablecertverification': False,
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
81 # Whether the legacy [hostfingerprints] section has data for this host.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
82 b'legacyfingerprint': False,
29618
fbf4adc0d8f2 sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29617
diff changeset
83 # String representation of minimum protocol to be used for UI
fbf4adc0d8f2 sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29617
diff changeset
84 # presentation.
44899
4ca1110991c4 sslutil: rename 'minimumprotocolui' -> 'minimumprotocol'
Manuel Jacob <me@manueljacob.de>
parents: 44898
diff changeset
85 b'minimumprotocol': None,
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
86 # ssl.CERT_* constant used by SSLContext.verify_mode.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
87 b'verifymode': None,
29577
9654ef41f7cc sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29561
diff changeset
88 # OpenSSL Cipher List to use (instead of default).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
89 b'ciphers': None,
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
90 }
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
91
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
92 # Allow minimum TLS protocol to be specified in the config.
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
93 def validateprotocol(protocol, key):
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
94 if protocol not in configprotocols:
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
95 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
96 _(b'unsupported protocol from hostsecurity.%s: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
97 % (key, protocol),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
98 hint=_(b'valid protocols: %s')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
99 % b' '.join(sorted(configprotocols)),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
100 )
29507
97dcdcf75f4f sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29501
diff changeset
101
44895
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
102 # We default to TLS 1.1+ because TLS 1.0 has known vulnerabilities (like
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
103 # BEAST and POODLE). We allow users to downgrade to TLS 1.0+ via config
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
104 # options in case a legacy server is encountered.
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
105
44902
24d440e2fdbb sslutil: fix comment to use inclusive or instead of exclusive or
Manuel Jacob <me@manueljacob.de>
parents: 44901
diff changeset
106 # setup.py checks that TLS 1.1 or TLS 1.2 is present, so the following
24d440e2fdbb sslutil: fix comment to use inclusive or instead of exclusive or
Manuel Jacob <me@manueljacob.de>
parents: 44901
diff changeset
107 # assert should not fail.
44895
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
108 assert supportedprotocols - {b'tls1.0'}
5921dc0d5c3a sslutil: remove dead code (that downgraded default minimum TLS version)
Manuel Jacob <me@manueljacob.de>
parents: 44894
diff changeset
109 defaultminimumprotocol = b'tls1.1'
29560
303e9300772a sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29559
diff changeset
110
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
111 key = b'minimumprotocol'
44889
ceb7318013d5 sslutil: fix names of variables containing minimum protocol strings
Manuel Jacob <me@manueljacob.de>
parents: 44888
diff changeset
112 minimumprotocol = ui.config(b'hostsecurity', key, defaultminimumprotocol)
ceb7318013d5 sslutil: fix names of variables containing minimum protocol strings
Manuel Jacob <me@manueljacob.de>
parents: 44888
diff changeset
113 validateprotocol(minimumprotocol, key)
29508
d65ec41b6384 sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29507
diff changeset
114
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
115 key = b'%s:minimumprotocol' % bhostname
44889
ceb7318013d5 sslutil: fix names of variables containing minimum protocol strings
Manuel Jacob <me@manueljacob.de>
parents: 44888
diff changeset
116 minimumprotocol = ui.config(b'hostsecurity', key, minimumprotocol)
ceb7318013d5 sslutil: fix names of variables containing minimum protocol strings
Manuel Jacob <me@manueljacob.de>
parents: 44888
diff changeset
117 validateprotocol(minimumprotocol, key)
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
118
49055
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
119 ciphers = ui.config(b'hostsecurity', b'ciphers')
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
120 ciphers = ui.config(b'hostsecurity', b'%s:ciphers' % bhostname, ciphers)
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
121
29617
2960ceee1948 sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29601
diff changeset
122 # If --insecure is used, we allow the use of TLS 1.0 despite config options.
2960ceee1948 sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29601
diff changeset
123 # We always print a "connection security to %s is disabled..." message when
2960ceee1948 sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29601
diff changeset
124 # --insecure is used. So no need to print anything more here.
2960ceee1948 sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29601
diff changeset
125 if ui.insecureconnections:
44889
ceb7318013d5 sslutil: fix names of variables containing minimum protocol strings
Manuel Jacob <me@manueljacob.de>
parents: 44888
diff changeset
126 minimumprotocol = b'tls1.0'
49055
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
127 if not ciphers:
50342
c54e9bb5737e sslutil: set context security level for legacy tls testing (issue6760)
pacien <pacien.trangirard@pacien.net>
parents: 50341
diff changeset
128 ciphers = b'DEFAULT:@SECLEVEL=0'
29558
a935cd7d51a6 sslutil: prevent CRIME
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29557
diff changeset
129
44899
4ca1110991c4 sslutil: rename 'minimumprotocolui' -> 'minimumprotocol'
Manuel Jacob <me@manueljacob.de>
parents: 44898
diff changeset
130 s[b'minimumprotocol'] = minimumprotocol
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
131 s[b'ciphers'] = ciphers
29577
9654ef41f7cc sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29561
diff changeset
132
29267
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
133 # Look for fingerprints in [hostsecurity] section. Value is a list
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
134 # of <alg>:<fingerprint> strings.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
135 fingerprints = ui.configlist(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
136 b'hostsecurity', b'%s:fingerprints' % bhostname
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
137 )
29267
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
138 for fingerprint in fingerprints:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
139 if not (fingerprint.startswith((b'sha1:', b'sha256:', b'sha512:'))):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
140 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
141 _(b'invalid fingerprint for %s: %s') % (bhostname, fingerprint),
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
142 hint=_(b'must begin with "sha1:", "sha256:", or "sha512:"'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
143 )
29267
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
144
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
145 alg, fingerprint = fingerprint.split(b':', 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
146 fingerprint = fingerprint.replace(b':', b'').lower()
48491
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
147 # pytype: disable=attribute-error
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
148 # `s` is heterogeneous, but this entry is always a list of tuples
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
149 s[b'certfingerprints'].append((alg, fingerprint))
48491
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
150 # pytype: enable=attribute-error
29267
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
151
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
152 # Fingerprints from [hostfingerprints] are always SHA-1.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
153 for fingerprint in ui.configlist(b'hostfingerprints', bhostname):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
154 fingerprint = fingerprint.replace(b':', b'').lower()
48491
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
155 # pytype: disable=attribute-error
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
156 # `s` is heterogeneous, but this entry is always a list of tuples
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
157 s[b'certfingerprints'].append((b'sha1', fingerprint))
48491
08af0adc235c pytype: stop excluding ssutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
158 # pytype: enable=attribute-error
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
159 s[b'legacyfingerprint'] = True
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
160
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
161 # If a host cert fingerprint is defined, it is the only thing that
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
162 # matters. No need to validate CA certs.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
163 if s[b'certfingerprints']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
164 s[b'verifymode'] = ssl.CERT_NONE
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
165 s[b'allowloaddefaultcerts'] = False
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
166
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
167 # If --insecure is used, don't take CAs into consideration.
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
168 elif ui.insecureconnections:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
169 s[b'disablecertverification'] = True
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
170 s[b'verifymode'] = ssl.CERT_NONE
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
171 s[b'allowloaddefaultcerts'] = False
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
172
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
173 if ui.configbool(b'devel', b'disableloaddefaultcerts'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
174 s[b'allowloaddefaultcerts'] = False
29288
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
175
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
176 # If both fingerprints and a per-host ca file are specified, issue a warning
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
177 # because users should not be surprised about what security is or isn't
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
178 # being performed.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
179 cafile = ui.config(b'hostsecurity', b'%s:verifycertsfile' % bhostname)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
180 if s[b'certfingerprints'] and cafile:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
181 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
182 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
183 b'(hostsecurity.%s:verifycertsfile ignored when host '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
184 b'fingerprints defined; using host fingerprints for '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
185 b'verification)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
186 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
187 % bhostname
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
188 )
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
189
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
190 # Try to hook up CA certificate validation unless something above
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
191 # makes it not necessary.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
192 if s[b'verifymode'] is None:
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
193 # Look at per-host ca file first.
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
194 if cafile:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
195 cafile = util.expandpath(cafile)
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
196 if not os.path.exists(cafile):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
197 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
198 _(b'path specified by %s does not exist: %s')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
199 % (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
200 b'hostsecurity.%s:verifycertsfile' % (bhostname,),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
201 cafile,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
202 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
203 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
204 s[b'cafile'] = cafile
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
205 else:
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
206 # Find global certificates file in config.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
207 cafile = ui.config(b'web', b'cacerts')
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
208
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
209 if cafile:
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
210 cafile = util.expandpath(cafile)
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
211 if not os.path.exists(cafile):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
212 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
213 _(b'could not find web.cacerts: %s') % cafile
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
214 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
215 elif s[b'allowloaddefaultcerts']:
29482
4e72995f6c9c sslutil: change comment and logged message for found ca cert file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29459
diff changeset
216 # CAs not defined in config. Try to find system bundles.
29483
918dce4b8c26 sslutil: pass ui to _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29482
diff changeset
217 cafile = _defaultcacerts(ui)
29334
ecc9b788fd69 sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29293
diff changeset
218 if cafile:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
219 ui.debug(b'using %s for CA file\n' % cafile)
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
220
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
221 s[b'cafile'] = cafile
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
222
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
223 # Require certificate validation if CA certs are being loaded and
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
224 # verification hasn't been disabled above.
44880
7dd63a8cb1ee sslutil: eliminate `_canloaddefaultcerts` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44878
diff changeset
225 if cafile or s[b'allowloaddefaultcerts']:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
226 s[b'verifymode'] = ssl.CERT_REQUIRED
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
227 else:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
228 # At this point we don't have a fingerprint, aren't being
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
229 # explicitly insecure, and can't load CA certs. Connecting
29411
e1778b9c8d53 sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29410
diff changeset
230 # is insecure. We allow the connection and abort during
e1778b9c8d53 sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29410
diff changeset
231 # validation (once we have the fingerprint to print to the
e1778b9c8d53 sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29410
diff changeset
232 # user).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
233 s[b'verifymode'] = ssl.CERT_NONE
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
234
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
235 assert s[b'verifymode'] is not None
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
236
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
237 return s
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
238
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
239
29249
cca59ef27e60 sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29248
diff changeset
240 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None):
28653
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
241 """Add SSL/TLS to a socket.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
242
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
243 This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
244 choices based on what security options are available.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
245
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
246 In addition to the arguments supported by ``ssl.wrap_socket``, we allow
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
247 the following additional arguments:
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
248
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
249 * serverhostname - The expected hostname of the remote server. If the
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
250 server (and client) support SNI, this tells the server which certificate
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
251 to use.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
252 """
29224
7424f4294199 sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29115
diff changeset
253 if not serverhostname:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
254 raise error.Abort(_(b'serverhostname argument is required'))
29224
7424f4294199 sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29115
diff changeset
255
42269
c8d55ff80da1 sslutil: add support for SSLKEYLOGFILE to wrapsocket
Augie Fackler <augie@google.com>
parents: 42263
diff changeset
256 if b'SSLKEYLOGFILE' in encoding.environ:
c8d55ff80da1 sslutil: add support for SSLKEYLOGFILE to wrapsocket
Augie Fackler <augie@google.com>
parents: 42263
diff changeset
257 try:
46785
521ac0d7047f typing: disable import error warnings that are already handled
Matt Harbison <matt_harbison@yahoo.com>
parents: 46113
diff changeset
258 import sslkeylog # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
259
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
260 sslkeylog.set_keylog(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
261 pycompat.fsdecode(encoding.environ[b'SSLKEYLOGFILE'])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
262 )
43080
86e4daa2d54c cleanup: mark some ui.(status|note|warn|write) calls as not needing i18n
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
263 ui.warnnoi18n(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
264 b'sslkeylog enabled by SSLKEYLOGFILE environment variable\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
265 )
42269
c8d55ff80da1 sslutil: add support for SSLKEYLOGFILE to wrapsocket
Augie Fackler <augie@google.com>
parents: 42263
diff changeset
266 except ImportError:
43080
86e4daa2d54c cleanup: mark some ui.(status|note|warn|write) calls as not needing i18n
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
267 ui.warnnoi18n(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
268 b'sslkeylog module missing, '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
269 b'but SSLKEYLOGFILE set in environment\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
270 )
42269
c8d55ff80da1 sslutil: add support for SSLKEYLOGFILE to wrapsocket
Augie Fackler <augie@google.com>
parents: 42263
diff changeset
271
33381
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
272 for f in (keyfile, certfile):
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
273 if f and not os.path.exists(f):
36747
4c71a26a4009 sslutil: some more forcebytes() on some exception messages
Augie Fackler <augie@google.com>
parents: 36746
diff changeset
274 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
275 _(b'certificate file (%s) does not exist; cannot connect to %s')
36747
4c71a26a4009 sslutil: some more forcebytes() on some exception messages
Augie Fackler <augie@google.com>
parents: 36746
diff changeset
276 % (f, pycompat.bytesurl(serverhostname)),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
277 hint=_(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
278 b'restore missing file or fix references '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
279 b'in Mercurial config'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
280 ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
281 )
33381
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
282
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
283 settings = _hostsettings(ui, serverhostname)
29249
cca59ef27e60 sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29248
diff changeset
284
29557
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
285 # We can't use ssl.create_default_context() because it calls
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
286 # load_default_certs() unless CA arguments are passed to it. We want to
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
287 # have explicit control over CA loading because implicitly loading
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
288 # CAs may undermine the user's intent. For example, a user may define a CA
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
289 # bundle with a specific CA cert removed. If the system/default CA bundle
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
290 # is loaded and contains that removed CA, you've just undone the user's
53de8255ec4e sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29554
diff changeset
291 # choice.
49054
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
292
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
293 sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
294 minimumprotocol = settings[b'minimumprotocol']
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
295 if minimumprotocol == b'tls1.0':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
296 with warnings.catch_warnings():
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
297 warnings.filterwarnings(
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
298 'ignore',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
299 'ssl.TLSVersion.TLSv1 is deprecated',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
300 DeprecationWarning,
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
301 )
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
302 sslcontext.minimum_version = ssl.TLSVersion.TLSv1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
303 elif minimumprotocol == b'tls1.1':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
304 with warnings.catch_warnings():
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
305 warnings.filterwarnings(
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
306 'ignore',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
307 'ssl.TLSVersion.TLSv1_1 is deprecated',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
308 DeprecationWarning,
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
309 )
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
310 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
311 elif minimumprotocol == b'tls1.2':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
312 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_2
52289
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
313 elif minimumprotocol == b'tls1.3':
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
314 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_3
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
315 else:
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
316 raise error.Abort(_(b'this should not happen'))
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
317 # Prevent CRIME.
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
318 # There is no guarantee this attribute is defined on the module.
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
319 sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0)
49054
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
320
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
321 # We check the hostname ourselves in _verifycert
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
322 sslcontext.check_hostname = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
323 sslcontext.verify_mode = settings[b'verifymode']
28848
e330db205b20 sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28653
diff changeset
324
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
325 if settings[b'ciphers']:
29577
9654ef41f7cc sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29561
diff changeset
326 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
327 sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers']))
29577
9654ef41f7cc sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29561
diff changeset
328 except ssl.SSLError as e:
36747
4c71a26a4009 sslutil: some more forcebytes() on some exception messages
Augie Fackler <augie@google.com>
parents: 36746
diff changeset
329 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
330 _(b'could not set ciphers: %s')
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
331 % stringutil.forcebytestr(e.args[0]),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
332 hint=_(b'change cipher string (%s) in config')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
333 % settings[b'ciphers'],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
334 )
29577
9654ef41f7cc sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29561
diff changeset
335
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
336 if certfile is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
337
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
338 def password():
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
339 f = keyfile or certfile
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
340 return ui.getpass(_(b'passphrase for %s: ') % f, b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
341
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
342 sslcontext.load_cert_chain(certfile, keyfile, password)
28848
e330db205b20 sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28653
diff changeset
343
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
344 if settings[b'cafile'] is not None:
29446
2f7f1e10f840 sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29411
diff changeset
345 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
346 sslcontext.load_verify_locations(cafile=settings[b'cafile'])
29446
2f7f1e10f840 sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29411
diff changeset
347 except ssl.SSLError as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
348 if len(e.args) == 1: # pypy has different SSLError args
29927
799e36749f1a ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29631
diff changeset
349 msg = e.args[0]
799e36749f1a ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29631
diff changeset
350 else:
799e36749f1a ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29631
diff changeset
351 msg = e.args[1]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
352 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
353 _(b'error loading CA file %s: %s')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
354 % (settings[b'cafile'], stringutil.forcebytestr(msg)),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
355 hint=_(b'file is empty or malformed?'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
356 )
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
357 caloaded = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
358 elif settings[b'allowloaddefaultcerts']:
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
359 # This is a no-op on old Python.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
360 sslcontext.load_default_certs()
29288
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
361 caloaded = True
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
362 else:
7dee15dee53c sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29287
diff changeset
363 caloaded = False
23834
bf07c19b4c82 https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents: 23069
diff changeset
364
29449
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
365 try:
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
366 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
367 except ssl.SSLError as e:
29449
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
368 # If we're doing certificate verification and no CA certs are loaded,
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
369 # that is almost certainly the reason why verification failed. Provide
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
370 # a hint to the user.
31725
c777b12cdc9b sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents: 31290
diff changeset
371 # The exception handler is here to handle bugs around cert attributes:
c777b12cdc9b sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents: 31290
diff changeset
372 # https://bugs.python.org/issue20916#msg213479. (See issues5313.)
c777b12cdc9b sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents: 31290
diff changeset
373 # When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a
c777b12cdc9b sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents: 31290
diff changeset
374 # non-empty list, but the following conditional is otherwise True.
29631
387bdd53c77e sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29619
diff changeset
375 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
376 if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
377 caloaded
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
378 and settings[b'verifymode'] == ssl.CERT_REQUIRED
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
379 and not sslcontext.get_ca_certs()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
380 ):
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
381 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
382 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
383 b'(an attempt was made to load CA certificates but '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
384 b'none were loaded; see '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
385 b'https://mercurial-scm.org/wiki/SecureConnections '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
386 b'for how to configure Mercurial to avoid this '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
387 b'error)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
388 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
389 )
29631
387bdd53c77e sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29619
diff changeset
390 except ssl.SSLError:
387bdd53c77e sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29619
diff changeset
391 pass
41410
0d226b2139df sslutil: use raw strings for exception reason compare
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38475
diff changeset
392
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
393 # Try to print more helpful error messages for known failures.
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50602
diff changeset
394 if hasattr(e, 'reason'):
29619
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
395 # This error occurs when the client and server don't share a
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
396 # common/supported SSL/TLS protocol. We've disabled SSLv2 and SSLv3
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
397 # outright. Hopefully the reason for this error is that we require
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
398 # TLS 1.1+ and the server only supports TLS 1.0. Whatever the
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
399 # reason, try to emit an actionable warning.
49057
27ef2aa953dd sslutil: support TLSV1_ALERT_PROTOCOL_VERSION reason code
Julien Cristau <jcristau@debian.org>
parents: 49055
diff changeset
400 if e.reason in (
27ef2aa953dd sslutil: support TLSV1_ALERT_PROTOCOL_VERSION reason code
Julien Cristau <jcristau@debian.org>
parents: 49055
diff changeset
401 'UNSUPPORTED_PROTOCOL',
27ef2aa953dd sslutil: support TLSV1_ALERT_PROTOCOL_VERSION reason code
Julien Cristau <jcristau@debian.org>
parents: 49055
diff changeset
402 'TLSV1_ALERT_PROTOCOL_VERSION',
27ef2aa953dd sslutil: support TLSV1_ALERT_PROTOCOL_VERSION reason code
Julien Cristau <jcristau@debian.org>
parents: 49055
diff changeset
403 ):
29619
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
404 # We attempted TLS 1.0+.
44899
4ca1110991c4 sslutil: rename 'minimumprotocolui' -> 'minimumprotocol'
Manuel Jacob <me@manueljacob.de>
parents: 44898
diff changeset
405 if settings[b'minimumprotocol'] == b'tls1.0':
29619
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
406 # We support more than just TLS 1.0+. If this happens,
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
407 # the likely scenario is either the client or the server
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
408 # is really old. (e.g. server doesn't support TLS 1.0+ or
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
409 # client doesn't support modern TLS versions introduced
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
410 # several years from when this comment was written).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
411 if supportedprotocols != {b'tls1.0'}:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
412 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
413 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
414 b'(could not communicate with %s using security '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
415 b'protocols %s; if you are using a modern Mercurial '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
416 b'version, consider contacting the operator of this '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
417 b'server; see '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
418 b'https://mercurial-scm.org/wiki/SecureConnections '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
419 b'for more info)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
420 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
421 % (
41411
f07aff7e8b5a sslutil: ensure serverhostname is bytes when formatting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41410
diff changeset
422 pycompat.bytesurl(serverhostname),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
423 b', '.join(sorted(supportedprotocols)),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
424 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
425 )
29619
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
426 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
427 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
428 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
429 b'(could not communicate with %s using TLS 1.0; the '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
430 b'likely cause of this is the server no longer '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
431 b'supports TLS 1.0 because it has known security '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
432 b'vulnerabilities; see '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
433 b'https://mercurial-scm.org/wiki/SecureConnections '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
434 b'for more info)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
435 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
436 % pycompat.bytesurl(serverhostname)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
437 )
29619
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
438 else:
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
439 # We attempted TLS 1.1+. We can only get here if the client
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
440 # supports the configured protocol. So the likely reason is
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
441 # the client wants better security than the server can
53e80179bd6a sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29618
diff changeset
442 # offer.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
443 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
444 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
445 b'(could not negotiate a common security protocol (%s+) '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
446 b'with %s; the likely cause is Mercurial is configured '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
447 b'to be more secure than the server can support)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
448 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
449 % (
44899
4ca1110991c4 sslutil: rename 'minimumprotocolui' -> 'minimumprotocol'
Manuel Jacob <me@manueljacob.de>
parents: 44898
diff changeset
450 settings[b'minimumprotocol'],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
451 pycompat.bytesurl(serverhostname),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
452 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
453 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
454 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
455 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
456 b'(consider contacting the operator of this '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
457 b'server and ask them to support modern TLS '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
458 b'protocol versions; or, set '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
459 b'hostsecurity.%s:minimumprotocol=tls1.0 to allow '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
460 b'use of legacy, less secure protocols when '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
461 b'communicating with this server)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
462 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
463 % pycompat.bytesurl(serverhostname)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
464 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
465 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
466 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
467 b'(see https://mercurial-scm.org/wiki/SecureConnections '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
468 b'for more info)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
469 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
470 )
33494
30f2715be123 sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents: 33381
diff changeset
471
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
472 elif e.reason == 'CERTIFICATE_VERIFY_FAILED' and pycompat.iswindows:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
473 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
474 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
475 b'(the full certificate chain may not be available '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
476 b'locally; see "hg help debugssl")\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
477 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
478 )
29449
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
479 raise
5b71a8d7f7ff sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29447
diff changeset
480
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
481 # check if wrap_socket failed silently because socket had been
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
482 # closed
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
483 # - see http://bugs.python.org/issue13721
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
484 if not sslsocket.cipher():
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
485 raise error.SecurityError(_(b'ssl connection failed'))
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
486
29225
b115eed11780 sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29224
diff changeset
487 sslsocket._hgstate = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
488 b'caloaded': caloaded,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
489 b'hostname': serverhostname,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
490 b'settings': settings,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
491 b'ui': ui,
29225
b115eed11780 sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29224
diff changeset
492 }
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
493
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
494 return sslsocket
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
495
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
496
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
497 def wrapserversocket(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
498 sock, ui, certfile=None, keyfile=None, cafile=None, requireclientcert=False
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
499 ):
29554
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
500 """Wrap a socket for use by servers.
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
501
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
502 ``certfile`` and ``keyfile`` specify the files containing the certificate's
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
503 public and private keys, respectively. Both keys can be defined in the same
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
504 file via ``certfile`` (the private key must come first in the file).
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
505
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
506 ``cafile`` defines the path to certificate authorities.
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
507
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
508 ``requireclientcert`` specifies whether to require client certificates.
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
509
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
510 Typically ``cafile`` is only defined if ``requireclientcert`` is true.
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
511 """
33381
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
512 # This function is not used much by core Mercurial, so the error messaging
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
513 # doesn't have to be as detailed as for wrapsocket().
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
514 for f in (certfile, keyfile, cafile):
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
515 if f and not os.path.exists(f):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
516 raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
517 _(b'referenced certificate file (%s) does not exist') % f
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
518 )
33381
3bdbbadddecc sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
519
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
520 sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
521 sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0)
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
522
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
523 # This config option is intended for use in tests only. It is a giant
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
524 # footgun to kill security. Don't define it.
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
525 exactprotocol = ui.config(b'devel', b'server-insecure-exact-protocol')
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
526 if exactprotocol == b'tls1.0':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
527 if b'tls1.0' not in supportedprotocols:
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
528 raise error.Abort(_(b'TLS 1.0 not supported by this Python'))
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
529 with warnings.catch_warnings():
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
530 warnings.filterwarnings(
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
531 'ignore',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
532 'ssl.TLSVersion.TLSv1 is deprecated',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
533 DeprecationWarning,
49054
5144d3579a9c sslutil: avoid deprecation warnings from python 3.10's ssl module
Julien Cristau <jcristau@debian.org>
parents: 48875
diff changeset
534 )
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
535 sslcontext.minimum_version = ssl.TLSVersion.TLSv1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
536 sslcontext.maximum_version = ssl.TLSVersion.TLSv1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
537 elif exactprotocol == b'tls1.1':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
538 if b'tls1.1' not in supportedprotocols:
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
539 raise error.Abort(_(b'TLS 1.1 not supported by this Python'))
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
540 with warnings.catch_warnings():
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
541 warnings.filterwarnings(
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
542 'ignore',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
543 'ssl.TLSVersion.TLSv1_1 is deprecated',
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
544 DeprecationWarning,
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
545 )
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
546 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
547 sslcontext.maximum_version = ssl.TLSVersion.TLSv1_1
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
548 elif exactprotocol == b'tls1.2':
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
549 if b'tls1.2' not in supportedprotocols:
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
550 raise error.Abort(_(b'TLS 1.2 not supported by this Python'))
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
551 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_2
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
552 sslcontext.maximum_version = ssl.TLSVersion.TLSv1_2
52289
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
553 elif exactprotocol == b'tls1.3':
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
554 if b'tls1.3' not in supportedprotocols:
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
555 raise error.Abort(_(b'TLS 1.3 not supported by this Python'))
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
556 sslcontext.minimum_version = ssl.TLSVersion.TLSv1_3
323e3626929a sslutil: add support for clients to set TLSv1.3 as the minimum protocol
Matt Harbison <matt_harbison@yahoo.com>
parents: 52287
diff changeset
557 sslcontext.maximum_version = ssl.TLSVersion.TLSv1_3
52286
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
558 elif exactprotocol:
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
559 raise error.Abort(
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
560 _(b'invalid value for server-insecure-exact-protocol: %s')
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
561 % exactprotocol
f1b37ed41f01 sslutil: de-indent the Python 3.7+ code from the previous commit
Matt Harbison <matt_harbison@yahoo.com>
parents: 52285
diff changeset
562 )
29559
7dec5e441bf7 sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29558
diff changeset
563
44878
035199ba04ee sslutil: eliminate `modernssl` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44876
diff changeset
564 # Improve forward secrecy.
035199ba04ee sslutil: eliminate `modernssl` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44876
diff changeset
565 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0)
035199ba04ee sslutil: eliminate `modernssl` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44876
diff changeset
566 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0)
29554
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
567
49055
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
568 # In tests, allow insecure ciphers
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
569 # Otherwise, use the list of more secure ciphers if found in the ssl module.
50bd2910d162 sslutil: be less strict about which ciphers are allowed when using --insecure
Julien Cristau <jcristau@debian.org>
parents: 49054
diff changeset
570 if exactprotocol:
50342
c54e9bb5737e sslutil: set context security level for legacy tls testing (issue6760)
pacien <pacien.trangirard@pacien.net>
parents: 50341
diff changeset
571 sslcontext.set_ciphers('DEFAULT:@SECLEVEL=0')
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50602
diff changeset
572 elif hasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'):
44878
035199ba04ee sslutil: eliminate `modernssl` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44876
diff changeset
573 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0)
46786
52528570312e typing: disable module attribute warnings for properly conditionalized code
Matt Harbison <matt_harbison@yahoo.com>
parents: 46785
diff changeset
574 # pytype: disable=module-attr
44878
035199ba04ee sslutil: eliminate `modernssl` by constant-folding code using it
Manuel Jacob <me@manueljacob.de>
parents: 44876
diff changeset
575 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS)
46786
52528570312e typing: disable module attribute warnings for properly conditionalized code
Matt Harbison <matt_harbison@yahoo.com>
parents: 46785
diff changeset
576 # pytype: enable=module-attr
29554
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
577
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
578 if requireclientcert:
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
579 sslcontext.verify_mode = ssl.CERT_REQUIRED
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
580 else:
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
581 sslcontext.verify_mode = ssl.CERT_NONE
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
582
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
583 if certfile or keyfile:
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
584 sslcontext.load_cert_chain(certfile=certfile, keyfile=keyfile)
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
585
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
586 if cafile:
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
587 sslcontext.load_verify_locations(cafile=cafile)
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
588
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
589 return sslcontext.wrap_socket(sock, server_side=True)
4a7b0c696fbc sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29537
diff changeset
590
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
591
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
592 class wildcarderror(Exception):
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
593 """Represents an error parsing wildcards in DNS name."""
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
594
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
595
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
596 def _dnsnamematch(dn, hostname, maxwildcards=1):
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
597 """Match DNS names according RFC 6125 section 6.4.3.
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
598
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
599 This code is effectively copied from CPython's ssl._dnsname_match.
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
600
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
601 Returns a bool indicating whether the expected hostname matches
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
602 the value in ``dn``.
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
603 """
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
604 pats = []
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
605 if not dn:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
606 return False
36745
424994a0adfd sslutil: lots of unicode/bytes cleanup
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
607 dn = pycompat.bytesurl(dn)
424994a0adfd sslutil: lots of unicode/bytes cleanup
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
608 hostname = pycompat.bytesurl(hostname)
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
609
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
610 pieces = dn.split(b'.')
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
611 leftmost = pieces[0]
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
612 remainder = pieces[1:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
613 wildcards = leftmost.count(b'*')
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
614 if wildcards > maxwildcards:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
615 raise wildcarderror(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
616 _(b'too many wildcards in certificate DNS name: %s') % dn
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
617 )
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
618
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
619 # speed up common case w/o wildcards
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
620 if not wildcards:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
621 return dn.lower() == hostname.lower()
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
622
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
623 # RFC 6125, section 6.4.3, subitem 1.
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
624 # The client SHOULD NOT attempt to match a presented identifier in which
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
625 # the wildcard character comprises a label other than the left-most label.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
626 if leftmost == b'*':
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
627 # When '*' is a fragment by itself, it matches a non-empty dotless
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
628 # fragment.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
629 pats.append(b'[^.]+')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
630 elif leftmost.startswith(b'xn--') or hostname.startswith(b'xn--'):
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
631 # RFC 6125, section 6.4.3, subitem 3.
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
632 # The client SHOULD NOT attempt to match a presented identifier
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
633 # where the wildcard character is embedded within an A-label or
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
634 # U-label of an internationalized domain name.
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 37872
diff changeset
635 pats.append(stringutil.reescape(leftmost))
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
636 else:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
637 # Otherwise, '*' matches any dotless string, e.g. www*
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
638 pats.append(stringutil.reescape(leftmost).replace(br'\*', b'[^.]*'))
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
639
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
640 # add the remaining fragments, ignore any wildcards
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
641 for frag in remainder:
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 37872
diff changeset
642 pats.append(stringutil.reescape(frag))
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
643
37666
46e705b79323 py3: add b'' prefixes to make values bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37120
diff changeset
644 pat = re.compile(br'\A' + br'\.'.join(pats) + br'\Z', re.IGNORECASE)
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
645 return pat.match(hostname) is not None
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
646
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
647
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
648 def _verifycert(cert, hostname):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45915
diff changeset
649 """Verify that cert (in socket.getpeercert() format) matches hostname.
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
650 CRLs is not handled.
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
651
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
652 Returns error message if any problems are found and None on success.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45915
diff changeset
653 """
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
654 if not cert:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
655 return _(b'no certificate received')
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
656
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
657 dnsnames = []
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
658 san = cert.get('subjectAltName', [])
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
659 for key, value in san:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
660 if key == 'DNS':
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
661 try:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
662 if _dnsnamematch(value, hostname):
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
663 return
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
664 except wildcarderror as e:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
665 return stringutil.forcebytestr(e.args[0])
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
666
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
667 dnsnames.append(value)
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
668
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
669 if not dnsnames:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
670 # The subject is only checked when there is no DNS in subjectAltName.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
671 for sub in cert.get('subject', []):
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
672 for key, value in sub:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
673 # According to RFC 2818 the most specific Common Name must
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
674 # be used.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
675 if key == 'commonName':
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30228
diff changeset
676 # 'subject' entries are unicode.
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
677 try:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
678 value = value.encode('ascii')
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
679 except UnicodeEncodeError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
680 return _(b'IDN in certificate not supported')
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
681
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
682 try:
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
683 if _dnsnamematch(value, hostname):
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
684 return
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
685 except wildcarderror as e:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36747
diff changeset
686 return stringutil.forcebytestr(e.args[0])
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
687
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
688 dnsnames.append(value)
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
689
37872
51a2f8d199c7 sslutil: fix some edge cases in Python 3 support
Augie Fackler <augie@google.com>
parents: 37666
diff changeset
690 dnsnames = [pycompat.bytesurl(d) for d in dnsnames]
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
691 if len(dnsnames) > 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
692 return _(b'certificate is for %s') % b', '.join(dnsnames)
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
693 elif len(dnsnames) == 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
694 return _(b'certificate is for %s') % dnsnames[0]
29452
26a5d605b868 sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29042
diff changeset
695 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
696 return _(b'no commonName or subjectAltName found in certificate')
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
697
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
698
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
699 def _plainapplepython():
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
700 """return true if this seems to be a pure Apple Python that
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
701 * is unfrozen and presumably has the whole mercurial module in the file
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
702 system
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
703 * presumably is an Apple Python that uses Apple OpenSSL which has patches
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
704 for using system certificate store CAs in addition to the provided
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
705 cacerts file
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
706 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
707 if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
708 not pycompat.isdarwin
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43506
diff changeset
709 or resourceutil.mainfrozen()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
710 or not pycompat.sysexecutable
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
711 ):
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
712 return False
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30641
diff changeset
713 exe = os.path.realpath(pycompat.sysexecutable).lower()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
714 return exe.startswith(b'/usr/bin/python') or exe.startswith(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
715 b'/system/library/frameworks/python.framework/'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
716 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
717
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
718
29483
918dce4b8c26 sslutil: pass ui to _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29482
diff changeset
719 def _defaultcacerts(ui):
29488
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
720 """return path to default CA certificates or None.
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
721
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
722 It is assumed this function is called when the returned certificates
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
723 file will actually be used to validate connections. Therefore this
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
724 function may print warnings or debug messages assuming this usage.
29500
4b16a5bd9948 sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29499
diff changeset
725
4b16a5bd9948 sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29499
diff changeset
726 We don't print a message when the Python is able to load default
4b16a5bd9948 sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29499
diff changeset
727 CA certs because this scenario is detected at socket connect time.
29488
1c26b9ce66f8 sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29487
diff changeset
728 """
30228
b9f7b0c10027 sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29927
diff changeset
729 # The "certifi" Python package provides certificates. If it is installed
b9f7b0c10027 sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29927
diff changeset
730 # and usable, assume the user intends it to be used and use it.
29486
a62c00f6dd04 sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29484
diff changeset
731 try:
51293
03fc41fe8aa1 pytype: ignore certifi import error
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
732 import certifi # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
733
29486
a62c00f6dd04 sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29484
diff changeset
734 certs = certifi.where()
30228
b9f7b0c10027 sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29927
diff changeset
735 if os.path.exists(certs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
736 ui.debug(b'using ca certificates from certifi\n')
42263
ce5f1232631f sslutil: fsencode path returned by certifi (issue6132)
Augie Fackler <augie@google.com>
parents: 41411
diff changeset
737 return pycompat.fsencode(certs)
30228
b9f7b0c10027 sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29927
diff changeset
738 except (ImportError, AttributeError):
29486
a62c00f6dd04 sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29484
diff changeset
739 pass
a62c00f6dd04 sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29484
diff changeset
740
29487
cdcb5747dc88 sslutil: document the Apple OpenSSL cert trick
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29486
diff changeset
741 # Apple's OpenSSL has patches that allow a specially constructed certificate
cdcb5747dc88 sslutil: document the Apple OpenSSL cert trick
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29486
diff changeset
742 # to load the system CA store. If we're running on Apple Python, use this
cdcb5747dc88 sslutil: document the Apple OpenSSL cert trick
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29486
diff changeset
743 # trick.
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
744 if _plainapplepython():
31074
2912b06905dc py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30669
diff changeset
745 dummycert = os.path.join(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
746 os.path.dirname(pycompat.fsencode(__file__)), b'dummycert.pem'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
747 )
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
748 if os.path.exists(dummycert):
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
749 return dummycert
29107
c8fbfb9163ce sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29106
diff changeset
750
c8fbfb9163ce sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29106
diff changeset
751 return None
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
752
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
753
29286
a05a91a3f120 sslutil: remove "strict" argument from validatesocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29268
diff changeset
754 def validatesocket(sock):
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30228
diff changeset
755 """Validate a socket meets security requirements.
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
756
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
757 The passed socket must have been created with ``wrapsocket()``.
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
758 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
759 shost = sock._hgstate[b'hostname']
36745
424994a0adfd sslutil: lots of unicode/bytes cleanup
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
760 host = pycompat.bytesurl(shost)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
761 ui = sock._hgstate[b'ui']
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
762 settings = sock._hgstate[b'settings']
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
763
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
764 try:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
765 peercert = sock.getpeercert(True)
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
766 peercert2 = sock.getpeercert()
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
767 except AttributeError:
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
768 raise error.SecurityError(_(b'%s ssl connection error') % host)
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
769
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
770 if not peercert:
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
771 raise error.SecurityError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
772 _(b'%s certificate error: no certificate received') % host
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
773 )
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
774
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
775 if settings[b'disablecertverification']:
29289
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
776 # We don't print the certificate fingerprint because it shouldn't
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
777 # be necessary: if the user requested certificate verification be
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
778 # disabled, they presumably already saw a message about the inability
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
779 # to verify the certificate and this message would have printed the
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
780 # fingerprint. So printing the fingerprint here adds little to no
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
781 # value.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
782 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
783 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
784 b'warning: connection security to %s is disabled per current '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
785 b'settings; communication is susceptible to eavesdropping '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
786 b'and tampering\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
787 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
788 % host
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
789 )
29289
3536673a25ae sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29288
diff changeset
790 return
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
791
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
792 # If a certificate fingerprint is pinned, use it and only it to
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
793 # validate the remote cert.
29262
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
794 peerfingerprints = {
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
795 b'sha1': hex(hashutil.sha1(peercert).digest()),
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
796 b'sha256': hex(hashlib.sha256(peercert).digest()),
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
797 b'sha512': hex(hashlib.sha512(peercert).digest()),
29262
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
798 }
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
799
29290
01248c37a68e sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29289
diff changeset
800 def fmtfingerprint(s):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
801 return b':'.join([s[x : x + 2] for x in range(0, len(s), 2)])
29290
01248c37a68e sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29289
diff changeset
802
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
803 nicefingerprint = b'sha256:%s' % fmtfingerprint(peerfingerprints[b'sha256'])
28850
3819c349b194 sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28849
diff changeset
804
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
805 if settings[b'certfingerprints']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
806 for hash, fingerprint in settings[b'certfingerprints']:
29262
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
807 if peerfingerprints[hash].lower() == fingerprint:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
808 ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
809 b'%s certificate matched fingerprint %s:%s\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
810 % (host, hash, fmtfingerprint(fingerprint))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
811 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
812 if settings[b'legacyfingerprint']:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
813 ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
814 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
815 b'(SHA-1 fingerprint for %s found in legacy '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
816 b'[hostfingerprints] section; '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
817 b'if you trust this fingerprint, remove the old '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
818 b'SHA-1 fingerprint from [hostfingerprints] and '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
819 b'add the following entry to the new '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
820 b'[hostsecurity] section: %s:fingerprints=%s)\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
821 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
822 % (host, host, nicefingerprint)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
823 )
29291
15e533b7909c sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29290
diff changeset
824 return
28850
3819c349b194 sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28849
diff changeset
825
29293
1b3a0b0c414f sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29292
diff changeset
826 # Pinned fingerprint didn't match. This is a fatal error.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
827 if settings[b'legacyfingerprint']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
828 section = b'hostfingerprint'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
829 nice = fmtfingerprint(peerfingerprints[b'sha1'])
29293
1b3a0b0c414f sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29292
diff changeset
830 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
831 section = b'hostsecurity'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
832 nice = b'%s:%s' % (hash, fmtfingerprint(peerfingerprints[hash]))
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
833 raise error.SecurityError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43089
diff changeset
834 _(b'certificate for %s has unexpected fingerprint %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
835 % (host, nice),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
836 hint=_(b'check %s configuration') % section,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
837 )
28850
3819c349b194 sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28849
diff changeset
838
29411
e1778b9c8d53 sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29410
diff changeset
839 # Security is enabled but no CAs are loaded. We can't establish trust
e1778b9c8d53 sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29410
diff changeset
840 # for the cert so abort.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
841 if not sock._hgstate[b'caloaded']:
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
842 raise error.SecurityError(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
843 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
844 b'unable to verify security of %s (no loaded CA certificates); '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
845 b'refusing to connect'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
846 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
847 % host,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
848 hint=_(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
849 b'see https://mercurial-scm.org/wiki/SecureConnections for '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
850 b'how to configure Mercurial to avoid this error or set '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
851 b'hostsecurity.%s:fingerprints=%s to trust this server'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
852 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
853 % (host, nicefingerprint),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
854 )
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
855
36745
424994a0adfd sslutil: lots of unicode/bytes cleanup
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
856 msg = _verifycert(peercert2, shost)
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
857 if msg:
45915
8f50dc096cf4 errors: introduce SecurityError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 44902
diff changeset
858 raise error.SecurityError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
859 _(b'%s certificate error: %s') % (host, msg),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
860 hint=_(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
861 b'set hostsecurity.%s:certfingerprints=%s '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
862 b'config setting or use --insecure to connect '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
863 b'insecurely'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
864 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
865 % (host, nicefingerprint),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42269
diff changeset
866 )