python - Error in SSL wrapper while cloning with Mercurial -


i've started working bitbucket , mercurial. can work git repositories fine, when try clone mercurial one, crashes in /users/foobar/library/enthought/canopy_64bit/user/lib/python2.7/site-packages/mercurial-3.4.2-py2.7-macosx-10.6-x86_64.egg/mercurial/sslutil.py on line 36, error:

valueerror: can't clear options before openssl 0.9.8m

i running openssl 1.0.2c.

as apparent file path, downloaded python (and mercurial) through enthought canopy

i searched around , found similar problem: https://bitbucket.org/durin42/hgsubversion/issues/439/unknown-exception-in-dispatchpy-value. partial solution (commenting out offending line) enough make download work, confess out of depth in trying determine whether cause security issues me using mercurial. there potential security issues this? there additional information you'd need begin answer this?

the file edited below (search "==========" find line removed).

# sslutil.py - ssl handling mercurial # # copyright 2005, 2006, 2007, 2008 matt mackall <mpm@selenic.com> # copyright 2006, 2007 alexis s. l. carvalho <alexis@cecm.usp.br> # copyright 2006 vadim gelfer <vadim.gelfer@gmail.com> # # software may used , distributed according terms of # gnu general public license version 2 or later version. import os, sys  mercurial import util mercurial.i18n import _  _canloaddefaultcerts = false try:     # avoid using deprecated/broken fakesocket in python 2.6     import ssl     cert_required = ssl.cert_required     try:         ssl_context = ssl.sslcontext         _canloaddefaultcerts = util.safehasattr(ssl_context,                                                 'load_default_certs')          def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.cert_none,                             ca_certs=none, serverhostname=none):             # allow version of ssl starting tlsv1 ,             # up. note specifying tlsv1 here prohibits use of             # newer standards (like tlsv1_2), right way             # this. note in future it'd better             # support using ssl.create_default_context(), sets             # bunch of things in smart ways (strong ciphers,             # protocol versions, etc) , upgraded python             # maintainers us, breaks many things             # in hurry.             sslcontext = ssl.sslcontext(ssl.protocol_sslv23)              # ================================================             # line removed             sslcontext.options &= ssl.op_no_sslv2 & ssl.op_no_sslv3             # ================================================              if certfile not none:                 sslcontext.load_cert_chain(certfile, keyfile)             sslcontext.verify_mode = cert_reqs             if ca_certs not none:                 sslcontext.load_verify_locations(cafile=ca_certs)             elif _canloaddefaultcerts:                 sslcontext.load_default_certs()              sslsocket = sslcontext.wrap_socket(sock,                                                server_hostname=serverhostname)             # check if wrap_socket failed silently because socket had been             # closed             # - see http://bugs.python.org/issue13721             if not sslsocket.cipher():                 raise util.abort(_('ssl connection failed'))             return sslsocket     except attributeerror:         def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.cert_none,                             ca_certs=none, serverhostname=none):             sslsocket = ssl.wrap_socket(sock, keyfile, certfile,                                         cert_reqs=cert_reqs, ca_certs=ca_certs,                                         ssl_version=ssl.protocol_tlsv1)             # check if wrap_socket failed silently because socket had been             # closed             # - see http://bugs.python.org/issue13721             if not sslsocket.cipher():                 raise util.abort(_('ssl connection failed'))             return sslsocket except importerror:     cert_required = 2      import socket, httplib      def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=cert_required,                         ca_certs=none, serverhostname=none):         if not util.safehasattr(socket, 'ssl'):             raise util.abort(_('python ssl support not found'))         if ca_certs:             raise util.abort(_(                 'certificate checking requires python 2.6'))          ssl = socket.ssl(sock, keyfile, certfile)         return httplib.fakesocket(sock, ssl)  def _verifycert(cert, hostname):     '''verify cert (in socket.getpeercert() format) matches hostname.     crls not handled.      returns error message if problems found , none on success.     '''     if not cert:         return _('no certificate received')     dnsname = hostname.lower()     def matchdnsname(certname):         return (certname == dnsname or                 '.' in dnsname , certname == '*.' + dnsname.split('.', 1)[1])      san = cert.get('subjectaltname', [])     if san:         certnames = [value.lower() key, value in san if key == 'dns']         name in certnames:             if matchdnsname(name):                 return none         if certnames:             return _('certificate %s') % ', '.join(certnames)      # subject checked when subjectaltname empty     s in cert.get('subject', []):         key, value = s[0]         if key == 'commonname':             try:                 # 'subject' entries unicode                 certname = value.lower().encode('ascii')             except unicodeencodeerror:                 return _('idn in certificate not supported')             if matchdnsname(certname):                 return none             return _('certificate %s') % certname     return _('no commonname or subjectaltname found in certificate')   # cert_required means fetch cert server time , # validate against ca store provided in web.cacerts. # # ignore cert_required on python <= 2.5, it's totally # busted on versions.  def _plainapplepython():     """return true if seems pure apple python     * unfrozen , presumably has whole mercurial module in file       system     * presumably apple python uses apple openssl has patches       using system certificate store cas in addition provided       cacerts file     """     if sys.platform != 'darwin' or util.mainfrozen() or not sys.executable:         return false     exe = os.path.realpath(sys.executable).lower()     return (exe.startswith('/usr/bin/python') or             exe.startswith('/system/library/frameworks/python.framework/'))  def _defaultcacerts():     """return path ca certificates; none system's store; ! disable"""     if _plainapplepython():         dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')         if os.path.exists(dummycert):             return dummycert     if _canloaddefaultcerts:         return none     return '!'  def sslkwargs(ui, host):     kws = {}     hostfingerprint = ui.config('hostfingerprints', host)     if hostfingerprint:         return kws     cacerts = ui.config('web', 'cacerts')     if cacerts == '!':         pass     elif cacerts:         cacerts = util.expandpath(cacerts)         if not os.path.exists(cacerts):             raise util.abort(_('could not find web.cacerts: %s') % cacerts)     else:         cacerts = _defaultcacerts()         if cacerts , cacerts != '!':             ui.debug('using %s enable os x system ca\n' % cacerts)         ui.setconfig('web', 'cacerts', cacerts, 'defaultcacerts')     if cacerts != '!':         kws.update({'ca_certs': cacerts,                     'cert_reqs': cert_required,                     })     return kws  class validator(object):     def __init__(self, ui, host):         self.ui = ui         self.host = host      def __call__(self, sock, strict=false):         host = self.host         cacerts = self.ui.config('web', 'cacerts')         hostfingerprint = self.ui.config('hostfingerprints', host)         if not getattr(sock, 'getpeercert', false): # python 2.5 ?             if hostfingerprint:                 raise util.abort(_("host fingerprint %s can't "                                    "verified (python old)") % host)             if strict:                 raise util.abort(_("certificate %s can't verified "                                    "(python old)") % host)             if self.ui.configbool('ui', 'reportoldssl', true):                 self.ui.warn(_("warning: certificate %s can't verified "                                "(python old)\n") % host)             return          if not sock.cipher(): # work around http://bugs.python.org/issue13721             raise util.abort(_('%s ssl connection error') % host)         try:             peercert = sock.getpeercert(true)             peercert2 = sock.getpeercert()         except attributeerror:             raise util.abort(_('%s ssl connection error') % host)          if not peercert:             raise util.abort(_('%s certificate error: '                                'no certificate received') % host)         peerfingerprint = util.sha1(peercert).hexdigest()         nicefingerprint = ":".join([peerfingerprint[x:x + 2]             x in xrange(0, len(peerfingerprint), 2)])         if hostfingerprint:             if peerfingerprint.lower() != \                     hostfingerprint.replace(':', '').lower():                 raise util.abort(_('certificate %s has unexpected '                                    'fingerprint %s') % (host, nicefingerprint),                                  hint=_('check hostfingerprint configuration'))             self.ui.debug('%s certificate matched fingerprint %s\n' %                           (host, nicefingerprint))         elif cacerts != '!':             msg = _verifycert(peercert2, host)             if msg:                 raise util.abort(_('%s certificate error: %s') % (host, msg),                                  hint=_('configure hostfingerprint %s or use '                                         '--insecure connect insecurely') %                                       nicefingerprint)             self.ui.debug('%s certificate verified\n' % host)         elif strict:             raise util.abort(_('%s certificate fingerprint %s not '                                'verified') % (host, nicefingerprint),                              hint=_('check hostfingerprints or web.cacerts '                                      'config setting'))         else:             self.ui.warn(_('warning: %s certificate fingerprint %s not '                            'verified (check hostfingerprints or web.cacerts '                            'config setting)\n') %                          (host, nicefingerprint)) 

valueerror: can't clear options before openssl 0.9.8m 

i running openssl 1.0.2c.

just guess, sounds script using apple's version of openssl, 0.9.8 (and not openssl 1.0.2 built things against).

to ensure use openssl 1.0.2, use dyld_library_path. similar ld_library_path on linux.

the other option omit shared openssl configure, gear can perform static linking. apple's linker uses *.dylib if available (even on ios, not allowed), have careful it.


Comments