From 31027c6183e3df927b08f0f0b7f84ae7420c3e88 Mon Sep 17 00:00:00 2001 From: John Dennis Date: Mon, 31 May 2010 07:40:17 -0400 Subject: use NSS for SSL operations --- ipalib/rpc.py | 133 ++++------------------------------------------------------ 1 file changed, 7 insertions(+), 126 deletions(-) (limited to 'ipalib/rpc.py') diff --git a/ipalib/rpc.py b/ipalib/rpc.py index f9067d1bd..686df3cba 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -32,7 +32,6 @@ Also see the `ipaserver.rpcserver` module. from types import NoneType import threading -import socket import os import errno from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, Transport, ProtocolError @@ -42,15 +41,9 @@ from ipalib.errors import public_errors, PublicError, UnknownError, NetworkError from ipalib import errors from ipalib.request import context from ipapython import ipautil -from OpenSSL import SSL import httplib - -try: - from httplib import SSLFile - from httplib import FakeSocket -except ImportError: - from ipapython.ipasslfile import SSLFile - from ipapython.ipasslfile import FakeSocket +from ipapython.nsslib import NSSHTTPS +from nss.error import NSPRError # Some Kerberos error definitions from krb5.h KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = (-1765328377L) @@ -199,121 +192,9 @@ class SSLTransport(Transport): def make_connection(self, host): host, extra_headers, x509 = self.get_host_info(host) - return SSLSocket(host, None, **(x509 or {})) - - -class SSLFile(SSLFile): - """ - Override the _read method so we can handle PyOpenSSL errors - gracefully. - """ - def _read(self): - buf = '' - while True: - try: - buf = self._ssl.read(self._bufsize) - except SSL.ZeroReturnError: - # Nothing more to be read - break - except SSL.SysCallError, e: - print "SSL exception", e.args - break - except SSL.WantWriteError: - break - except SSL.WantReadError: - break - except socket.error, err: - if err[0] == errno.EINTR: - continue - if err[0] == errno.EBADF: - # XXX socket was closed? - break - raise - else: - break - return buf - - -class FakeSocket(FakeSocket): - """ - Override this class so we can end up using our own SSLFile - implementation. - """ - def makefile(self, mode, bufsize=None): - if mode != 'r' and mode != 'rb': - raise httplib.UnimplementedFileMode() - return SSLFile(self._shared, self._ssl, bufsize) - - -class SSLConnection(httplib.HTTPConnection): - """ - Use OpenSSL as the SSL provider instead of the built-in python SSL - support. The built-in SSL client doesn't do CA validation. - - By default we will attempt to load the ca-bundle.crt and our own - IPA CA for validation purposes. To add an additional CA to verify - against set the x509['ca_file'] to the path of the CA PEM file in - KerbTransport.get_host_info - """ - default_port = httplib.HTTPSConnection.default_port - - def verify_callback(self, conn, cert, errnum, depth, ok): - """ - Verify callback. If we get here then the certificate is ok. - """ - return ok - - def __init__(self, host, port=None, key_file=None, cert_file=None, - ca_file=None, strict=None): - httplib.HTTPConnection.__init__(self, host, port, strict) - self.key_file = key_file - self.cert_file = cert_file - self.ca_file = ca_file - - def connect(self): - ctx = SSL.Context(SSL.SSLv23_METHOD) - ctx.set_verify(SSL.VERIFY_PEER, self.verify_callback) - if self.key_file: - ctx.use_privatekey_file (self.key_file) - if self.cert_file: - ctx.use_certificate_file(self.cert_file) - if os.path.exists("/etc/pki/tls/certs/ca-bundle.crt"): - ctx.load_verify_locations("/etc/pki/tls/certs/ca-bundle.crt") - if os.path.exists("/etc/ipa/ca.crt"): - ctx.load_verify_locations("/etc/ipa/ca.crt") - if self.ca_file is not None and os.path.exists(self.ca_file): - ctx.load_verify_locations(self.ca_file) - - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - ssl = SSL.Connection(ctx, sock) - ssl.connect((self.host, self.port)) - ssl.do_handshake() - self.sock = FakeSocket(sock, ssl) - - -class SSLSocket(httplib.HTTP): - """ - This is more or less equivalent to the httplib.HTTPS class, we juse - use our own connection provider. - """ - _connection_class = SSLConnection - - def __init__(self, host='', port=None, key_file=None, cert_file=None, - ca_file=None, strict=None): - # provide a default host, pass the X509 cert info - - # urf. compensate for bad input. - if port == 0: - port = None - self._setup(self._connection_class(host, port, key_file, - cert_file, ca_file, strict)) - - # we never actually use these for anything, but we keep them - # here for compatibility with post-1.5.2 CVS. - self.key_file = key_file - self.cert_file = cert_file - self.ca_file = ca_file - + conn = NSSHTTPS(host, 443, dbdir="/etc/pki/nssdb") + conn.connect() + return conn class KerbTransport(SSLTransport): """ @@ -417,7 +298,7 @@ class xmlclient(Connectible): error=e.faultString, server=self.env.xmlrpc_uri, ) - except socket.error, e: - raise NetworkError(uri=self.env.xmlrpc_uri, error=e.args[1]) + except NSPRError, e: + raise NetworkError(uri=self.env.xmlrpc_uri, error=str(e)) except ProtocolError, e: raise NetworkError(uri=self.env.xmlrpc_uri, error=e.errmsg) -- cgit