diff options
author | Fabian Affolter <fabian@bernewireless.net> | 2010-12-13 23:22:40 +0100 |
---|---|---|
committer | Fabian Affolter <fabian@bernewireless.net> | 2010-12-13 23:22:40 +0100 |
commit | f5792d907e357c90624ec110d908d42b94296a12 (patch) | |
tree | fc4976fb05c8d4026bc2580e48ad8070d85bd7c7 /build/lib/Bcfg2/Proxy.py | |
parent | 18b3b41b3f993b2dd5a10e1bbb8abf959c57c4e2 (diff) | |
download | bcfg2-f5792d907e357c90624ec110d908d42b94296a12.tar.gz bcfg2-f5792d907e357c90624ec110d908d42b94296a12.tar.bz2 bcfg2-f5792d907e357c90624ec110d908d42b94296a12.zip |
Removed build files
Diffstat (limited to 'build/lib/Bcfg2/Proxy.py')
-rw-r--r-- | build/lib/Bcfg2/Proxy.py | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/build/lib/Bcfg2/Proxy.py b/build/lib/Bcfg2/Proxy.py deleted file mode 100644 index 275405faf..000000000 --- a/build/lib/Bcfg2/Proxy.py +++ /dev/null @@ -1,316 +0,0 @@ -"""RPC client access to cobalt components. - -Classes: -ComponentProxy -- an RPC client proxy to Cobalt components - -Functions: -load_config -- read configuration files - -""" - -__revision__ = '$Revision: $' - - -from xmlrpclib import _Method - -import httplib -import logging -import re -import socket - -# The ssl module is provided by either Python 2.6 or a separate ssl -# package that works on older versions of Python (see -# http://pypi.python.org/pypi/ssl). If neither can be found, look for -# M2Crypto instead. -try: - import ssl - SSL_LIB = 'py26_ssl' -except ImportError, e: - from M2Crypto import SSL - import M2Crypto.SSL.Checker - SSL_LIB = 'm2crypto' - - -import string -import sys -import time -import urlparse -import xmlrpclib - -version = sys.version_info[:2] -has_py23 = map(int, version) >= [2, 3] -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: - return _Method.__call__(self, *args) - except xmlrpclib.ProtocolError, err: - 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: - 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: - self.log.error("Got unallowed commonName %s from server" \ - % ce.commonName) - break - except KeyError: - self.log.error("Server disallowed connection") - break - except: - self.log.error("Unknown failure", exc_info=1) - break - time.sleep(0.5) - raise xmlrpclib.Fault(20, "Server Failure") - -# sorry jon -xmlrpclib._Method = RetryMethod - -class SSLHTTPConnection(httplib.HTTPConnection): - """Extension of HTTPConnection that implements SSL and related behaviors.""" - - logger = logging.getLogger('Bcfg2.Proxy.SSLHTTPConnection') - - def __init__(self, host, port=None, strict=None, timeout=90, key=None, - cert=None, ca=None, scns=None, protocol='xmlrpc/ssl'): - """Initializes the `httplib.HTTPConnection` object and stores security - parameters - - Parameters - ---------- - host : string - Name of host to contact - port : int, optional - Port on which to contact the host. If none is specified, - the default port of 80 will be used unless the `host` - string has a port embedded in the form host:port. - strict : Boolean, optional - Passed to the `httplib.HTTPConnection` constructor and if - True, causes the `BadStatusLine` exception to be raised if - the status line cannot be parsed as a valid HTTP 1.0 or - 1.1 status. - timeout : int, optional - Causes blocking operations to timeout after `timeout` - seconds. - key : string, optional - The file system path to the local endpoint's SSL key. May - specify the same file as `cert` if using a file that - contains both. See - http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. - cert : string, optional - The file system path to the local endpoint's SSL - certificate. May specify the same file as `cert` if using - a file that contains both. See - http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. - ca : string, optional - The file system path to a set of concatenated certificate - authority certs, which are used to validate certificates - passed from the other end of the connection. - scns : array-like, optional - List of acceptable server commonNames. The peer cert's - common name must appear in this list, otherwise the - connect() call will throw a `CertificateError`. - protocol : {'xmlrpc/ssl', 'xmlrpc/tlsv1'}, optional - Communication protocol to use. - - """ - if not has_py26: - httplib.HTTPConnection.__init__(self, host, port, strict) - else: - httplib.HTTPConnection.__init__(self, host, port, strict, timeout) - self.key = key - self.cert = cert - self.ca = ca - self.scns = scns - self.protocol = protocol - self.timeout = timeout - - def connect(self): - """Initiates a connection using previously set attributes.""" - if SSL_LIB == 'py26_ssl': - self._connect_py26ssl() - elif SSL_LIB == 'm2crypto': - self._connect_m2crypto() - 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) - if self.protocol == 'xmlrpc/ssl': - ssl_protocol_ver = ssl.PROTOCOL_SSLv23 - elif self.protocol == 'xmlrpc/tlsv1': - ssl_protocol_ver = ssl.PROTOCOL_TLSv1 - else: - self.logger.error("Unknown protocol %s" % (self.protocol)) - raise Exception, "unknown protocol %s" % self.protocol - if self.ca: - other_side_required = ssl.CERT_REQUIRED - else: - 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.cert = None - if self.key and not self.cert: - self.logger.warning("SSL key specfied, but no cert. Cannot authenticate this client with SSL.") - self.key = None - - if has_py23: - rawsock.settimeout(self.timeout) - self.sock = ssl.SSLSocket(rawsock, cert_reqs=other_side_required, - 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)) - 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] - if scn not in self.scns: - raise CertificateError, scn - self.sock.closeSocket = True - - def _connect_m2crypto(self): - """Initiates a connection using the M2Crypto module.""" - - if self.protocol == 'xmlrpc/ssl': - ctx = SSL.Context('sslv23') - elif self.protocol == 'xmlrpc/tlsv1': - ctx = SSL.Context('tlsv1') - else: - self.logger.error("Unknown protocol %s" % (self.protocol)) - raise Exception, "unknown protocol %s" % self.protocol - - if self.ca: - # Use the certificate authority to validate the cert - # presented by the server - ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9) - if ctx.load_verify_locations(self.ca) != 1: - raise Exception('No CA certs') - else: - self.logger.warning("No ca is specified. Cannot authenticate the server with SSL.") - - if self.cert and self.key: - # A cert/key is defined, use them to support client - # 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.") - elif self.key: - self.logger.warning("SSL key specfied, but no cert. Cannot authenticate this client with SSL.") - - self.sock = SSL.Connection(ctx) - if re.match('\\d+\\.\\d+\\.\\d+\\.\\d+', self.host): - # host is ip address - try: - hostname = socket.gethostbyaddr(self.host)[0] - except: - # fall back to ip address - hostname = self.host - else: - hostname = self.host - try: - self.sock.connect((hostname, self.port)) - # automatically checks cert matches host - except M2Crypto.SSL.Checker.WrongHost, wr: - raise CertificateError, wr - - -class XMLRPCTransport(xmlrpclib.Transport): - 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 - self.cert = cert - self.ca = ca - self.scns = scns - self.timeout = timeout - - def make_connection(self, host): - host = self.get_host_info(host)[0] - 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 - - def request(self, host, handler, request_body, verbose=0): - """Send request to server and return response.""" - h = self.make_connection(host) - self.send_request(h, handler, request_body) - self.send_host(h, host) - self.send_user_agent(h) - self.send_content(h, request_body) - - errcode, errmsg, headers = h.getreply() - - if errcode != 200: - raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) - - self.verbose = verbose - msglen = int(headers.dict['content-length']) - return self._get_response(h.getfile(), msglen) - - def _get_response(self, fd, length): - # read response from input file/socket, and parse it - recvd = 0 - - p, u = self.getparser() - - while recvd < length: - rlen = min(length - recvd, 1024) - response = fd.read(rlen) - recvd += len(response) - if not response: - break - if self.verbose: - print "body:", repr(response), len(response) - p.feed(response) - - fd.close() - p.close() - - return u.close() - -def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, - allowedServerCNs=None, timeout=90): - - """Constructs proxies to components. - - Arguments: - component_name -- name of the component to connect to - - Additional arguments are passed to the ServerProxy constructor. - - """ - - if user and password: - method, path = urlparse.urlparse(url)[:2] - newurl = "%s://%s:%s@%s" % (method, user, password, path) - else: - newurl = url - ssl_trans = XMLRPCTransport(key, cert, ca, allowedServerCNs, timeout=timeout) - return xmlrpclib.ServerProxy(newurl, allow_none=True, transport=ssl_trans) |