##// END OF EJS Templates
url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart -
r10409:4c94a3df default
parent child Browse files
Show More
@@ -873,6 +873,26 b' Web interface configuration.'
873 873 Base URL to use when publishing URLs in other locations, so
874 874 third-party tools like email notification hooks can construct
875 875 URLs. Example: ``http://hgserver/repos/``.
876 ``cacerts``
877 Path to file containing a list of PEM encoded certificate authorities
878 that may be used to verify an SSL server's identity. The form must be
879 as follows::
880
881 -----BEGIN CERTIFICATE-----
882 ... (certificate in base64 PEM encoding) ...
883 -----END CERTIFICATE-----
884 -----BEGIN CERTIFICATE-----
885 ... (certificate in base64 PEM encoding) ...
886 -----END CERTIFICATE-----
887
888 This feature is only supported when using Python 2.6. If you wish to
889 use it with earlier versions of Python, install the backported
890 version of the ssl library that is available from
891 ``http://pypi.python.org``.
892
893 You can use OpenSSL's CA certificate file if your platform has one.
894 On most Linux systems this will be ``/etc/ssl/certs/ca-certificates.crt``.
895 Otherwise you will have to generate this file manually.
876 896 ``contact``
877 897 Name or email address of the person in charge of the repository.
878 898 Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
@@ -255,11 +255,48 b' if has_https:'
255 255 # avoid using deprecated/broken FakeSocket in python 2.6
256 256 import ssl
257 257 _ssl_wrap_socket = ssl.wrap_socket
258 CERT_REQUIRED = ssl.CERT_REQUIRED
258 259 except ImportError:
259 def _ssl_wrap_socket(sock, key_file, cert_file):
260 CERT_REQUIRED = 2
261
262 def _ssl_wrap_socket(sock, key_file, cert_file,
263 cert_reqs=CERT_REQUIRED, ca_certs=None):
264 if ca_certs:
265 raise util.Abort(_(
266 'certificate checking requires Python 2.6'))
267
260 268 ssl = socket.ssl(sock, key_file, cert_file)
261 269 return httplib.FakeSocket(sock, ssl)
262 270
271 _GLOBAL_DEFAULT_TIMEOUT = object()
272
273 try:
274 _create_connection = socket.create_connection
275 except ImportError:
276 def _create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
277 source_address=None):
278 # lifted from Python 2.6
279
280 msg = "getaddrinfo returns an empty list"
281 host, port = address
282 for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
283 af, socktype, proto, canonname, sa = res
284 sock = None
285 try:
286 sock = socket.socket(af, socktype, proto)
287 if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
288 sock.settimeout(timeout)
289 if source_address:
290 sock.bind(source_address)
291 sock.connect(sa)
292 return sock
293
294 except socket.error, msg:
295 if sock is not None:
296 sock.close()
297
298 raise socket.error, msg
299
263 300 class httpconnection(keepalive.HTTPConnection):
264 301 # must be able to send big bundle as stream.
265 302 send = _gen_sendfile(keepalive.HTTPConnection)
@@ -427,6 +464,21 b' if has_https:'
427 464 class BetterHTTPS(httplib.HTTPSConnection):
428 465 send = keepalive.safesend
429 466
467 def connect(self):
468 if hasattr(self, 'ui'):
469 cacerts = self.ui.config('web', 'cacerts')
470 else:
471 cacerts = None
472
473 if cacerts:
474 sock = _create_connection((self.host, self.port))
475 self.sock = _ssl_wrap_socket(sock, self.key_file,
476 self.cert_file, cert_reqs=CERT_REQUIRED,
477 ca_certs=cacerts)
478 self.ui.debug(_('server identity verification succeeded\n'))
479 else:
480 httplib.HTTPSConnection.connect(self)
481
430 482 class httpsconnection(BetterHTTPS):
431 483 response_class = keepalive.HTTPResponse
432 484 # must be able to send big bundle as stream.
@@ -473,7 +525,9 b' if has_https:'
473 525 keyfile = self.auth['key']
474 526 certfile = self.auth['cert']
475 527
476 return httpsconnection(host, port, keyfile, certfile, *args, **kwargs)
528 conn = httpsconnection(host, port, keyfile, certfile, *args, **kwargs)
529 conn.ui = self.ui
530 return conn
477 531
478 532 # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
479 533 # it doesn't know about the auth type requested. This can happen if
General Comments 0
You need to be logged in to leave comments. Login now