[Inteproxy-commits] r282 - in trunk: . inteproxy
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Oct 11 10:29:19 CEST 2010
Author: iweinzierl
Date: 2010-10-11 10:29:18 +0200 (Mon, 11 Oct 2010)
New Revision: 282
Modified:
trunk/ChangeLog
trunk/inteproxy/proxycore.py
Log:
Validate remote certificates when creating HTTPS connections.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2010-10-11 08:22:07 UTC (rev 281)
+++ trunk/ChangeLog 2010-10-11 08:29:18 UTC (rev 282)
@@ -1,5 +1,14 @@
2010-10-11 Ingo Weinzierl <ingo.weinzierl at intevation.de>
+ * inteproxy/proxycore.py: Validate remote certificates when an ssl
+ connection is created (requires python >= 2.6, otherwise no validation
+ takes place) using pythons ssl module. If the validation failes, a popup
+ dialog is opened with the error/warning. If the user accepts the
+ certificate, the ssl connection is created, otherwise a HTML error code
+ 502 is returned.
+
+2010-10-11 Ingo Weinzierl <ingo.weinzierl at intevation.de>
+
* inteproxy/certificatedialog.py: New module to handle errors/warnings
that occured while certificate validation.
Modified: trunk/inteproxy/proxycore.py
===================================================================
--- trunk/inteproxy/proxycore.py 2010-10-11 08:22:07 UTC (rev 281)
+++ trunk/inteproxy/proxycore.py 2010-10-11 08:29:18 UTC (rev 282)
@@ -16,8 +16,16 @@
import socket
import base64
+# the ssl modules was introduced in Python 2.6. If available, we use
+# that, otherwise the older ssl support from the socket module
+try:
+ import ssl
+except ImportError:
+ ssl = None
+
from inteproxy.threadpool import ThreadPool
from inteproxy.feesdialog import handle_fees_and_access_constraints
+from inteproxy.certificatedialog import handle_certificate_validation_error
from inteproxy.httpserver import HTTPServer
from inteproxy.httpmessage import HTTPRequestMessage, HTTPResponseMessage
from inteproxy.httpconnection import connect_tcp, connect_http_connect, \
@@ -118,11 +126,39 @@
return headers
- def open_https_connection(self, remote_address):
+ def https_connection_wrapper(self, remote_address):
+ """Open a HTTPS connection to remote_address and validate the server
+ certificate
+
+ The server certificate is validated if python >= 2.6. If the validation
+ failed, a popup dialog with technical details of the failure is shown.
+ The user has the choice to trust or reject the connection. Rejecting the
+ connection will result in a HTTP-502. If python < 2.6 is installed, the
+ certificate is not validated but an ssl connection is used as well to
+ encrypt the data."""
+ if ssl is not None:
+ try:
+ return self.open_https_connection(remote_address)
+ except ssl.SSLError:
+ self.log_debug("SSL certificate validation failed.")
+ if handle_certificate_validation_error(remote_address[0]):
+ return self.open_https_connection(remote_address,
+ validate=False)
+ return None
+ else:
+ return self.open_https_connection(remote_address, validate=False)
+
+
+ def open_https_connection(self, remote_address, validate=True):
"""Open a HTTPS connection to remote_address
This method handles proxies as well. Its return value is a socket like
- object using SSL to encrypt the data."""
+ object using SSL to encrypt the data. If python >= 2.6 is installed, the
+ server certificate is validated. If this validation failed None is
+ returned, otherwise a ssl like object. The parameter validate may be
+ used to skip the certificate validation.If python < 2.6 is installed,
+ the certificate is not validated, but a ssl connection is used to
+ encrypt the data."""
self.log_debug("Open HTTPS connection to %r" % remote_address[0])
sock = None
@@ -137,9 +173,21 @@
else:
sock = connect_tcp(remote_address[0], remote_address[1],
log_debug=self.log_debug)
- return connect_ssl(sock, log_debug=self.log_debug)
+ if ssl is not None and validate:
+ self.log_debug("Start HTTPS connection and validate certificates.")
+ cert_file = self.server.get_cacert_path()
+ return connect_ssl(sock, log_debug=self.log_debug,
+ ca_certs=cert_file, remote_url=remote_address[0])
+ elif ssl is not None and not validate:
+ self.log_debug("Start HTTPS connection but do not validate certificates.")
+ return connect_ssl(sock, log_debug=self.log_debug,
+ cert_required=False)
+ else:
+ self.log_debug("Certificate validation is not supported.")
+ return connect_ssl(sock, log_debug=self.log_debug)
+
def open_http_connection(self, remote_url, remote_address, request_uri,
extra_headers):
"""Open a HTTP connection to remote_address
@@ -182,7 +230,10 @@
request_uri,
extra_headers)
elif scheme == "https":
- sock = self.open_https_connection(remote_address)
+ sock = self.https_connection_wrapper(remote_address)
+ if not sock:
+ self.send_error(502)
+ return
connection = SocketHTTPConnection(sock, *remote_address)
if self.debug_level > 1:
More information about the Inteproxy-commits
mailing list