Show More
@@ -284,6 +284,6 b' class http2handler(urlreq.httphandler, u' | |||
|
284 | 284 | |
|
285 | 285 | con = HTTPConnection(host, port, use_ssl=True, |
|
286 | 286 | ssl_wrap_socket=sslutil.wrapsocket, |
|
287 |
ssl_validator=sslutil.validat |
|
|
287 | ssl_validator=sslutil.validatesocket, | |
|
288 | 288 | **kwargs) |
|
289 | 289 | return con |
@@ -139,7 +139,7 b' def _smtp(ui):' | |||
|
139 | 139 | s.ehlo() |
|
140 | 140 | if (starttls or smtps) and verifycert: |
|
141 | 141 | ui.note(_('(verifying remote certificate)\n')) |
|
142 |
sslutil.validat |
|
|
142 | sslutil.validatesocket(s.sock, verifycert == 'strict') | |
|
143 | 143 | username = ui.config('smtp', 'username') |
|
144 | 144 | password = ui.config('smtp', 'password') |
|
145 | 145 | if username and not password: |
@@ -291,77 +291,77 b' def sslkwargs(ui, host):' | |||
|
291 | 291 | |
|
292 | 292 | return kws |
|
293 | 293 | |
|
294 | class validator(object): | |
|
295 | def __init__(self, ui=None, host=None): | |
|
296 | pass | |
|
294 | def validatesocket(sock, strict=False): | |
|
295 | """Validate a socket meets security requiremnets. | |
|
297 | 296 |
|
|
298 | def __call__(self, sock, strict=False): | |
|
299 | host = sock._hgstate['hostname'] | |
|
300 |
|
|
|
297 | The passed socket must have been created with ``wrapsocket()``. | |
|
298 | """ | |
|
299 | host = sock._hgstate['hostname'] | |
|
300 | ui = sock._hgstate['ui'] | |
|
301 | 301 | |
|
302 |
|
|
|
303 |
|
|
|
304 |
|
|
|
305 |
|
|
|
306 |
|
|
|
307 |
|
|
|
308 |
|
|
|
302 | if not sock.cipher(): # work around http://bugs.python.org/issue13721 | |
|
303 | raise error.Abort(_('%s ssl connection error') % host) | |
|
304 | try: | |
|
305 | peercert = sock.getpeercert(True) | |
|
306 | peercert2 = sock.getpeercert() | |
|
307 | except AttributeError: | |
|
308 | raise error.Abort(_('%s ssl connection error') % host) | |
|
309 | 309 | |
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
|
310 | if not peercert: | |
|
311 | raise error.Abort(_('%s certificate error: ' | |
|
312 | 'no certificate received') % host) | |
|
313 | 313 | |
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
|
320 |
|
|
|
321 |
|
|
|
322 |
|
|
|
323 |
|
|
|
324 |
|
|
|
325 |
|
|
|
326 |
|
|
|
327 |
|
|
|
328 |
|
|
|
329 |
|
|
|
330 |
|
|
|
331 |
|
|
|
332 |
|
|
|
333 |
|
|
|
314 | # If a certificate fingerprint is pinned, use it and only it to | |
|
315 | # validate the remote cert. | |
|
316 | hostfingerprints = ui.configlist('hostfingerprints', host) | |
|
317 | peerfingerprint = util.sha1(peercert).hexdigest() | |
|
318 | nicefingerprint = ":".join([peerfingerprint[x:x + 2] | |
|
319 | for x in xrange(0, len(peerfingerprint), 2)]) | |
|
320 | if hostfingerprints: | |
|
321 | fingerprintmatch = False | |
|
322 | for hostfingerprint in hostfingerprints: | |
|
323 | if peerfingerprint.lower() == \ | |
|
324 | hostfingerprint.replace(':', '').lower(): | |
|
325 | fingerprintmatch = True | |
|
326 | break | |
|
327 | if not fingerprintmatch: | |
|
328 | raise error.Abort(_('certificate for %s has unexpected ' | |
|
329 | 'fingerprint %s') % (host, nicefingerprint), | |
|
330 | hint=_('check hostfingerprint configuration')) | |
|
331 | ui.debug('%s certificate matched fingerprint %s\n' % | |
|
332 | (host, nicefingerprint)) | |
|
333 | return | |
|
334 | 334 | |
|
335 |
|
|
|
336 |
|
|
|
337 |
|
|
|
338 |
|
|
|
339 |
|
|
|
340 |
|
|
|
341 |
|
|
|
342 |
|
|
|
343 |
|
|
|
344 |
|
|
|
345 |
|
|
|
346 |
|
|
|
335 | # If insecure connections were explicitly requested via --insecure, | |
|
336 | # print a warning and do no verification. | |
|
337 | # | |
|
338 | # It may seem odd that this is checked *after* host fingerprint pinning. | |
|
339 | # This is for backwards compatibility (for now). The message is also | |
|
340 | # the same as below for BC. | |
|
341 | if ui.insecureconnections: | |
|
342 | ui.warn(_('warning: %s certificate with fingerprint %s not ' | |
|
343 | 'verified (check hostfingerprints or web.cacerts ' | |
|
344 | 'config setting)\n') % | |
|
345 | (host, nicefingerprint)) | |
|
346 | return | |
|
347 | 347 | |
|
348 |
|
|
|
349 |
|
|
|
350 |
|
|
|
351 |
|
|
|
352 |
|
|
|
353 |
|
|
|
354 |
|
|
|
355 |
|
|
|
356 |
|
|
|
357 |
|
|
|
358 |
|
|
|
348 | if not sock._hgstate['caloaded']: | |
|
349 | if strict: | |
|
350 | raise error.Abort(_('%s certificate with fingerprint %s not ' | |
|
351 | 'verified') % (host, nicefingerprint), | |
|
352 | hint=_('check hostfingerprints or ' | |
|
353 | 'web.cacerts config setting')) | |
|
354 | else: | |
|
355 | ui.warn(_('warning: %s certificate with fingerprint %s ' | |
|
356 | 'not verified (check hostfingerprints or ' | |
|
357 | 'web.cacerts config setting)\n') % | |
|
358 | (host, nicefingerprint)) | |
|
359 | 359 | |
|
360 |
|
|
|
360 | return | |
|
361 | 361 | |
|
362 |
|
|
|
363 |
|
|
|
364 |
|
|
|
365 |
|
|
|
366 |
|
|
|
367 |
|
|
|
362 | msg = _verifycert(peercert2, host) | |
|
363 | if msg: | |
|
364 | raise error.Abort(_('%s certificate error: %s') % (host, msg), | |
|
365 | hint=_('configure hostfingerprint %s or use ' | |
|
366 | '--insecure to connect insecurely') % | |
|
367 | nicefingerprint) |
@@ -356,7 +356,7 b' if has_https:' | |||
|
356 | 356 | self.sock = sslutil.wrapsocket( |
|
357 | 357 | self.sock, self.key_file, self.cert_file, serverhostname=host, |
|
358 | 358 | **sslutil.sslkwargs(self.ui, host)) |
|
359 |
sslutil.validat |
|
|
359 | sslutil.validatesocket(self.sock) | |
|
360 | 360 | |
|
361 | 361 | class httpshandler(keepalive.KeepAliveHandler, urlreq.httpshandler): |
|
362 | 362 | def __init__(self, ui): |
General Comments 0
You need to be logged in to leave comments.
Login now