equal
deleted
inserted
replaced
11 |
11 |
12 import hashlib |
12 import hashlib |
13 import os |
13 import os |
14 import re |
14 import re |
15 import ssl |
15 import ssl |
16 import sys |
|
17 |
16 |
18 from .i18n import _ |
17 from .i18n import _ |
19 from . import ( |
18 from . import ( |
20 error, |
19 error, |
21 pycompat, |
20 pycompat, |
56 modernssl = False |
55 modernssl = False |
57 _canloaddefaultcerts = False |
56 _canloaddefaultcerts = False |
58 |
57 |
59 # We implement SSLContext using the interface from the standard library. |
58 # We implement SSLContext using the interface from the standard library. |
60 class SSLContext(object): |
59 class SSLContext(object): |
61 # ssl.wrap_socket gained the "ciphers" named argument in 2.7. |
|
62 _supportsciphers = sys.version_info >= (2, 7) |
|
63 |
|
64 def __init__(self, protocol): |
60 def __init__(self, protocol): |
65 # From the public interface of SSLContext |
61 # From the public interface of SSLContext |
66 self.protocol = protocol |
62 self.protocol = protocol |
67 self.check_hostname = False |
63 self.check_hostname = False |
68 self.options = 0 |
64 self.options = 0 |
90 raise error.Abort(_('cadata not supported')) |
86 raise error.Abort(_('cadata not supported')) |
91 |
87 |
92 self._cacerts = cafile |
88 self._cacerts = cafile |
93 |
89 |
94 def set_ciphers(self, ciphers): |
90 def set_ciphers(self, ciphers): |
95 if not self._supportsciphers: |
|
96 raise error.Abort(_('setting ciphers in [hostsecurity] is not ' |
|
97 'supported by this version of Python'), |
|
98 hint=_('remove the config option or run ' |
|
99 'Mercurial with a modern Python ' |
|
100 'version (preferred)')) |
|
101 |
|
102 self._ciphers = ciphers |
91 self._ciphers = ciphers |
103 |
92 |
104 def wrap_socket(self, socket, server_hostname=None, server_side=False): |
93 def wrap_socket(self, socket, server_hostname=None, server_side=False): |
105 # server_hostname is unique to SSLContext.wrap_socket and is used |
94 # server_hostname is unique to SSLContext.wrap_socket and is used |
106 # for SNI in that context. So there's nothing for us to do with it |
95 # for SNI in that context. So there's nothing for us to do with it |
111 'certfile': self._certfile, |
100 'certfile': self._certfile, |
112 'server_side': server_side, |
101 'server_side': server_side, |
113 'cert_reqs': self.verify_mode, |
102 'cert_reqs': self.verify_mode, |
114 'ssl_version': self.protocol, |
103 'ssl_version': self.protocol, |
115 'ca_certs': self._cacerts, |
104 'ca_certs': self._cacerts, |
|
105 'ciphers': self._ciphers, |
116 } |
106 } |
117 |
|
118 if self._supportsciphers: |
|
119 args['ciphers'] = self._ciphers |
|
120 |
107 |
121 return ssl.wrap_socket(socket, **args) |
108 return ssl.wrap_socket(socket, **args) |
122 |
109 |
123 def _hostsettings(ui, hostname): |
110 def _hostsettings(ui, hostname): |
124 """Obtain security settings for a hostname. |
111 """Obtain security settings for a hostname. |