comparison mercurial/url.py @ 12595:0f83a402faa0

merge with stable
author Mads Kiilerich <mads@kiilerich.com>
date Fri, 01 Oct 2010 00:54:03 +0200
parents 9d45f78c465b f2937d6492c5
children 1393a81b3bdc
comparison
equal deleted inserted replaced
12591:4b9f23885a55 12595:0f83a402faa0
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> 5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
6 # 6 #
7 # This software may be used and distributed according to the terms of the 7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version. 8 # GNU General Public License version 2 or any later version.
9 9
10 import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO 10 import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO, time
11 import __builtin__ 11 import __builtin__
12 from i18n import _ 12 from i18n import _
13 import keepalive, util 13 import keepalive, util
14 14
15 def _urlunparse(scheme, netloc, path, params, query, fragment, url): 15 def _urlunparse(scheme, netloc, path, params, query, fragment, url):
484 484
485 def _start_transaction(self, h, req): 485 def _start_transaction(self, h, req):
486 _generic_start_transaction(self, h, req) 486 _generic_start_transaction(self, h, req)
487 return keepalive.HTTPHandler._start_transaction(self, h, req) 487 return keepalive.HTTPHandler._start_transaction(self, h, req)
488 488
489 def _verifycert(cert, hostname):
490 '''Verify that cert (in socket.getpeercert() format) matches hostname and is
491 valid at this time. CRLs and subjectAltName are not handled.
492
493 Returns error message if any problems are found and None on success.
494 '''
495 if not cert:
496 return _('no certificate received')
497 notafter = cert.get('notAfter')
498 if notafter and time.time() > ssl.cert_time_to_seconds(notafter):
499 return _('certificate expired %s') % notafter
500 notbefore = cert.get('notBefore')
501 if notbefore and time.time() < ssl.cert_time_to_seconds(notbefore):
502 return _('certificate not valid before %s') % notbefore
503 dnsname = hostname.lower()
504 for s in cert.get('subject', []):
505 key, value = s[0]
506 if key == 'commonName':
507 certname = value.lower()
508 if (certname == dnsname or
509 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]):
510 return None
511 return _('certificate is for %s') % certname
512 return _('no commonName found in certificate')
513
489 if has_https: 514 if has_https:
490 class BetterHTTPS(httplib.HTTPSConnection): 515 class BetterHTTPS(httplib.HTTPSConnection):
491 send = keepalive.safesend 516 send = keepalive.safesend
492 517
493 def connect(self): 518 def connect(self):
499 if cacerts: 524 if cacerts:
500 sock = _create_connection((self.host, self.port)) 525 sock = _create_connection((self.host, self.port))
501 self.sock = _ssl_wrap_socket(sock, self.key_file, 526 self.sock = _ssl_wrap_socket(sock, self.key_file,
502 self.cert_file, cert_reqs=CERT_REQUIRED, 527 self.cert_file, cert_reqs=CERT_REQUIRED,
503 ca_certs=cacerts) 528 ca_certs=cacerts)
504 self.ui.debug(_('server identity verification succeeded\n')) 529 msg = _verifycert(self.sock.getpeercert(), self.host)
530 if msg:
531 raise util.Abort('%s certificate error: %s' % (self.host, msg))
532 self.ui.debug(_('%s certificate successfully verified\n') %
533 self.host)
505 else: 534 else:
506 httplib.HTTPSConnection.connect(self) 535 httplib.HTTPSConnection.connect(self)
507 536
508 class httpsconnection(BetterHTTPS): 537 class httpsconnection(BetterHTTPS):
509 response_class = keepalive.HTTPResponse 538 response_class = keepalive.HTTPResponse