Mercurial > hg
annotate mercurial/sslutil.py @ 35058:a68c3420be41
rebase: exclude descendants of obsoletes w/o a successor in dest (issue5300)
.. feature::
Let 'hg rebase' avoid content-divergence by skipping obsolete
changesets (and their descendants) when they are present in the rebase
set along with one of their successors but none of their successors is
in destination.
In the following example, when trying to rebase 3:: onto 2, the rebase
will abort with "this rebase will cause divergence from: 4":
o 7 f
|
| o 6 e
| |
| o 5 d'
| |
x | 4 d (rewritten as 5)
|/
o 3 c
|
| o 2 x
| |
o | 1 b
|/
o 0 a
By excluding obsolete changesets without a successor in destination (4
in the example above) and their descendants, we make rebase work in this
case, thus giving:
o 11 e
|
o 10 d'
|
o 9 c
|
o 8 b
|
| o 7 f
| |
| | x 6 e (rewritten using rebase as 11)
| | |
| | x 5 d' (rewritten using rebase as 10)
| | |
| x | 4 d
| |/
| x 3 c (rewritten using rebase as 9)
| |
o | 2 x
| |
| x 1 b (rewritten using rebase as 8)
|/
o 0 a
where branch 4:: is left behind while branch 5:: is rebased as expected.
The rationale is that users may not be interested in rebasing orphan
changesets when specifying a rebase set that include them but would
still want "stable" ones to be rebased. Currently, the user is suggested
to allow divergence (but probably does not want it) or they must specify
a rebase set excluding problematic changesets (which might be a bit
cumbersome). The approach proposed here corresponds to "Option 2" in
https://www.mercurial-scm.org/wiki/CEDRebase.
We extend _computeobsoletenotrebased() so that it also return a set of
obsolete changesets in rebase set without a successor in destination but
with at least one successor in rebase set. This
'obsoletewithoutsuccessorindestination' is then stored as an attribute
of rebaseruntime and used in _performrebasesubset() to:
* filter out descendants of these changesets from the revisions to
rebase;
* issue a message about these revisions being skipped.
This only occurs if 'evolution.allowdivergence' option is off and
'rebaseskipobsolete' is on.
author | Denis Laxalde <denis@laxalde.org> |
---|---|
date | Tue, 14 Nov 2017 22:46:10 +0100 |
parents | 17919e9006b9 |
children | c8ecd96cc357 |
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 # |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> |
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 |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
10 from __future__ import absolute_import |
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 |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
16 |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
17 from .i18n import _ |
28577
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
18 from . import ( |
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
19 error, |
30639
d524c88511a7
py3: replace os.name with pycompat.osname (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
20 pycompat, |
28577
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
21 util, |
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
22 ) |
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
|
23 |
28647
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
24 # 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
|
25 # 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
|
26 # 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
|
27 # |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
28 # Depending on the version of Python being used, SSL/TLS support is either |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
29 # modern/secure or legacy/insecure. Many operations in this module have |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
30 # separate code paths depending on support in Python. |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
31 |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32273
diff
changeset
|
32 configprotocols = { |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
33 'tls1.0', |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
34 'tls1.1', |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
35 'tls1.2', |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32273
diff
changeset
|
36 } |
26622
9e15286609ae
sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26587
diff
changeset
|
37 |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
38 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
|
39 |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
40 # TLS 1.1 and 1.2 may not be supported if the OpenSSL Python is compiled |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
41 # against doesn't support them. |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32273
diff
changeset
|
42 supportedprotocols = {'tls1.0'} |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
43 if util.safehasattr(ssl, 'PROTOCOL_TLSv1_1'): |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
44 supportedprotocols.add('tls1.1') |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
45 if util.safehasattr(ssl, 'PROTOCOL_TLSv1_2'): |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
46 supportedprotocols.add('tls1.2') |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
47 |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
48 try: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
49 # ssl.SSLContext was added in 2.7.9 and presence indicates modern |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
50 # SSL/TLS features are available. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
51 SSLContext = ssl.SSLContext |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
52 modernssl = True |
28650
737863b01d9f
sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28649
diff
changeset
|
53 _canloaddefaultcerts = util.safehasattr(SSLContext, 'load_default_certs') |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
54 except AttributeError: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
55 modernssl = False |
28650
737863b01d9f
sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28649
diff
changeset
|
56 _canloaddefaultcerts = False |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
57 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
58 # We implement SSLContext using the interface from the standard library. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
59 class SSLContext(object): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
60 def __init__(self, protocol): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
61 # From the public interface of SSLContext |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
62 self.protocol = protocol |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
63 self.check_hostname = False |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
64 self.options = 0 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
65 self.verify_mode = ssl.CERT_NONE |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
66 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
67 # Used by our implementation. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
68 self._certfile = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
69 self._keyfile = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
70 self._certpassword = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
71 self._cacerts = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
72 self._ciphers = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
73 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
74 def load_cert_chain(self, certfile, keyfile=None, password=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
75 self._certfile = certfile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
76 self._keyfile = keyfile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
77 self._certpassword = password |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
78 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
79 def load_default_certs(self, purpose=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
80 pass |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
81 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
82 def load_verify_locations(self, cafile=None, capath=None, cadata=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
83 if capath: |
29389
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
29341
diff
changeset
|
84 raise error.Abort(_('capath not supported')) |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
85 if cadata: |
29389
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
29341
diff
changeset
|
86 raise error.Abort(_('cadata not supported')) |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
87 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
88 self._cacerts = cafile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
89 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
90 def set_ciphers(self, ciphers): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
91 self._ciphers = ciphers |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
92 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
93 def wrap_socket(self, socket, server_hostname=None, server_side=False): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
94 # server_hostname is unique to SSLContext.wrap_socket and is used |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
95 # for SNI in that context. So there's nothing for us to do with it |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
96 # in this legacy code since we don't support SNI. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
97 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
98 args = { |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
99 'keyfile': self._keyfile, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
100 'certfile': self._certfile, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
101 'server_side': server_side, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
102 'cert_reqs': self.verify_mode, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
103 'ssl_version': self.protocol, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
104 'ca_certs': self._cacerts, |
32247
e05cfb4a6a8e
sslutil: remove conditional cipher code needed for Python 2.6
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32194
diff
changeset
|
105 'ciphers': self._ciphers, |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
106 } |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
107 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
108 return ssl.wrap_socket(socket, **args) |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
109 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
110 def _hostsettings(ui, hostname): |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
111 """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
|
112 |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
113 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
|
114 """ |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
115 s = { |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
116 # 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
|
117 # if an explicit ``cafile`` is not defined. |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
118 'allowloaddefaultcerts': True, |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
119 # List of 2-tuple of (hash algorithm, hash). |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
120 'certfingerprints': [], |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
121 # 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
|
122 # SSLContext.load_verify_locations(). |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
123 'cafile': None, |
29287
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
124 # Whether certificate verification should be disabled. |
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
125 'disablecertverification': False, |
29268
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
126 # Whether the legacy [hostfingerprints] section has data for this host. |
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
127 'legacyfingerprint': False, |
29507
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
128 # PROTOCOL_* constant to use for SSLContext.__init__. |
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
129 'protocol': None, |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
130 # 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
|
131 # presentation. |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
132 'protocolui': None, |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
133 # ssl.CERT_* constant used by SSLContext.verify_mode. |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
134 'verifymode': None, |
29508
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
135 # Defines extra ssl.OP* bitwise options to set. |
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
136 'ctxoptions': None, |
29577
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
137 # OpenSSL Cipher List to use (instead of default). |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
138 'ciphers': None, |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
139 } |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
140 |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
141 # 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
|
142 def validateprotocol(protocol, key): |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
143 if protocol not in configprotocols: |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
144 raise error.Abort( |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
145 _('unsupported protocol from hostsecurity.%s: %s') % |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
146 (key, protocol), |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
147 hint=_('valid protocols: %s') % |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
148 ' '.join(sorted(configprotocols))) |
29507
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
149 |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
150 # We default to TLS 1.1+ where we can because TLS 1.0 has known |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
151 # vulnerabilities (like BEAST and POODLE). We allow users to downgrade to |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
152 # TLS 1.0+ via config options in case a legacy server is encountered. |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
153 if 'tls1.1' in supportedprotocols: |
29560
303e9300772a
sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29559
diff
changeset
|
154 defaultprotocol = 'tls1.1' |
303e9300772a
sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29559
diff
changeset
|
155 else: |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
156 # Let people know they are borderline secure. |
29561
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
157 # We don't document this config option because we want people to see |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
158 # the bold warnings on the web site. |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
159 # internal config: hostsecurity.disabletls10warning |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
160 if not ui.configbool('hostsecurity', 'disabletls10warning'): |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
161 ui.warn(_('warning: connecting to %s using legacy security ' |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
162 'technology (TLS 1.0); see ' |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
163 'https://mercurial-scm.org/wiki/SecureConnections for ' |
1a782fabf80d
sslutil: print a warning when using TLS 1.0 on legacy Python
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29560
diff
changeset
|
164 'more info\n') % hostname) |
29560
303e9300772a
sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29559
diff
changeset
|
165 defaultprotocol = 'tls1.0' |
303e9300772a
sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29559
diff
changeset
|
166 |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
167 key = 'minimumprotocol' |
29560
303e9300772a
sslutil: require TLS 1.1+ when supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29559
diff
changeset
|
168 protocol = ui.config('hostsecurity', key, defaultprotocol) |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
169 validateprotocol(protocol, key) |
29508
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
170 |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
171 key = '%s:minimumprotocol' % hostname |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
172 protocol = ui.config('hostsecurity', key, protocol) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
173 validateprotocol(protocol, key) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
174 |
29617
2960ceee1948
sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29601
diff
changeset
|
175 # 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
|
176 # 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
|
177 # --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
|
178 if ui.insecureconnections: |
2960ceee1948
sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29601
diff
changeset
|
179 protocol = 'tls1.0' |
2960ceee1948
sslutil: allow TLS 1.0 when --insecure is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29601
diff
changeset
|
180 |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
181 s['protocol'], s['ctxoptions'], s['protocolui'] = protocolsettings(protocol) |
29558
a935cd7d51a6
sslutil: prevent CRIME
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29557
diff
changeset
|
182 |
29577
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
183 ciphers = ui.config('hostsecurity', 'ciphers') |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
184 ciphers = ui.config('hostsecurity', '%s:ciphers' % hostname, ciphers) |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
185 s['ciphers'] = ciphers |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
186 |
29267
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
187 # 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
|
188 # of <alg>:<fingerprint> strings. |
34775
17919e9006b9
configitems: register the 'hostsecurity.*:fingerprints' config
Boris Feld <boris.feld@octobus.net>
parents:
34748
diff
changeset
|
189 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname) |
29267
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
190 for fingerprint in fingerprints: |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
191 if not (fingerprint.startswith(('sha1:', 'sha256:', 'sha512:'))): |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
192 raise error.Abort(_('invalid fingerprint for %s: %s') % ( |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
193 hostname, fingerprint), |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
194 hint=_('must begin with "sha1:", "sha256:", ' |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
195 'or "sha512:"')) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
196 |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
197 alg, fingerprint = fingerprint.split(':', 1) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
198 fingerprint = fingerprint.replace(':', '').lower() |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
199 s['certfingerprints'].append((alg, fingerprint)) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
200 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
201 # Fingerprints from [hostfingerprints] are always SHA-1. |
34748
8c1d0fe1f431
configitems: register the 'hostfingerprints' section
Boris Feld <boris.feld@octobus.net>
parents:
34647
diff
changeset
|
202 for fingerprint in ui.configlist('hostfingerprints', hostname): |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
203 fingerprint = fingerprint.replace(':', '').lower() |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
204 s['certfingerprints'].append(('sha1', fingerprint)) |
29268
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
205 s['legacyfingerprint'] = True |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
206 |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
207 # 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
|
208 # matters. No need to validate CA certs. |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
209 if s['certfingerprints']: |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
210 s['verifymode'] = ssl.CERT_NONE |
29447
13edc11eb7b7
sslutil: don't load default certificates when they aren't relevant
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29446
diff
changeset
|
211 s['allowloaddefaultcerts'] = False |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
212 |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
213 # 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
|
214 elif ui.insecureconnections: |
29287
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
215 s['disablecertverification'] = True |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
216 s['verifymode'] = ssl.CERT_NONE |
29447
13edc11eb7b7
sslutil: don't load default certificates when they aren't relevant
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29446
diff
changeset
|
217 s['allowloaddefaultcerts'] = False |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
218 |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
219 if ui.configbool('devel', 'disableloaddefaultcerts'): |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
220 s['allowloaddefaultcerts'] = False |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
221 |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
222 # 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
|
223 # 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
|
224 # being performed. |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
225 cafile = ui.config('hostsecurity', '%s:verifycertsfile' % hostname) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
226 if s['certfingerprints'] and cafile: |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
227 ui.warn(_('(hostsecurity.%s:verifycertsfile ignored when host ' |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
228 'fingerprints defined; using host fingerprints for ' |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
229 'verification)\n') % hostname) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
230 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
231 # 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
|
232 # makes it not necessary. |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
233 if s['verifymode'] is None: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
234 # 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
|
235 if cafile: |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
236 cafile = util.expandpath(cafile) |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
237 if not os.path.exists(cafile): |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
238 raise error.Abort(_('path specified by %s does not exist: %s') % |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
239 ('hostsecurity.%s:verifycertsfile' % hostname, |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
240 cafile)) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
241 s['cafile'] = cafile |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
242 else: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
243 # Find global certificates file in config. |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
244 cafile = ui.config('web', 'cacerts') |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
245 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
246 if cafile: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
247 cafile = util.expandpath(cafile) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
248 if not os.path.exists(cafile): |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
249 raise error.Abort(_('could not find web.cacerts: %s') % |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
250 cafile) |
29484
53b7fc7cc2bb
sslutil: don't attempt to find default CA certs file when told not to
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29483
diff
changeset
|
251 elif s['allowloaddefaultcerts']: |
29482
4e72995f6c9c
sslutil: change comment and logged message for found ca cert file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29459
diff
changeset
|
252 # 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
|
253 cafile = _defaultcacerts(ui) |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
254 if cafile: |
29482
4e72995f6c9c
sslutil: change comment and logged message for found ca cert file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29459
diff
changeset
|
255 ui.debug('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
|
256 |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
257 s['cafile'] = cafile |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
258 |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
259 # 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
|
260 # verification hasn't been disabled above. |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
261 if cafile or (_canloaddefaultcerts and s['allowloaddefaultcerts']): |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
262 s['verifymode'] = ssl.CERT_REQUIRED |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
263 else: |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
264 # 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
|
265 # 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
|
266 # 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
|
267 # 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
|
268 # user). |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
269 s['verifymode'] = ssl.CERT_NONE |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
270 |
29507
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
271 assert s['protocol'] is not None |
29508
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
272 assert s['ctxoptions'] is not None |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
273 assert s['verifymode'] is not None |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
274 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
275 return s |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
276 |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
277 def protocolsettings(protocol): |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
278 """Resolve the protocol for a config value. |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
279 |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
280 Returns a 3-tuple of (protocol, options, ui value) where the first |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
281 2 items are values used by SSLContext and the last is a string value |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
282 of the ``minimumprotocol`` config option equivalent. |
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
283 """ |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
284 if protocol not in configprotocols: |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
285 raise ValueError('protocol value not supported: %s' % protocol) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
286 |
29578
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
287 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
288 # that both ends support, including TLS protocols. On legacy stacks, |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
289 # the highest it likely goes is TLS 1.0. On modern stacks, it can |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
290 # support TLS 1.2. |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
291 # |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
292 # The PROTOCOL_TLSv* constants select a specific TLS version |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
293 # only (as opposed to multiple versions). So the method for |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
294 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
295 # disable protocols via SSLContext.options and OP_NO_* constants. |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
296 # However, SSLContext.options doesn't work unless we have the |
4a4b8d3b4e43
sslutil: move comment about protocol constants
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29577
diff
changeset
|
297 # full/real SSLContext available to us. |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32273
diff
changeset
|
298 if supportedprotocols == {'tls1.0'}: |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
299 if protocol != 'tls1.0': |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
300 raise error.Abort(_('current Python does not support protocol ' |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
301 'setting %s') % protocol, |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
302 hint=_('upgrade Python or disable setting since ' |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
303 'only TLS 1.0 is supported')) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
304 |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
305 return ssl.PROTOCOL_TLSv1, 0, 'tls1.0' |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
306 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
307 # WARNING: returned options don't work unless the modern ssl module |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
308 # is available. Be careful when adding options here. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
309 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
310 # SSLv2 and SSLv3 are broken. We ban them outright. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
311 options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
312 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
313 if protocol == 'tls1.0': |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
314 # Defaults above are to use TLS 1.0+ |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
315 pass |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
316 elif protocol == 'tls1.1': |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
317 options |= ssl.OP_NO_TLSv1 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
318 elif protocol == 'tls1.2': |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
319 options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
320 else: |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
321 raise error.Abort(_('this should not happen')) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
322 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
323 # Prevent CRIME. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
324 # There is no guarantee this attribute is defined on the module. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
325 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
326 |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
327 return ssl.PROTOCOL_SSLv23, options, protocol |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
328 |
29249
cca59ef27e60
sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
329 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
|
330 """Add SSL/TLS to a socket. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
331 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
332 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
|
333 choices based on what security options are available. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
334 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
335 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
|
336 the following additional arguments: |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
337 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
338 * 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
|
339 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
|
340 to use. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
341 """ |
29224
7424f4294199
sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29115
diff
changeset
|
342 if not serverhostname: |
29389
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
29341
diff
changeset
|
343 raise error.Abort(_('serverhostname argument is required')) |
29224
7424f4294199
sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29115
diff
changeset
|
344 |
33381
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
345 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
|
346 if f and not os.path.exists(f): |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
347 raise error.Abort(_('certificate file (%s) does not exist; ' |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
348 'cannot connect to %s') % (f, serverhostname), |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
349 hint=_('restore missing file or fix references ' |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
350 'in Mercurial config')) |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
351 |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
352 settings = _hostsettings(ui, serverhostname) |
29249
cca59ef27e60
sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
353 |
29557
53de8255ec4e
sslutil: update comment about create_default_context()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29554
diff
changeset
|
354 # 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
|
355 # 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
|
356 # 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
|
357 # 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
|
358 # 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
|
359 # 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
|
360 # choice. |
29507
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
361 sslcontext = SSLContext(settings['protocol']) |
97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29501
diff
changeset
|
362 |
29508
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
363 # This is a no-op unless using modern ssl. |
d65ec41b6384
sslutil: move context options flags to _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29507
diff
changeset
|
364 sslcontext.options |= settings['ctxoptions'] |
28651
4827d07073e6
sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28650
diff
changeset
|
365 |
28848
e330db205b20
sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28653
diff
changeset
|
366 # This still works on our fake SSLContext. |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
367 sslcontext.verify_mode = settings['verifymode'] |
28848
e330db205b20
sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28653
diff
changeset
|
368 |
29577
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
369 if settings['ciphers']: |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
370 try: |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
371 sslcontext.set_ciphers(settings['ciphers']) |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
372 except ssl.SSLError as e: |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
373 raise error.Abort(_('could not set ciphers: %s') % e.args[0], |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
374 hint=_('change cipher string (%s) in config') % |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
375 settings['ciphers']) |
9654ef41f7cc
sslutil: support defining cipher list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29561
diff
changeset
|
376 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
377 if certfile is not None: |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
378 def password(): |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
379 f = keyfile or certfile |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
380 return ui.getpass(_('passphrase for %s: ') % f, '') |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
381 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
|
382 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
383 if settings['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
|
384 try: |
2f7f1e10f840
sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29411
diff
changeset
|
385 sslcontext.load_verify_locations(cafile=settings['cafile']) |
2f7f1e10f840
sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29411
diff
changeset
|
386 except ssl.SSLError as e: |
29927
799e36749f1a
ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29631
diff
changeset
|
387 if len(e.args) == 1: # pypy has different SSLError args |
799e36749f1a
ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29631
diff
changeset
|
388 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
|
389 else: |
799e36749f1a
ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29631
diff
changeset
|
390 msg = e.args[1] |
29446
2f7f1e10f840
sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29411
diff
changeset
|
391 raise error.Abort(_('error loading CA file %s: %s') % ( |
29927
799e36749f1a
ssl: handle a difference in SSLError with pypy (issue5348)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29631
diff
changeset
|
392 settings['cafile'], msg), |
29446
2f7f1e10f840
sslutil: display a better error message when CA file loading fails
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29411
diff
changeset
|
393 hint=_('file is empty or malformed?')) |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
394 caloaded = True |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
395 elif settings['allowloaddefaultcerts']: |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
396 # 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
|
397 sslcontext.load_default_certs() |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
398 caloaded = True |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
399 else: |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
400 caloaded = False |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
401 |
29449
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
402 try: |
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
403 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
|
404 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
|
405 # 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
|
406 # 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
|
407 # a hint to the user. |
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
408 # Only modern ssl module exposes SSLContext.get_ca_certs() so we can |
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
409 # only show this warning if modern ssl is available. |
31725
c777b12cdc9b
sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents:
31290
diff
changeset
|
410 # 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
|
411 # https://bugs.python.org/issue20916#msg213479. (See issues5313.) |
c777b12cdc9b
sslutil: clarify internal documentation
Matt Harbison <matt_harbison@yahoo.com>
parents:
31290
diff
changeset
|
412 # 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
|
413 # 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
|
414 try: |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
415 if (caloaded and settings['verifymode'] == ssl.CERT_REQUIRED and |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
416 modernssl and not sslcontext.get_ca_certs()): |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
417 ui.warn(_('(an attempt was made to load CA certificates but ' |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
418 'none were loaded; see ' |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
419 'https://mercurial-scm.org/wiki/SecureConnections ' |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
420 'for how to configure Mercurial to avoid this ' |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
421 'error)\n')) |
387bdd53c77e
sslutil: work around SSLContext.get_ca_certs bug on Windows (issue5313)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29619
diff
changeset
|
422 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
|
423 pass |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
424 # Try to print more helpful error messages for known failures. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
425 if util.safehasattr(e, 'reason'): |
29619
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
426 # 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
|
427 # 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
|
428 # 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
|
429 # 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
|
430 # reason, try to emit an actionable warning. |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
431 if e.reason == 'UNSUPPORTED_PROTOCOL': |
29619
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
432 # We attempted TLS 1.0+. |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
433 if settings['protocolui'] == 'tls1.0': |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
434 # 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
|
435 # 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
|
436 # 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
|
437 # 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
|
438 # several years from when this comment was written). |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32273
diff
changeset
|
439 if supportedprotocols != {'tls1.0'}: |
29619
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
440 ui.warn(_( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
441 '(could not communicate with %s using security ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
442 'protocols %s; if you are using a modern Mercurial ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
443 'version, consider contacting the operator of this ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
444 'server; see ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
445 'https://mercurial-scm.org/wiki/SecureConnections ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
446 'for more info)\n') % ( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
447 serverhostname, |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
448 ', '.join(sorted(supportedprotocols)))) |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
449 else: |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
450 ui.warn(_( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
451 '(could not communicate with %s using TLS 1.0; the ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
452 'likely cause of this is the server no longer ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
453 'supports TLS 1.0 because it has known security ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
454 'vulnerabilities; see ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
455 'https://mercurial-scm.org/wiki/SecureConnections ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
456 'for more info)\n') % serverhostname) |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
457 else: |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
458 # 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
|
459 # 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
|
460 # 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
|
461 # offer. |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
462 ui.warn(_( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
463 '(could not negotiate a common security protocol (%s+) ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
464 'with %s; the likely cause is Mercurial is configured ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
465 'to be more secure than the server can support)\n') % ( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
466 settings['protocolui'], serverhostname)) |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
467 ui.warn(_('(consider contacting the operator of this ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
468 'server and ask them to support modern TLS ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
469 'protocol versions; or, set ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
470 'hostsecurity.%s:minimumprotocol=tls1.0 to allow ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
471 'use of legacy, less secure protocols when ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
472 'communicating with this server)\n') % |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
473 serverhostname) |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
474 ui.warn(_( |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
475 '(see https://mercurial-scm.org/wiki/SecureConnections ' |
53e80179bd6a
sslutil: improve messaging around unsupported protocols (issue5303)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29618
diff
changeset
|
476 'for more info)\n')) |
33494
30f2715be123
sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents:
33381
diff
changeset
|
477 |
30f2715be123
sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents:
33381
diff
changeset
|
478 elif (e.reason == 'CERTIFICATE_VERIFY_FAILED' and |
34645 | 479 pycompat.iswindows): |
33494
30f2715be123
sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents:
33381
diff
changeset
|
480 |
30f2715be123
sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents:
33381
diff
changeset
|
481 ui.warn(_('(the full certificate chain may not be available ' |
30f2715be123
sslutil: inform the user about how to fix an incomplete certificate chain
Matt Harbison <matt_harbison@yahoo.com>
parents:
33381
diff
changeset
|
482 'locally; see "hg help debugssl")\n')) |
29449
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
483 raise |
5b71a8d7f7ff
sslutil: emit warning when no CA certificates loaded
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29447
diff
changeset
|
484 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
485 # 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
|
486 # closed |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
487 # - see http://bugs.python.org/issue13721 |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
488 if not sslsocket.cipher(): |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
489 raise error.Abort(_('ssl connection failed')) |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
490 |
29225
b115eed11780
sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29224
diff
changeset
|
491 sslsocket._hgstate = { |
b115eed11780
sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29224
diff
changeset
|
492 'caloaded': caloaded, |
29226
33006bd6a1d7
sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29225
diff
changeset
|
493 'hostname': serverhostname, |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
494 'settings': settings, |
29226
33006bd6a1d7
sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29225
diff
changeset
|
495 '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
|
496 } |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
497 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
498 return sslsocket |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
499 |
29554
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
500 def wrapserversocket(sock, ui, certfile=None, keyfile=None, cafile=None, |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
501 requireclientcert=False): |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
502 """Wrap a socket for use by servers. |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
503 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
504 ``certfile`` and ``keyfile`` specify the files containing the certificate's |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
505 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
|
506 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
|
507 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
508 ``cafile`` defines the path to certificate authorities. |
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 ``requireclientcert`` specifies whether to require client certificates. |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
511 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
512 Typically ``cafile`` is only defined if ``requireclientcert`` is true. |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
513 """ |
33381
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
514 # 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
|
515 # 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
|
516 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
|
517 if f and not os.path.exists(f): |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
518 raise error.Abort(_('referenced certificate file (%s) does not ' |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
519 'exist') % f) |
3bdbbadddecc
sslutil: check for missing certificate and key files (issue5598)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32291
diff
changeset
|
520 |
29618
fbf4adc0d8f2
sslutil: capture string string representation of protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29617
diff
changeset
|
521 protocol, options, _protocolui = protocolsettings('tls1.0') |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
522 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
523 # This config option is intended for use in tests only. It is a giant |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
524 # footgun to kill security. Don't define it. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
525 exactprotocol = ui.config('devel', 'serverexactprotocol') |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
526 if exactprotocol == 'tls1.0': |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
527 protocol = ssl.PROTOCOL_TLSv1 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
528 elif exactprotocol == 'tls1.1': |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
529 if 'tls1.1' not in supportedprotocols: |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
530 raise error.Abort(_('TLS 1.1 not supported by this Python')) |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
531 protocol = ssl.PROTOCOL_TLSv1_1 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
532 elif exactprotocol == 'tls1.2': |
29601
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
533 if 'tls1.2' not in supportedprotocols: |
6cff2ac0ccb9
sslutil: more robustly detect protocol support
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29578
diff
changeset
|
534 raise error.Abort(_('TLS 1.2 not supported by this Python')) |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
535 protocol = ssl.PROTOCOL_TLSv1_2 |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
536 elif exactprotocol: |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
537 raise error.Abort(_('invalid value for serverexactprotocol: %s') % |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
538 exactprotocol) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
539 |
29554
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
540 if modernssl: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
541 # We /could/ use create_default_context() here since it doesn't load |
29559
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
542 # CAs when configured for client auth. However, it is hard-coded to |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
543 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
544 sslcontext = SSLContext(protocol) |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
545 sslcontext.options |= options |
7dec5e441bf7
sslutil: config option to specify TLS protocol version
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29558
diff
changeset
|
546 |
29554
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
547 # Improve forward secrecy. |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
548 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
549 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
550 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
551 # Use the list of more secure ciphers if found in the ssl module. |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
552 if util.safehasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'): |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
553 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
554 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
555 else: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
556 sslcontext = SSLContext(ssl.PROTOCOL_TLSv1) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
557 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
558 if requireclientcert: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
559 sslcontext.verify_mode = ssl.CERT_REQUIRED |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
560 else: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
561 sslcontext.verify_mode = ssl.CERT_NONE |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
562 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
563 if certfile or keyfile: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
564 sslcontext.load_cert_chain(certfile=certfile, keyfile=keyfile) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
565 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
566 if cafile: |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
567 sslcontext.load_verify_locations(cafile=cafile) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
568 |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
569 return sslcontext.wrap_socket(sock, server_side=True) |
4a7b0c696fbc
sslutil: implement wrapserversocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29537
diff
changeset
|
570 |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
571 class wildcarderror(Exception): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
572 """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
|
573 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
574 def _dnsnamematch(dn, hostname, maxwildcards=1): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
575 """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
|
576 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
577 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
|
578 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
579 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
|
580 the value in ``dn``. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
581 """ |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
582 pats = [] |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
583 if not dn: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
584 return False |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
585 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
586 pieces = dn.split(r'.') |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
587 leftmost = pieces[0] |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
588 remainder = pieces[1:] |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
589 wildcards = leftmost.count('*') |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
590 if wildcards > maxwildcards: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
591 raise wildcarderror( |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
592 _('too many wildcards in certificate DNS name: %s') % dn) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
593 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
594 # 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
|
595 if not wildcards: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
596 return dn.lower() == hostname.lower() |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
597 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
598 # 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
|
599 # 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
|
600 # the wildcard character comprises a label other than the left-most label. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
601 if leftmost == '*': |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
602 # 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
|
603 # fragment. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
604 pats.append('[^.]+') |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
605 elif leftmost.startswith('xn--') or hostname.startswith('xn--'): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
606 # 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
|
607 # 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
|
608 # 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
|
609 # U-label of an internationalized domain name. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
610 pats.append(re.escape(leftmost)) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
611 else: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
612 # Otherwise, '*' matches any dotless string, e.g. www* |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
613 pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
614 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
615 # 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
|
616 for frag in remainder: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
617 pats.append(re.escape(frag)) |
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 pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
620 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
|
621 |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
622 def _verifycert(cert, hostname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
623 '''Verify that cert (in socket.getpeercert() format) matches hostname. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
624 CRLs is not handled. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
625 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
626 Returns error message if any problems are found and None on success. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
627 ''' |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
628 if not cert: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
629 return _('no certificate received') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
630 |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
631 dnsnames = [] |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
632 san = cert.get('subjectAltName', []) |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
633 for key, value in san: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
634 if key == 'DNS': |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
635 try: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
636 if _dnsnamematch(value, hostname): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
637 return |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
638 except wildcarderror as e: |
29460
a7d1532b26a1
sslutil: don't access message attribute in exception (issue5285)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29452
diff
changeset
|
639 return e.args[0] |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
640 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
641 dnsnames.append(value) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
642 |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
643 if not dnsnames: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
644 # The subject is only checked when there is no DNS in subjectAltName. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
645 for sub in cert.get('subject', []): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
646 for key, value in sub: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
647 # 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
|
648 # be used. |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
649 if key == 'commonName': |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
30228
diff
changeset
|
650 # 'subject' entries are unicode. |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
651 try: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
652 value = value.encode('ascii') |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
653 except UnicodeEncodeError: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
654 return _('IDN in certificate not supported') |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
655 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
656 try: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
657 if _dnsnamematch(value, hostname): |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
658 return |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
659 except wildcarderror as e: |
29460
a7d1532b26a1
sslutil: don't access message attribute in exception (issue5285)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29452
diff
changeset
|
660 return e.args[0] |
29452
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
661 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
662 dnsnames.append(value) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
663 |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
664 if len(dnsnames) > 1: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
665 return _('certificate is for %s') % ', '.join(dnsnames) |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
666 elif len(dnsnames) == 1: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
667 return _('certificate is for %s') % dnsnames[0] |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
668 else: |
26a5d605b868
sslutil: synchronize hostname matching logic with CPython
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29042
diff
changeset
|
669 return _('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
|
670 |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
671 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
|
672 """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
|
673 * 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
|
674 system |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
675 * 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
|
676 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
|
677 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
|
678 """ |
34647 | 679 if (not pycompat.isdarwin or util.mainfrozen() or |
680 not pycompat.sysexecutable): | |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
681 return False |
30669
10b17ed9b591
py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30641
diff
changeset
|
682 exe = os.path.realpath(pycompat.sysexecutable).lower() |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
683 return (exe.startswith('/usr/bin/python') or |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
684 exe.startswith('/system/library/frameworks/python.framework/')) |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
685 |
29500
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
686 _systemcacertpaths = [ |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
687 # RHEL, CentOS, and Fedora |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
688 '/etc/pki/tls/certs/ca-bundle.trust.crt', |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
689 # Debian, Ubuntu, Gentoo |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
690 '/etc/ssl/certs/ca-certificates.crt', |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
691 ] |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
692 |
29483
918dce4b8c26
sslutil: pass ui to _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29482
diff
changeset
|
693 def _defaultcacerts(ui): |
29488
1c26b9ce66f8
sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29487
diff
changeset
|
694 """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
|
695 |
1c26b9ce66f8
sslutil: expand _defaultcacerts docstring to note calling assumptions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29487
diff
changeset
|
696 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
|
697 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
|
698 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
|
699 |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
700 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
|
701 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
|
702 """ |
30228
b9f7b0c10027
sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
29927
diff
changeset
|
703 # 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
|
704 # 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
|
705 try: |
a62c00f6dd04
sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29484
diff
changeset
|
706 import certifi |
a62c00f6dd04
sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29484
diff
changeset
|
707 certs = certifi.where() |
30228
b9f7b0c10027
sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
29927
diff
changeset
|
708 if os.path.exists(certs): |
b9f7b0c10027
sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
29927
diff
changeset
|
709 ui.debug('using ca certificates from certifi\n') |
b9f7b0c10027
sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
29927
diff
changeset
|
710 return certs |
b9f7b0c10027
sslutil: guard against broken certifi installations (issue5406)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
29927
diff
changeset
|
711 except (ImportError, AttributeError): |
29486
a62c00f6dd04
sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29484
diff
changeset
|
712 pass |
a62c00f6dd04
sslutil: use certificates provided by certifi if available
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29484
diff
changeset
|
713 |
29489
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
714 # On Windows, only the modern ssl module is capable of loading the system |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
715 # CA certificates. If we're not capable of doing that, emit a warning |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
716 # because we'll get a certificate verification error later and the lack |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
717 # of loaded CA certificates will be the reason why. |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
718 # Assertion: this code is only called if certificates are being verified. |
34645 | 719 if pycompat.iswindows: |
29489
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
720 if not _canloaddefaultcerts: |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
721 ui.warn(_('(unable to load Windows CA certificates; see ' |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
722 'https://mercurial-scm.org/wiki/SecureConnections for ' |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
723 'how to configure Mercurial to avoid this message)\n')) |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
724 |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
725 return None |
54ad81b0665f
sslutil: handle default CA certificate loading on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29488
diff
changeset
|
726 |
29487
cdcb5747dc88
sslutil: document the Apple OpenSSL cert trick
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29486
diff
changeset
|
727 # 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
|
728 # 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
|
729 # trick. |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
730 if _plainapplepython(): |
31074
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30669
diff
changeset
|
731 dummycert = os.path.join( |
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30669
diff
changeset
|
732 os.path.dirname(pycompat.fsencode(__file__)), 'dummycert.pem') |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
733 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
|
734 return dummycert |
29107
c8fbfb9163ce
sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29106
diff
changeset
|
735 |
29499
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
736 # The Apple OpenSSL trick isn't available to us. If Python isn't able to |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
737 # load system certs, we're out of luck. |
34647 | 738 if pycompat.isdarwin: |
29499
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
739 # FUTURE Consider looking for Homebrew or MacPorts installed certs |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
740 # files. Also consider exporting the keychain certs to a file during |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
741 # Mercurial install. |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
742 if not _canloaddefaultcerts: |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
743 ui.warn(_('(unable to load CA certificates; see ' |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
744 'https://mercurial-scm.org/wiki/SecureConnections for ' |
9c5325c79683
sslutil: issue warning when unable to load certificates on OS X
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29489
diff
changeset
|
745 'how to configure Mercurial to avoid this message)\n')) |
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
|
746 return None |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
747 |
29537
5f8b36d5a6ec
sslutil: add assertion to prevent accidental CA usage on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29508
diff
changeset
|
748 # / is writable on Windows. Out of an abundance of caution make sure |
5f8b36d5a6ec
sslutil: add assertion to prevent accidental CA usage on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29508
diff
changeset
|
749 # we're not on Windows because paths from _systemcacerts could be installed |
5f8b36d5a6ec
sslutil: add assertion to prevent accidental CA usage on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29508
diff
changeset
|
750 # by non-admin users. |
34645 | 751 assert not pycompat.iswindows |
29537
5f8b36d5a6ec
sslutil: add assertion to prevent accidental CA usage on Windows
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29508
diff
changeset
|
752 |
29500
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
753 # Try to find CA certificates in well-known locations. We print a warning |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
754 # when using a found file because we don't want too much silent magic |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
755 # for security settings. The expectation is that proper Mercurial |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
756 # installs will have the CA certs path defined at install time and the |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
757 # installer/packager will make an appropriate decision on the user's |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
758 # behalf. We only get here and perform this setting as a feature of |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
759 # last resort. |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
760 if not _canloaddefaultcerts: |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
761 for path in _systemcacertpaths: |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
762 if os.path.isfile(path): |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
763 ui.warn(_('(using CA certificates from %s; if you see this ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
764 'message, your Mercurial install is not properly ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
765 'configured; see ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
766 'https://mercurial-scm.org/wiki/SecureConnections ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
767 'for how to configure Mercurial to avoid this ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
768 'message)\n') % path) |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
769 return path |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
770 |
29500
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
771 ui.warn(_('(unable to load CA certificates; see ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
772 'https://mercurial-scm.org/wiki/SecureConnections for ' |
4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29499
diff
changeset
|
773 'how to configure Mercurial to avoid this message)\n')) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
774 |
29107
c8fbfb9163ce
sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29106
diff
changeset
|
775 return None |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
776 |
29286
a05a91a3f120
sslutil: remove "strict" argument from validatesocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29268
diff
changeset
|
777 def validatesocket(sock): |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
30228
diff
changeset
|
778 """Validate a socket meets security requirements. |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
779 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
780 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
|
781 """ |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
782 host = sock._hgstate['hostname'] |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
783 ui = sock._hgstate['ui'] |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
784 settings = sock._hgstate['settings'] |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
785 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
786 try: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
787 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
|
788 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
|
789 except AttributeError: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
790 raise error.Abort(_('%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
|
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 not peercert: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
793 raise error.Abort(_('%s certificate error: ' |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
794 'no certificate received') % host) |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
795 |
29289
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
796 if settings['disablecertverification']: |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
797 # 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
|
798 # 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
|
799 # 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
|
800 # 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
|
801 # 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
|
802 # value. |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
803 ui.warn(_('warning: connection security to %s is disabled per current ' |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
804 'settings; communication is susceptible to eavesdropping ' |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
805 'and tampering\n') % host) |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
806 return |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
807 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
808 # 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
|
809 # validate the remote cert. |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
810 peerfingerprints = { |
29341
0d83ad967bf8
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents:
29334
diff
changeset
|
811 'sha1': hashlib.sha1(peercert).hexdigest(), |
0d83ad967bf8
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents:
29334
diff
changeset
|
812 'sha256': hashlib.sha256(peercert).hexdigest(), |
0d83ad967bf8
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents:
29334
diff
changeset
|
813 'sha512': hashlib.sha512(peercert).hexdigest(), |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
814 } |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
815 |
29290
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
816 def fmtfingerprint(s): |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
817 return ':'.join([s[x:x + 2] for x in range(0, len(s), 2)]) |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
818 |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
819 nicefingerprint = 'sha256:%s' % fmtfingerprint(peerfingerprints['sha256']) |
28850
3819c349b194
sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28849
diff
changeset
|
820 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
821 if settings['certfingerprints']: |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
822 for hash, fingerprint in settings['certfingerprints']: |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
823 if peerfingerprints[hash].lower() == fingerprint: |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
824 ui.debug('%s certificate matched fingerprint %s:%s\n' % |
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
825 (host, hash, fmtfingerprint(fingerprint))) |
31290
f819aa9dbbf9
sslutil: issue warning when [hostfingerprint] is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31074
diff
changeset
|
826 if settings['legacyfingerprint']: |
f819aa9dbbf9
sslutil: issue warning when [hostfingerprint] is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31074
diff
changeset
|
827 ui.warn(_('(SHA-1 fingerprint for %s found in legacy ' |
f819aa9dbbf9
sslutil: issue warning when [hostfingerprint] is used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31074
diff
changeset
|
828 '[hostfingerprints] section; ' |
32273
2e455cbeac50
sslutil: tweak the legacy [hostfingerprints] warning message
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32247
diff
changeset
|
829 'if you trust this fingerprint, remove the old ' |
2e455cbeac50
sslutil: tweak the legacy [hostfingerprints] warning message
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32247
diff
changeset
|
830 'SHA-1 fingerprint from [hostfingerprints] and ' |
2e455cbeac50
sslutil: tweak the legacy [hostfingerprints] warning message
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32247
diff
changeset
|
831 'add the following entry to the new ' |
2e455cbeac50
sslutil: tweak the legacy [hostfingerprints] warning message
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32247
diff
changeset
|
832 '[hostsecurity] section: %s:fingerprints=%s)\n') % |
2e455cbeac50
sslutil: tweak the legacy [hostfingerprints] warning message
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32247
diff
changeset
|
833 (host, host, nicefingerprint)) |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
834 return |
28850
3819c349b194
sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28849
diff
changeset
|
835 |
29293
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
836 # Pinned fingerprint didn't match. This is a fatal error. |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
837 if settings['legacyfingerprint']: |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
838 section = 'hostfingerprint' |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
839 nice = fmtfingerprint(peerfingerprints['sha1']) |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
840 else: |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
841 section = 'hostsecurity' |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
842 nice = '%s:%s' % (hash, fmtfingerprint(peerfingerprints[hash])) |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
843 raise error.Abort(_('certificate for %s has unexpected ' |
29293
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
844 'fingerprint %s') % (host, nice), |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
845 hint=_('check %s configuration') % section) |
28850
3819c349b194
sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28849
diff
changeset
|
846 |
29411
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
847 # 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
|
848 # for the cert so abort. |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
849 if not sock._hgstate['caloaded']: |
29411
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
850 raise error.Abort( |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
851 _('unable to verify security of %s (no loaded CA certificates); ' |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
852 'refusing to connect') % host, |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
853 hint=_('see https://mercurial-scm.org/wiki/SecureConnections for ' |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
854 'how to configure Mercurial to avoid this error or set ' |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
855 'hostsecurity.%s:fingerprints=%s to trust this server') % |
e1778b9c8d53
sslutil: abort when unable to verify peer connection (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29410
diff
changeset
|
856 (host, nicefingerprint)) |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
857 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
858 msg = _verifycert(peercert2, host) |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
859 if msg: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
860 raise error.Abort(_('%s certificate error: %s') % (host, msg), |
29292
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
861 hint=_('set hostsecurity.%s:certfingerprints=%s ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
862 'config setting or use --insecure to connect ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
863 'insecurely') % |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
864 (host, nicefingerprint)) |