Show More
@@ -106,8 +106,49 b' except AttributeError:' | |||||
106 |
|
106 | |||
107 | return ssl.wrap_socket(socket, **args) |
|
107 | return ssl.wrap_socket(socket, **args) | |
108 |
|
108 | |||
109 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
|
109 | def _determinecertoptions(ui, host): | |
110 | ca_certs=None, serverhostname=None): |
|
110 | """Determine certificate options for a connections. | |
|
111 | ||||
|
112 | Returns a tuple of (cert_reqs, ca_certs). | |||
|
113 | """ | |||
|
114 | # If a host key fingerprint is on file, it is the only thing that matters | |||
|
115 | # and CA certs don't come into play. | |||
|
116 | hostfingerprint = ui.config('hostfingerprints', host) | |||
|
117 | if hostfingerprint: | |||
|
118 | return ssl.CERT_NONE, None | |||
|
119 | ||||
|
120 | # The code below sets up CA verification arguments. If --insecure is | |||
|
121 | # used, we don't take CAs into consideration, so return early. | |||
|
122 | if ui.insecureconnections: | |||
|
123 | return ssl.CERT_NONE, None | |||
|
124 | ||||
|
125 | cacerts = ui.config('web', 'cacerts') | |||
|
126 | ||||
|
127 | # If a value is set in the config, validate against a path and load | |||
|
128 | # and require those certs. | |||
|
129 | if cacerts: | |||
|
130 | cacerts = util.expandpath(cacerts) | |||
|
131 | if not os.path.exists(cacerts): | |||
|
132 | raise error.Abort(_('could not find web.cacerts: %s') % cacerts) | |||
|
133 | ||||
|
134 | return ssl.CERT_REQUIRED, cacerts | |||
|
135 | ||||
|
136 | # No CAs in config. See if we can load defaults. | |||
|
137 | cacerts = _defaultcacerts() | |||
|
138 | ||||
|
139 | # We found an alternate CA bundle to use. Load it. | |||
|
140 | if cacerts: | |||
|
141 | ui.debug('using %s to enable OS X system CA\n' % cacerts) | |||
|
142 | ui.setconfig('web', 'cacerts', cacerts, 'defaultcacerts') | |||
|
143 | return ssl.CERT_REQUIRED, cacerts | |||
|
144 | ||||
|
145 | # FUTURE this can disappear once wrapsocket() is secure by default. | |||
|
146 | if _canloaddefaultcerts: | |||
|
147 | return ssl.CERT_REQUIRED, None | |||
|
148 | ||||
|
149 | return ssl.CERT_NONE, None | |||
|
150 | ||||
|
151 | def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): | |||
111 | """Add SSL/TLS to a socket. |
|
152 | """Add SSL/TLS to a socket. | |
112 |
|
153 | |||
113 | This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane |
|
154 | This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane | |
@@ -123,6 +164,8 b' def wrapsocket(sock, keyfile, certfile, ' | |||||
123 | if not serverhostname: |
|
164 | if not serverhostname: | |
124 | raise error.Abort('serverhostname argument is required') |
|
165 | raise error.Abort('serverhostname argument is required') | |
125 |
|
166 | |||
|
167 | cert_reqs, ca_certs = _determinecertoptions(ui, serverhostname) | |||
|
168 | ||||
126 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol |
|
169 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | |
127 | # that both ends support, including TLS protocols. On legacy stacks, |
|
170 | # that both ends support, including TLS protocols. On legacy stacks, | |
128 | # the highest it likely goes in TLS 1.0. On modern stacks, it can |
|
171 | # the highest it likely goes in TLS 1.0. On modern stacks, it can | |
@@ -243,53 +286,7 b' def _defaultcacerts():' | |||||
243 | return None |
|
286 | return None | |
244 |
|
287 | |||
245 | def sslkwargs(ui, host): |
|
288 | def sslkwargs(ui, host): | |
246 | """Determine arguments to pass to wrapsocket(). |
|
289 | return {} | |
247 |
|
||||
248 | ``host`` is the hostname being connected to. |
|
|||
249 | """ |
|
|||
250 | kws = {} |
|
|||
251 |
|
||||
252 | # If a host key fingerprint is on file, it is the only thing that matters |
|
|||
253 | # and CA certs don't come into play. |
|
|||
254 | hostfingerprint = ui.config('hostfingerprints', host) |
|
|||
255 | if hostfingerprint: |
|
|||
256 | return kws |
|
|||
257 |
|
||||
258 | # The code below sets up CA verification arguments. If --insecure is |
|
|||
259 | # used, we don't take CAs into consideration, so return early. |
|
|||
260 | if ui.insecureconnections: |
|
|||
261 | return kws |
|
|||
262 |
|
||||
263 | cacerts = ui.config('web', 'cacerts') |
|
|||
264 |
|
||||
265 | # If a value is set in the config, validate against a path and load |
|
|||
266 | # and require those certs. |
|
|||
267 | if cacerts: |
|
|||
268 | cacerts = util.expandpath(cacerts) |
|
|||
269 | if not os.path.exists(cacerts): |
|
|||
270 | raise error.Abort(_('could not find web.cacerts: %s') % cacerts) |
|
|||
271 |
|
||||
272 | kws.update({'ca_certs': cacerts, |
|
|||
273 | 'cert_reqs': ssl.CERT_REQUIRED}) |
|
|||
274 | return kws |
|
|||
275 |
|
||||
276 | # No CAs in config. See if we can load defaults. |
|
|||
277 | cacerts = _defaultcacerts() |
|
|||
278 |
|
||||
279 | # We found an alternate CA bundle to use. Load it. |
|
|||
280 | if cacerts: |
|
|||
281 | ui.debug('using %s to enable OS X system CA\n' % cacerts) |
|
|||
282 | ui.setconfig('web', 'cacerts', cacerts, 'defaultcacerts') |
|
|||
283 | kws.update({'ca_certs': cacerts, |
|
|||
284 | 'cert_reqs': ssl.CERT_REQUIRED}) |
|
|||
285 | return kws |
|
|||
286 |
|
||||
287 | # FUTURE this can disappear once wrapsocket() is secure by default. |
|
|||
288 | if _canloaddefaultcerts: |
|
|||
289 | kws['cert_reqs'] = ssl.CERT_REQUIRED |
|
|||
290 | return kws |
|
|||
291 |
|
||||
292 | return kws |
|
|||
293 |
|
290 | |||
294 | def validatesocket(sock, strict=False): |
|
291 | def validatesocket(sock, strict=False): | |
295 | """Validate a socket meets security requiremnets. |
|
292 | """Validate a socket meets security requiremnets. |
General Comments 0
You need to be logged in to leave comments.
Login now