annotate mercurial/sslutil.py @ 46113:59fa3890d40a

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