diff --git a/CHANGELOG b/CHANGELOG index 1dea97103b..c59653f991 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Verify certificate with default CA * Replace URL entry by a toolbar button Version 4.2.0 - 2016-11-28 diff --git a/doc/installation.rst b/doc/installation.rst index 6895965131..23564ae18d 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -4,7 +4,7 @@ Installing tryton Prerequisites ------------- - * Python 2.7 or later (http://www.python.org/) + * Python 2.7.9 or later (http://www.python.org/) * gtk+ 2.6 or later and pygtk 2.22 or later (http://www.pygtk.org/) * gtk+ 3.20 or later and py-gobject3 (http://www.gtk.org/) * librsvg (http://librsvg.sourceforge.net/) diff --git a/tryton/jsonrpc.py b/tryton/jsonrpc.py index 8f1d8cca13..0d8ab46d18 100644 --- a/tryton/jsonrpc.py +++ b/tryton/jsonrpc.py @@ -181,8 +181,7 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): return self._connection[1] host, self._extra_headers, x509 = self.get_host_info(host) - ca_certs = self.__ca_certs - cert_reqs = ssl.CERT_REQUIRED if ca_certs else ssl.CERT_NONE + ssl_ctx = ssl.create_default_context(cafile=self.__ca_certs) class HTTPSConnection(httplib.HTTPSConnection): @@ -192,8 +191,8 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): if self._tunnel_host: self.sock = sock self._tunnel() - self.sock = ssl.wrap_socket(sock, self.key_file, - self.cert_file, ca_certs=ca_certs, cert_reqs=cert_reqs) + self.sock = ssl_ctx.wrap_socket( + sock, server_hostname=self.host) def http_connection(): self._connection = host, httplib.HTTPConnection(host, @@ -203,7 +202,7 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - def https_connection(): + def https_connection(allow_http=False): self._connection = host, HTTPSConnection(host, timeout=CONNECT_TIMEOUT) try: @@ -222,7 +221,10 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): enumerate(value), '') return format_hash(hashlib.sha1(peercert).hexdigest()) except ssl.SSLError: - http_connection() + if allow_http: + http_connection() + else: + raise fingerprint = '' if self.__fingerprints is not None and host in self.__fingerprints: @@ -231,15 +233,10 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): else: http_connection() else: - fingerprint = https_connection() + fingerprint = https_connection(allow_http=True) if self.__fingerprints is not None: - if host in self.__fingerprints and self.__fingerprints[host]: - if self.__fingerprints[host] != fingerprint: - self.close() - raise ssl.SSLError('BadFingerprint') - else: - self.__fingerprints[host] = fingerprint + self.__fingerprints[host] = fingerprint self._connection[1].timeout = DEFAULT_TIMEOUT self._connection[1].sock.settimeout(DEFAULT_TIMEOUT) return self._connection[1] diff --git a/tryton/rpc.py b/tryton/rpc.py index 695c5483be..d899a73431 100644 --- a/tryton/rpc.py +++ b/tryton/rpc.py @@ -3,6 +3,7 @@ import httplib import logging import socket +import ssl import os from functools import partial from tryton.jsonrpc import ServerProxy, ServerPool, Fault @@ -57,7 +58,8 @@ def server_version(host, port): result = connection.common.server.version() logging.getLogger(__name__).debug(repr(result)) return result - except (Fault, socket.error): + except (Fault, socket.error, ssl.SSLError, ssl.CertificateError), e: + logging.getLogger(__name__).error(e) return None