comparison mercurial/sslutil.py @ 25430:19fa0cb71cd3

ssl: drop support for Python < 2.6, require ssl module try-except clause is kept for readability of this patch, and it will be removed soon.
author Yuya Nishihara <yuya@tcha.org>
date Fri, 05 Jun 2015 21:37:46 +0900
parents 9d1c61715939
children 96159068c506
comparison
equal deleted inserted replaced
25429:9d1c61715939 25430:19fa0cb71cd3
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br> 4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
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 import os, sys 9 import os, sys, ssl
10 10
11 from mercurial import util 11 from mercurial import util
12 from mercurial.i18n import _ 12 from mercurial.i18n import _
13 13
14 _canloaddefaultcerts = False 14 _canloaddefaultcerts = False
15 try: 15 try:
16 # avoid using deprecated/broken FakeSocket in python 2.6
17 import ssl
18 CERT_REQUIRED = ssl.CERT_REQUIRED 16 CERT_REQUIRED = ssl.CERT_REQUIRED
19 try: 17 try:
20 ssl_context = ssl.SSLContext 18 ssl_context = ssl.SSLContext
21 _canloaddefaultcerts = util.safehasattr(ssl_context, 19 _canloaddefaultcerts = util.safehasattr(ssl_context,
22 'load_default_certs') 20 'load_default_certs')
66 # - see http://bugs.python.org/issue13721 64 # - see http://bugs.python.org/issue13721
67 if not sslsocket.cipher(): 65 if not sslsocket.cipher():
68 raise util.Abort(_('ssl connection failed')) 66 raise util.Abort(_('ssl connection failed'))
69 return sslsocket 67 return sslsocket
70 except ImportError: 68 except ImportError:
71 CERT_REQUIRED = 2 69 raise
72
73 import socket, httplib
74
75 def wrapsocket(sock, keyfile, certfile, ui,
76 cert_reqs=CERT_REQUIRED,
77 ca_certs=None, serverhostname=None):
78 if not util.safehasattr(socket, 'ssl'):
79 raise util.Abort(_('Python SSL support not found'))
80 if ca_certs:
81 raise util.Abort(_(
82 'certificate checking requires Python 2.6'))
83
84 ssl = socket.ssl(sock, keyfile, certfile)
85 return httplib.FakeSocket(sock, ssl)
86 70
87 def _verifycert(cert, hostname): 71 def _verifycert(cert, hostname):
88 '''Verify that cert (in socket.getpeercert() format) matches hostname. 72 '''Verify that cert (in socket.getpeercert() format) matches hostname.
89 CRLs is not handled. 73 CRLs is not handled.
90 74
121 return _('no commonName or subjectAltName found in certificate') 105 return _('no commonName or subjectAltName found in certificate')
122 106
123 107
124 # CERT_REQUIRED means fetch the cert from the server all the time AND 108 # CERT_REQUIRED means fetch the cert from the server all the time AND
125 # validate it against the CA store provided in web.cacerts. 109 # validate it against the CA store provided in web.cacerts.
126 #
127 # We COMPLETELY ignore CERT_REQUIRED on Python <= 2.5, as it's totally
128 # busted on those versions.
129 110
130 def _plainapplepython(): 111 def _plainapplepython():
131 """return true if this seems to be a pure Apple Python that 112 """return true if this seems to be a pure Apple Python that
132 * is unfrozen and presumably has the whole mercurial module in the file 113 * is unfrozen and presumably has the whole mercurial module in the file
133 system 114 system
181 162
182 def __call__(self, sock, strict=False): 163 def __call__(self, sock, strict=False):
183 host = self.host 164 host = self.host
184 cacerts = self.ui.config('web', 'cacerts') 165 cacerts = self.ui.config('web', 'cacerts')
185 hostfingerprint = self.ui.config('hostfingerprints', host) 166 hostfingerprint = self.ui.config('hostfingerprints', host)
186 if not getattr(sock, 'getpeercert', False): # python 2.5 ?
187 if hostfingerprint:
188 raise util.Abort(_("host fingerprint for %s can't be "
189 "verified (Python too old)") % host)
190 if strict:
191 raise util.Abort(_("certificate for %s can't be verified "
192 "(Python too old)") % host)
193 if self.ui.configbool('ui', 'reportoldssl', True):
194 self.ui.warn(_("warning: certificate for %s can't be verified "
195 "(Python too old)\n") % host)
196 return
197 167
198 if not sock.cipher(): # work around http://bugs.python.org/issue13721 168 if not sock.cipher(): # work around http://bugs.python.org/issue13721
199 raise util.Abort(_('%s ssl connection error') % host) 169 raise util.Abort(_('%s ssl connection error') % host)
200 try: 170 try:
201 peercert = sock.getpeercert(True) 171 peercert = sock.getpeercert(True)