From 42169282aa36b97808e3b5046fab1dfa41ea81e5 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sun, 3 Apr 2011 17:19:49 -0500 Subject: Proxy: Fix for Python 2.7 xmlrpclib Transport class (Patch from Gordon Messmer) Something changed in Python 2.7 with respect to the xmlrpclib.Transport api such that you need to store the authentication headers in self.extra_headers so that they are sent to the server properly. Signed-off-by: Sol Jerome --- src/lib/Proxy.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 275405faf..42ff6a12b 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -31,7 +31,6 @@ except ImportError, e: SSL_LIB = 'm2crypto' -import string import sys import time import urlparse @@ -43,14 +42,17 @@ has_py26 = map(int, version) >= [2, 6] __all__ = ["ComponentProxy", "RetryMethod", "SSLHTTPConnection", "XMLRPCTransport"] + class CertificateError(Exception): def __init__(self, commonName): self.commonName = commonName + class RetryMethod(_Method): """Method with error handling and retries built in.""" log = logging.getLogger('xmlrpc') max_retries = 4 + def __call__(self, *args): for retry in range(self.max_retries): try: @@ -84,6 +86,7 @@ class RetryMethod(_Method): # sorry jon xmlrpclib._Method = RetryMethod + class SSLHTTPConnection(httplib.HTTPConnection): """Extension of HTTPConnection that implements SSL and related behaviors.""" @@ -156,7 +159,6 @@ class SSLHTTPConnection(httplib.HTTPConnection): else: raise Exception, "No SSL module support" - def _connect_py26ssl(self): """Initiates a connection using the ssl module.""" rawsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -240,7 +242,8 @@ class SSLHTTPConnection(httplib.HTTPConnection): class XMLRPCTransport(xmlrpclib.Transport): - def __init__(self, key=None, cert=None, ca=None, scns=None, use_datetime=0, timeout=90): + def __init__(self, key=None, cert=None, ca=None, + scns=None, use_datetime=0, timeout=90): if hasattr(xmlrpclib.Transport, '__init__'): xmlrpclib.Transport.__init__(self, use_datetime) self.key = key @@ -250,7 +253,7 @@ class XMLRPCTransport(xmlrpclib.Transport): self.timeout = timeout def make_connection(self, host): - host = self.get_host_info(host)[0] + host, self._extra_headers = self.get_host_info(host)[0:2] http = SSLHTTPConnection(host, key=self.key, cert=self.cert, ca=self.ca, scns=self.scns, timeout=self.timeout) https = httplib.HTTP() @@ -295,7 +298,9 @@ class XMLRPCTransport(xmlrpclib.Transport): return u.close() -def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, + +def ComponentProxy(url, user=None, password=None, + key=None, cert=None, ca=None, allowedServerCNs=None, timeout=90): """Constructs proxies to components. @@ -312,5 +317,6 @@ def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, newurl = "%s://%s:%s@%s" % (method, user, password, path) else: newurl = url - ssl_trans = XMLRPCTransport(key, cert, ca, allowedServerCNs, timeout=timeout) + ssl_trans = XMLRPCTransport(key, cert, ca, + allowedServerCNs, timeout=timeout) return xmlrpclib.ServerProxy(newurl, allow_none=True, transport=ssl_trans) -- cgit v1.2.3-1-g7c22 From 2e1a79fe401bea5b33551b9f94689524bf43cdca Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 7 Apr 2011 14:04:36 -0500 Subject: PY3K + PEP8 fixes for remaining files Signed-off-by: Sol Jerome --- src/lib/Proxy.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 42ff6a12b..8b3fcb87c 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -37,10 +37,13 @@ import urlparse import xmlrpclib version = sys.version_info[:2] -has_py23 = map(int, version) >= [2, 3] -has_py26 = map(int, version) >= [2, 6] +has_py23 = version >= (2, 3) +has_py26 = version >= (2, 6) -__all__ = ["ComponentProxy", "RetryMethod", "SSLHTTPConnection", "XMLRPCTransport"] +__all__ = ["ComponentProxy", + "RetryMethod", + "SSLHTTPConnection", + "XMLRPCTransport"] class CertificateError(Exception): @@ -88,7 +91,9 @@ xmlrpclib._Method = RetryMethod class SSLHTTPConnection(httplib.HTTPConnection): - """Extension of HTTPConnection that implements SSL and related behaviors.""" + """Extension of HTTPConnection that + implements SSL and related behaviors. + """ logger = logging.getLogger('Bcfg2.Proxy.SSLHTTPConnection') @@ -157,7 +162,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): elif SSL_LIB == 'm2crypto': self._connect_m2crypto() else: - raise Exception, "No SSL module support" + raise Exception("No SSL module support") def _connect_py26ssl(self): """Initiates a connection using the ssl module.""" @@ -168,7 +173,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): ssl_protocol_ver = ssl.PROTOCOL_TLSv1 else: self.logger.error("Unknown protocol %s" % (self.protocol)) - raise Exception, "unknown protocol %s" % self.protocol + raise Exception("unknown protocol %s" % self.protocol) if self.ca: other_side_required = ssl.CERT_REQUIRED else: @@ -192,7 +197,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): if peer_cert and self.scns: scn = [x[0][1] for x in peer_cert['subject'] if x[0][0] == 'commonName'][0] if scn not in self.scns: - raise CertificateError, scn + raise CertificateError(scn) self.sock.closeSocket = True def _connect_m2crypto(self): @@ -204,7 +209,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): ctx = SSL.Context('tlsv1') else: self.logger.error("Unknown protocol %s" % (self.protocol)) - raise Exception, "unknown protocol %s" % self.protocol + raise Exception("unknown protocol %s" % self.protocol) if self.ca: # Use the certificate authority to validate the cert @@ -238,7 +243,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): self.sock.connect((hostname, self.port)) # automatically checks cert matches host except M2Crypto.SSL.Checker.WrongHost, wr: - raise CertificateError, wr + raise CertificateError(wr) class XMLRPCTransport(xmlrpclib.Transport): @@ -254,8 +259,12 @@ class XMLRPCTransport(xmlrpclib.Transport): def make_connection(self, host): host, self._extra_headers = self.get_host_info(host)[0:2] - http = SSLHTTPConnection(host, key=self.key, cert=self.cert, ca=self.ca, - scns=self.scns, timeout=self.timeout) + http = SSLHTTPConnection(host, + key=self.key, + cert=self.cert, + ca=self.ca, + scns=self.scns, + timeout=self.timeout) https = httplib.HTTP() https._setup(http) return https @@ -271,7 +280,10 @@ class XMLRPCTransport(xmlrpclib.Transport): errcode, errmsg, headers = h.getreply() if errcode != 200: - raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) + raise xmlrpclib.ProtocolError(host + handler, + errcode, + errmsg, + headers) self.verbose = verbose msglen = int(headers.dict['content-length']) @@ -290,7 +302,7 @@ class XMLRPCTransport(xmlrpclib.Transport): if not response: break if self.verbose: - print "body:", repr(response), len(response) + print("body:", repr(response), len(response)) p.feed(response) fd.close() -- cgit v1.2.3-1-g7c22 From d3348a34c78ba13d4d4c3e96db19faeeeefac11b Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 27 Apr 2011 11:40:08 -0500 Subject: Common: Add full PY3K compatibility Signed-off-by: Sol Jerome --- src/lib/Proxy.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 8b3fcb87c..30b7deaf5 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -11,9 +11,6 @@ load_config -- read configuration files __revision__ = '$Revision: $' -from xmlrpclib import _Method - -import httplib import logging import re import socket @@ -25,7 +22,7 @@ import socket try: import ssl SSL_LIB = 'py26_ssl' -except ImportError, e: +except ImportError: from M2Crypto import SSL import M2Crypto.SSL.Checker SSL_LIB = 'm2crypto' @@ -33,8 +30,9 @@ except ImportError, e: import sys import time -import urlparse -import xmlrpclib + +# Compatibility imports +from Bcfg2.Bcfg2Py3k import httplib, xmlrpclib, urlparse version = sys.version_info[:2] has_py23 = version >= (2, 3) @@ -51,7 +49,7 @@ class CertificateError(Exception): self.commonName = commonName -class RetryMethod(_Method): +class RetryMethod(xmlrpclib._Method): """Method with error handling and retries built in.""" log = logging.getLogger('xmlrpc') max_retries = 4 @@ -59,21 +57,24 @@ class RetryMethod(_Method): def __call__(self, *args): for retry in range(self.max_retries): try: - return _Method.__call__(self, *args) - except xmlrpclib.ProtocolError, err: + return xmlrpclib._Method.__call__(self, *args) + except xmlrpclib.ProtocolError: + err = sys.exc_info()[1] self.log.error("Server failure: Protocol Error: %s %s" % \ (err.errcode, err.errmsg)) raise xmlrpclib.Fault(20, "Server Failure") except xmlrpclib.Fault: raise - except socket.error, err: + except socket.error: + err = sys.exc_info()[1] if hasattr(err, 'errno') and err.errno == 336265218: self.log.error("SSL Key error") break if retry == 3: self.log.error("Server failure: %s" % err) raise xmlrpclib.Fault(20, err) - except CertificateError, ce: + except CertificateError: + ce = sys.exc_info()[1] self.log.error("Got unallowed commonName %s from server" \ % ce.commonName) break @@ -242,7 +243,8 @@ class SSLHTTPConnection(httplib.HTTPConnection): try: self.sock.connect((hostname, self.port)) # automatically checks cert matches host - except M2Crypto.SSL.Checker.WrongHost, wr: + except M2Crypto.SSL.Checker.WrongHost: + wr = sys.exc_info()[1] raise CertificateError(wr) @@ -325,7 +327,7 @@ def ComponentProxy(url, user=None, password=None, """ if user and password: - method, path = urlparse.urlparse(url)[:2] + method, path = urlparse(url)[:2] newurl = "%s://%s:%s@%s" % (method, user, password, path) else: newurl = url -- cgit v1.2.3-1-g7c22 From 8bc620dd945a001754d01c87974a71ff078dc85a Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 3 May 2011 12:50:22 -0500 Subject: Fix regressions with new py3k code Signed-off-by: Sol Jerome --- src/lib/Proxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 30b7deaf5..8a1ad683e 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -88,7 +88,7 @@ class RetryMethod(xmlrpclib._Method): raise xmlrpclib.Fault(20, "Server Failure") # sorry jon -xmlrpclib._Method = RetryMethod +_Method = RetryMethod class SSLHTTPConnection(httplib.HTTPConnection): -- cgit v1.2.3-1-g7c22 From bdeb933b7b76f422a0df8f03cf74d2a3fe58b056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20Wei=C3=9F?= Date: Wed, 11 May 2011 15:33:14 +0200 Subject: Fix a typo in an SSL error message --- src/lib/Proxy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 8a1ad683e..ed33316af 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -181,7 +181,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): other_side_required = ssl.CERT_NONE self.logger.warning("No ca is specified. Cannot authenticate the server with SSL.") if self.cert and not self.key: - self.logger.warning("SSL cert specfied, but key. Cannot authenticate this client with SSL.") + self.logger.warning("SSL cert specfied, but no key. Cannot authenticate this client with SSL.") self.cert = None if self.key and not self.cert: self.logger.warning("SSL key specfied, but no cert. Cannot authenticate this client with SSL.") @@ -226,7 +226,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): # authentication to the server ctx.load_cert(self.cert, self.key) elif self.cert: - self.logger.warning("SSL cert specfied, but key. Cannot authenticate this client with SSL.") + self.logger.warning("SSL cert specfied, but no key. Cannot authenticate this client with SSL.") elif self.key: self.logger.warning("SSL key specfied, but no cert. Cannot authenticate this client with SSL.") -- cgit v1.2.3-1-g7c22 From 623ef741053c9c213b526787a0631c71b90df186 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 1 Jun 2011 16:01:15 -0400 Subject: guarantee that timeout is a float --- src/lib/Proxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index ed33316af..9656b166c 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -332,5 +332,5 @@ def ComponentProxy(url, user=None, password=None, else: newurl = url ssl_trans = XMLRPCTransport(key, cert, ca, - allowedServerCNs, timeout=timeout) + allowedServerCNs, timeout=float(timeout)) return xmlrpclib.ServerProxy(newurl, allow_none=True, transport=ssl_trans) -- cgit v1.2.3-1-g7c22 From 44f427f197c7f4e2cb4bba250450454bf7b8d179 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sat, 4 Jun 2011 17:49:01 -0500 Subject: Proxy: Catch traceback when name resolution fails (#1012) Signed-off-by: Sol Jerome --- src/lib/Proxy.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/lib/Proxy.py') diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py index 9656b166c..e4a0f6a3d 100644 --- a/src/lib/Proxy.py +++ b/src/lib/Proxy.py @@ -193,7 +193,13 @@ class SSLHTTPConnection(httplib.HTTPConnection): ca_certs=self.ca, suppress_ragged_eofs=True, keyfile=self.key, certfile=self.cert, ssl_version=ssl_protocol_ver) - self.sock.connect((self.host, self.port)) + try: + self.sock.connect((self.host, self.port)) + except socket.gaierror: + e = sys.exc_info()[1] + self.logger.error("Unable to connect to %s:%s\n%s" % + (self.host, self.port, e.strerror)) + sys.exit(1) peer_cert = self.sock.getpeercert() if peer_cert and self.scns: scn = [x[0][1] for x in peer_cert['subject'] if x[0][0] == 'commonName'][0] -- cgit v1.2.3-1-g7c22