mercurial/url.py
branchstable
changeset 13249 75d0c38a0bca
parent 13248 00411a4fa1bb
child 13250 1a4330e30017
child 13314 8dc488dfcdb4
equal deleted inserted replaced
13248:00411a4fa1bb 13249:75d0c38a0bca
   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):
   489 def _verifycert(cert, hostname):
   490     '''Verify that cert (in socket.getpeercert() format) matches hostname.
   490     '''Verify that cert (in socket.getpeercert() format) matches hostname.
   491     CRLs and subjectAltName are not handled.
   491     CRLs is not handled.
   492 
   492 
   493     Returns error message if any problems are found and None on success.
   493     Returns error message if any problems are found and None on success.
   494     '''
   494     '''
   495     if not cert:
   495     if not cert:
   496         return _('no certificate received')
   496         return _('no certificate received')
   497     dnsname = hostname.lower()
   497     dnsname = hostname.lower()
       
   498     def matchdnsname(certname):
       
   499         return (certname == dnsname or
       
   500                 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1])
       
   501 
       
   502     san = cert.get('subjectAltName', [])
       
   503     if san:
       
   504         certnames = [value.lower() for key, value in san if key == 'DNS']
       
   505         for name in certnames:
       
   506             if matchdnsname(name):
       
   507                 return None
       
   508         return _('certificate is for %s') % ', '.join(certnames)
       
   509 
       
   510     # subject is only checked when subjectAltName is empty
   498     for s in cert.get('subject', []):
   511     for s in cert.get('subject', []):
   499         key, value = s[0]
   512         key, value = s[0]
   500         if key == 'commonName':
   513         if key == 'commonName':
   501             try:
   514             try:
   502                 # 'subject' entries are unicode
   515                 # 'subject' entries are unicode
   503                 certname = value.lower().encode('ascii')
   516                 certname = value.lower().encode('ascii')
   504             except UnicodeEncodeError:
   517             except UnicodeEncodeError:
   505                 return _('IDN in certificate not supported')
   518                 return _('IDN in certificate not supported')
   506             if (certname == dnsname or
   519             if matchdnsname(certname):
   507                 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]):
       
   508                 return None
   520                 return None
   509             return _('certificate is for %s') % certname
   521             return _('certificate is for %s') % certname
   510     return _('no commonName found in certificate')
   522     return _('no commonName or subjectAltName found in certificate')
   511 
   523 
   512 if has_https:
   524 if has_https:
   513     class BetterHTTPS(httplib.HTTPSConnection):
   525     class BetterHTTPS(httplib.HTTPSConnection):
   514         send = keepalive.safesend
   526         send = keepalive.safesend
   515 
   527