Mercurial > hg
annotate mercurial/sslutil.py @ 29336:9368ed12f3c0
scmutil: delete extra newline at EOF
Spotted by my emacs config that cleans up extra whitespace.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Fri, 10 Jun 2016 00:14:10 -0400 |
parents | ecc9b788fd69 |
children | 0d83ad967bf8 |
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 |
25977
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
12 import os |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
13 import ssl |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
14 import sys |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
15 |
696f6e2be282
sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25432
diff
changeset
|
16 from .i18n import _ |
28577
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
17 from . import ( |
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
18 error, |
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
19 util, |
7efff6ce9826
sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28525
diff
changeset
|
20 ) |
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
|
21 |
28647
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
22 # 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
|
23 # 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
|
24 # 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
|
25 # |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
26 # Depending on the version of Python being used, SSL/TLS support is either |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
27 # modern/secure or legacy/insecure. Many operations in this module have |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
28 # separate code paths depending on support in Python. |
834d1c4ba749
sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28577
diff
changeset
|
29 |
26622
9e15286609ae
sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26587
diff
changeset
|
30 hassni = getattr(ssl, 'HAS_SNI', False) |
9e15286609ae
sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26587
diff
changeset
|
31 |
28648
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
32 try: |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
33 OP_NO_SSLv2 = ssl.OP_NO_SSLv2 |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
34 OP_NO_SSLv3 = ssl.OP_NO_SSLv3 |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
35 except AttributeError: |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
36 OP_NO_SSLv2 = 0x1000000 |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
37 OP_NO_SSLv3 = 0x2000000 |
7fc787e5d8ec
sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28647
diff
changeset
|
38 |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
39 try: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
40 # ssl.SSLContext was added in 2.7.9 and presence indicates modern |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
41 # SSL/TLS features are available. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
42 SSLContext = ssl.SSLContext |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
43 modernssl = True |
28650
737863b01d9f
sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28649
diff
changeset
|
44 _canloaddefaultcerts = util.safehasattr(SSLContext, 'load_default_certs') |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
45 except AttributeError: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
46 modernssl = False |
28650
737863b01d9f
sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28649
diff
changeset
|
47 _canloaddefaultcerts = False |
28649
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
48 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
49 # We implement SSLContext using the interface from the standard library. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
50 class SSLContext(object): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
51 # ssl.wrap_socket gained the "ciphers" named argument in 2.7. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
52 _supportsciphers = sys.version_info >= (2, 7) |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
53 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
54 def __init__(self, protocol): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
55 # From the public interface of SSLContext |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
56 self.protocol = protocol |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
57 self.check_hostname = False |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
58 self.options = 0 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
59 self.verify_mode = ssl.CERT_NONE |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
60 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
61 # Used by our implementation. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
62 self._certfile = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
63 self._keyfile = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
64 self._certpassword = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
65 self._cacerts = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
66 self._ciphers = None |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
67 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
68 def load_cert_chain(self, certfile, keyfile=None, password=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
69 self._certfile = certfile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
70 self._keyfile = keyfile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
71 self._certpassword = password |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
72 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
73 def load_default_certs(self, purpose=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
74 pass |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
75 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
76 def load_verify_locations(self, cafile=None, capath=None, cadata=None): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
77 if capath: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
78 raise error.Abort('capath not supported') |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
79 if cadata: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
80 raise error.Abort('cadata not supported') |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
81 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
82 self._cacerts = cafile |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
83 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
84 def set_ciphers(self, ciphers): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
85 if not self._supportsciphers: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
86 raise error.Abort('setting ciphers not supported') |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
87 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
88 self._ciphers = ciphers |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
89 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
90 def wrap_socket(self, socket, server_hostname=None, server_side=False): |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
91 # server_hostname is unique to SSLContext.wrap_socket and is used |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
92 # for SNI in that context. So there's nothing for us to do with it |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
93 # in this legacy code since we don't support SNI. |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
94 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
95 args = { |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
96 'keyfile': self._keyfile, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
97 'certfile': self._certfile, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
98 'server_side': server_side, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
99 'cert_reqs': self.verify_mode, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
100 'ssl_version': self.protocol, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
101 'ca_certs': self._cacerts, |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
102 } |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
103 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
104 if self._supportsciphers: |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
105 args['ciphers'] = self._ciphers |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
106 |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
107 return ssl.wrap_socket(socket, **args) |
7acab42ef184
sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28648
diff
changeset
|
108 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
109 def _hostsettings(ui, hostname): |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
110 """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
|
111 |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
112 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
|
113 """ |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
114 s = { |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
115 # 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
|
116 # if an explicit ``cafile`` is not defined. |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
117 'allowloaddefaultcerts': True, |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
118 # List of 2-tuple of (hash algorithm, hash). |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
119 'certfingerprints': [], |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
120 # 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
|
121 # SSLContext.load_verify_locations(). |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
122 'cafile': None, |
29287
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
123 # Whether certificate verification should be disabled. |
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
124 'disablecertverification': False, |
29268
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
125 # Whether the legacy [hostfingerprints] section has data for this host. |
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
126 'legacyfingerprint': False, |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
127 # ssl.CERT_* constant used by SSLContext.verify_mode. |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
128 'verifymode': None, |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
129 } |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
130 |
29267
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
131 # 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
|
132 # of <alg>:<fingerprint> strings. |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
133 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname, |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
134 []) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
135 for fingerprint in fingerprints: |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
136 if not (fingerprint.startswith(('sha1:', 'sha256:', 'sha512:'))): |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
137 raise error.Abort(_('invalid fingerprint for %s: %s') % ( |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
138 hostname, fingerprint), |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
139 hint=_('must begin with "sha1:", "sha256:", ' |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
140 'or "sha512:"')) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
141 |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
142 alg, fingerprint = fingerprint.split(':', 1) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
143 fingerprint = fingerprint.replace(':', '').lower() |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
144 s['certfingerprints'].append((alg, fingerprint)) |
f0ccb6cde3e5
sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29262
diff
changeset
|
145 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
146 # Fingerprints from [hostfingerprints] are always SHA-1. |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
147 for fingerprint in ui.configlist('hostfingerprints', hostname, []): |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
148 fingerprint = fingerprint.replace(':', '').lower() |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
149 s['certfingerprints'].append(('sha1', fingerprint)) |
29268
f200b58497f1
sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29267
diff
changeset
|
150 s['legacyfingerprint'] = True |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
151 |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
152 # 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
|
153 # matters. No need to validate CA certs. |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
154 if s['certfingerprints']: |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
155 s['verifymode'] = ssl.CERT_NONE |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
156 |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
157 # 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
|
158 elif ui.insecureconnections: |
29287
fbccb334efe7
sslutil: store flag for whether cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29286
diff
changeset
|
159 s['disablecertverification'] = True |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
160 s['verifymode'] = ssl.CERT_NONE |
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
161 |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
162 if ui.configbool('devel', 'disableloaddefaultcerts'): |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
163 s['allowloaddefaultcerts'] = False |
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. |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
168 cafile = ui.config('hostsecurity', '%s:verifycertsfile' % hostname) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
169 if s['certfingerprints'] and cafile: |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
170 ui.warn(_('(hostsecurity.%s:verifycertsfile ignored when host ' |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
171 'fingerprints defined; using host fingerprints for ' |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
172 'verification)\n') % hostname) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
173 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
174 # 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
|
175 # makes it not necessary. |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
176 if s['verifymode'] is None: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
177 # 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
|
178 if cafile: |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
179 cafile = util.expandpath(cafile) |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
180 if not os.path.exists(cafile): |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
181 raise error.Abort(_('path specified by %s does not exist: %s') % |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
182 ('hostsecurity.%s:verifycertsfile' % hostname, |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
183 cafile)) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
184 s['cafile'] = cafile |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
185 else: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
186 # Find global certificates file in config. |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
187 cafile = ui.config('web', 'cacerts') |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
188 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
189 if cafile: |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
190 cafile = util.expandpath(cafile) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
191 if not os.path.exists(cafile): |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
192 raise error.Abort(_('could not find web.cacerts: %s') % |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
193 cafile) |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
194 else: |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
195 # No global CA certs. See if we can load defaults. |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
196 cafile = _defaultcacerts() |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
197 if cafile: |
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
198 ui.debug('using %s to enable OS X system CA\n' % cafile) |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
199 |
29334
ecc9b788fd69
sslutil: per-host config option to define certificates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29293
diff
changeset
|
200 s['cafile'] = cafile |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
201 |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
202 # 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
|
203 # verification hasn't been disabled above. |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
204 if cafile or (_canloaddefaultcerts and s['allowloaddefaultcerts']): |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
205 s['verifymode'] = ssl.CERT_REQUIRED |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
206 else: |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
207 # 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
|
208 # explicitly insecure, and can't load CA certs. Connecting |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
209 # at this point is insecure. But we do it for BC reasons. |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
210 # TODO abort here to make secure by default. |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
211 s['verifymode'] = ssl.CERT_NONE |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
212 |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
213 assert s['verifymode'] is not None |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
214 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
215 return s |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
216 |
29249
cca59ef27e60
sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
217 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
|
218 """Add SSL/TLS to a socket. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
219 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
220 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
|
221 choices based on what security options are available. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
222 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
223 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
|
224 the following additional arguments: |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
225 |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
226 * 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
|
227 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
|
228 to use. |
1eb0bd8adf39
sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28652
diff
changeset
|
229 """ |
29224
7424f4294199
sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29115
diff
changeset
|
230 if not serverhostname: |
7424f4294199
sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29115
diff
changeset
|
231 raise error.Abort('serverhostname argument is required') |
7424f4294199
sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29115
diff
changeset
|
232 |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
233 settings = _hostsettings(ui, serverhostname) |
29249
cca59ef27e60
sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
234 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
235 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
236 # that both ends support, including TLS protocols. On legacy stacks, |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
237 # the highest it likely goes in TLS 1.0. On modern stacks, it can |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
238 # support TLS 1.2. |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
239 # |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
240 # The PROTOCOL_TLSv* constants select a specific TLS version |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
241 # only (as opposed to multiple versions). So the method for |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
242 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
243 # disable protocols via SSLContext.options and OP_NO_* constants. |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
244 # However, SSLContext.options doesn't work unless we have the |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
245 # full/real SSLContext available to us. |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
246 # |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
247 # SSLv2 and SSLv3 are broken. We ban them outright. |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
248 if modernssl: |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
249 protocol = ssl.PROTOCOL_SSLv23 |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
250 else: |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
251 protocol = ssl.PROTOCOL_TLSv1 |
28651
4827d07073e6
sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28650
diff
changeset
|
252 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
253 # TODO use ssl.create_default_context() on modernssl. |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
254 sslcontext = SSLContext(protocol) |
28651
4827d07073e6
sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28650
diff
changeset
|
255 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
256 # 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
|
257 sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 |
28651
4827d07073e6
sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28650
diff
changeset
|
258 |
28848
e330db205b20
sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28653
diff
changeset
|
259 # This still works on our fake SSLContext. |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
260 sslcontext.verify_mode = settings['verifymode'] |
28848
e330db205b20
sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28653
diff
changeset
|
261 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
262 if certfile is not None: |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
263 def password(): |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
264 f = keyfile or certfile |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
265 return ui.getpass(_('passphrase for %s: ') % f, '') |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
266 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
|
267 |
29260
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
268 if settings['cafile'] is not None: |
70bc9912d83d
sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29259
diff
changeset
|
269 sslcontext.load_verify_locations(cafile=settings['cafile']) |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
270 caloaded = True |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
271 elif settings['allowloaddefaultcerts']: |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
272 # 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
|
273 sslcontext.load_default_certs() |
29288
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
274 caloaded = True |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
275 else: |
7dee15dee53c
sslutil: add devel.disableloaddefaultcerts to disable CA loading
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29287
diff
changeset
|
276 caloaded = False |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
277 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
278 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
279 # 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
|
280 # closed |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
281 # - see http://bugs.python.org/issue13721 |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
282 if not sslsocket.cipher(): |
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
283 raise error.Abort(_('ssl connection failed')) |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
284 |
29225
b115eed11780
sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29224
diff
changeset
|
285 sslsocket._hgstate = { |
b115eed11780
sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29224
diff
changeset
|
286 'caloaded': caloaded, |
29226
33006bd6a1d7
sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29225
diff
changeset
|
287 'hostname': serverhostname, |
29259
ec247e8595f9
sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29258
diff
changeset
|
288 'settings': settings, |
29226
33006bd6a1d7
sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29225
diff
changeset
|
289 '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
|
290 } |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
291 |
28652
c617614aefd2
sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28651
diff
changeset
|
292 return sslsocket |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
293 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
294 def _verifycert(cert, hostname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
295 '''Verify that cert (in socket.getpeercert() format) matches hostname. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
296 CRLs is not handled. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
297 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
298 Returns error message if any problems are found and None on success. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
299 ''' |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
300 if not cert: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
301 return _('no certificate received') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
302 dnsname = hostname.lower() |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
303 def matchdnsname(certname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
304 return (certname == dnsname or |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
305 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
306 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
307 san = cert.get('subjectAltName', []) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
308 if san: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
309 certnames = [value.lower() for key, value in san if key == 'DNS'] |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
310 for name in certnames: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
311 if matchdnsname(name): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
312 return None |
14666
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14616
diff
changeset
|
313 if certnames: |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14616
diff
changeset
|
314 return _('certificate is for %s') % ', '.join(certnames) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
315 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
316 # subject is only checked when subjectAltName is empty |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
317 for s in cert.get('subject', []): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
318 key, value = s[0] |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
319 if key == 'commonName': |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
320 try: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
321 # 'subject' entries are unicode |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
322 certname = value.lower().encode('ascii') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
323 except UnicodeEncodeError: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
324 return _('IDN in certificate not supported') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
325 if matchdnsname(certname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
326 return None |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
327 return _('certificate is for %s') % certname |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
328 return _('no commonName or subjectAltName found in certificate') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
329 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
330 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
331 # CERT_REQUIRED means fetch the cert from the server all the time AND |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
332 # validate it against the CA store provided in web.cacerts. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
333 |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
334 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
|
335 """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
|
336 * 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
|
337 system |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
338 * 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
|
339 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
|
340 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
|
341 """ |
24614
241d98d84aed
ssl: resolve symlink before checking for Apple python executable (issue4588)
Yuya Nishihara <yuya@tcha.org>
parents:
24291
diff
changeset
|
342 if sys.platform != 'darwin' or util.mainfrozen() or not sys.executable: |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
343 return False |
24614
241d98d84aed
ssl: resolve symlink before checking for Apple python executable (issue4588)
Yuya Nishihara <yuya@tcha.org>
parents:
24291
diff
changeset
|
344 exe = os.path.realpath(sys.executable).lower() |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
345 return (exe.startswith('/usr/bin/python') or |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
346 exe.startswith('/system/library/frameworks/python.framework/')) |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
347 |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
348 def _defaultcacerts(): |
29107
c8fbfb9163ce
sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29106
diff
changeset
|
349 """return path to default CA certificates or None.""" |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
350 if _plainapplepython(): |
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
351 dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem') |
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
352 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
|
353 return dummycert |
29107
c8fbfb9163ce
sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29106
diff
changeset
|
354 |
c8fbfb9163ce
sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29106
diff
changeset
|
355 return None |
24288
922e087ba158
ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents:
23851
diff
changeset
|
356 |
29286
a05a91a3f120
sslutil: remove "strict" argument from validatesocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29268
diff
changeset
|
357 def validatesocket(sock): |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
358 """Validate a socket meets security requiremnets. |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
359 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
360 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
|
361 """ |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
362 host = sock._hgstate['hostname'] |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
363 ui = sock._hgstate['ui'] |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
364 settings = sock._hgstate['settings'] |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
365 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
366 try: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
367 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
|
368 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
|
369 except AttributeError: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
370 raise error.Abort(_('%s ssl connection error') % host) |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
371 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
372 if not peercert: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
373 raise error.Abort(_('%s certificate error: ' |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
374 'no certificate received') % host) |
28850
3819c349b194
sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28849
diff
changeset
|
375 |
29289
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
376 if settings['disablecertverification']: |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
377 # 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
|
378 # 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
|
379 # 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
|
380 # 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
|
381 # 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
|
382 # value. |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
383 ui.warn(_('warning: connection security to %s is disabled per current ' |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
384 'settings; communication is susceptible to eavesdropping ' |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
385 'and tampering\n') % host) |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
386 return |
3536673a25ae
sslutil: move and change warning when cert verification is disabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29288
diff
changeset
|
387 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
388 # 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
|
389 # validate the remote cert. |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
390 peerfingerprints = { |
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
391 'sha1': util.sha1(peercert).hexdigest(), |
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
392 'sha256': util.sha256(peercert).hexdigest(), |
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
393 'sha512': util.sha512(peercert).hexdigest(), |
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
394 } |
29290
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
395 |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
396 def fmtfingerprint(s): |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
397 return ':'.join([s[x:x + 2] for x in range(0, len(s), 2)]) |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
398 |
01248c37a68e
sslutil: print SHA-256 fingerprint by default
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29289
diff
changeset
|
399 nicefingerprint = 'sha256:%s' % fmtfingerprint(peerfingerprints['sha256']) |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
400 |
29258
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
401 if settings['certfingerprints']: |
6315c1e14f75
sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29253
diff
changeset
|
402 for hash, fingerprint in settings['certfingerprints']: |
29262
dfc4f08aa160
sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29260
diff
changeset
|
403 if peerfingerprints[hash].lower() == fingerprint: |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
404 ui.debug('%s certificate matched fingerprint %s:%s\n' % |
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
405 (host, hash, fmtfingerprint(fingerprint))) |
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
406 return |
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
407 |
29293
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
408 # Pinned fingerprint didn't match. This is a fatal error. |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
409 if settings['legacyfingerprint']: |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
410 section = 'hostfingerprint' |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
411 nice = fmtfingerprint(peerfingerprints['sha1']) |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
412 else: |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
413 section = 'hostsecurity' |
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
414 nice = '%s:%s' % (hash, fmtfingerprint(peerfingerprints[hash])) |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
415 raise error.Abort(_('certificate for %s has unexpected ' |
29293
1b3a0b0c414f
sslutil: print the fingerprint from the last hash used
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29292
diff
changeset
|
416 'fingerprint %s') % (host, nice), |
29291
15e533b7909c
sslutil: refactor code for fingerprint matching
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29290
diff
changeset
|
417 hint=_('check %s configuration') % section) |
28850
3819c349b194
sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28849
diff
changeset
|
418 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
419 if not sock._hgstate['caloaded']: |
29292
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
420 ui.warn(_('warning: certificate for %s not verified ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
421 '(set hostsecurity.%s:certfingerprints=%s or web.cacerts ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
422 'config settings)\n') % (host, host, nicefingerprint)) |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
423 return |
29113
5b9577edf745
sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29112
diff
changeset
|
424 |
29227
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
425 msg = _verifycert(peercert2, host) |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
426 if msg: |
dffe78d80a6c
sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29226
diff
changeset
|
427 raise error.Abort(_('%s certificate error: %s') % (host, msg), |
29292
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
428 hint=_('set hostsecurity.%s:certfingerprints=%s ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
429 'config setting or use --insecure to connect ' |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
430 'insecurely') % |
bc5f55493397
sslutil: make cert fingerprints messages more actionable
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29291
diff
changeset
|
431 (host, nicefingerprint)) |