This patch removes the use of OpenSSL (via Python's native libraries) for SSL operations and substitutes NSS for SSL. We were already using NSS in some places, now it's consistently universal.

Be aware that this patch depends on a an upgrade of python-nss to 0.9.

The patch also fixes a problem with certification validation, previously we had not been fully validating a certificate and as such it was a security vulnerability.

--
John Dennis <jden...@redhat.com>

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
>From 8633a03ce20fde85b61d37b932e52a524e0321f2 Mon Sep 17 00:00:00 2001
From: John Dennis <jden...@redhat.com>
Date: Mon, 31 May 2010 07:40:17 -0400
Subject: [PATCH 16/16] use NSS for SSL operations
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

---
 ipa.spec.in                     |    2 +-
 ipalib/rpc.py                   |  133 ++---------------------
 ipapython/dogtag.py             |   13 ++-
 ipapython/ipasslfile.py         |  185 -------------------------------
 ipapython/nsslib.py             |  228 +++++++++++++++++++++++++++------------
 ipaserver/install/cainstance.py |   24 ----
 ipaserver/install/certs.py      |   24 ----
 7 files changed, 175 insertions(+), 434 deletions(-)
 delete mode 100644 ipapython/ipasslfile.py

diff --git a/ipa.spec.in b/ipa.spec.in
index 0e5d575..3120cd4 100644
--- a/ipa.spec.in
+++ b/ipa.spec.in
@@ -178,7 +178,7 @@ Requires: python-kerberos >= 1.1-3
 Requires: authconfig
 Requires: gnupg
 Requires: pyOpenSSL
-Requires: python-nss >= 0.8
+Requires: python-nss >= 0.9
 Requires: python-lxml
 
 %description python
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index f9067d1..686df3c 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)
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index c6b3a5d..96d9469 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -22,9 +22,9 @@ import httplib
 import xml.dom.minidom
 from ipapython import nsslib
 import nss.nss as nss
+from nss.error import NSPRError
 from ipalib.errors import NetworkError, CertificateOperationError
 from urllib import urlencode
-import socket
 import logging
 
 def get_ca_certchain(ca_host=None):
@@ -76,10 +76,11 @@ def https_request(host, port, url, secdir, password, nickname, **kw):
                        "Accept": "text/plain"}
     try:
         conn = nsslib.NSSConnection(host, port, dbdir=secdir)
-        conn.sslsock.set_client_auth_data_callback(nsslib.client_auth_data_callback,
-                                                   nickname,
-                                                   password, nss.get_default_certdb())
+        conn.sock.set_client_auth_data_callback(nsslib.client_auth_data_callback,
+                                                nickname,
+                                                password, nss.get_default_certdb())
         conn.set_debuglevel(0)
+        conn.connect()
         conn.request("POST", url, post, request_headers)
 
         res = conn.getresponse()
@@ -122,8 +123,8 @@ def http_request(host, port, url, **kw):
             http_headers = res.msg.dict
             http_body = res.read()
             conn.close()
-        except socket.error, e:
-            raise NetworkError(uri=uri, error=e.args[1])
+        except NSPRError, e:
+            raise NetworkError(uri=uri, error=str(e))
 
         logging.debug('request status %d',        http_status)
         logging.debug('request reason_phrase %r', http_reason_phrase)
diff --git a/ipapython/ipasslfile.py b/ipapython/ipasslfile.py
deleted file mode 100644
index 2082e26..0000000
--- a/ipapython/ipasslfile.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# This is a forward backport of the Python2.5 uuid module. It isn't available
-# in Python 2.6
-
-# The next several classes are used to define FakeSocket, a socket-like
-# interface to an SSL connection.
-
-# The primary complexity comes from faking a makefile() method.  The
-# standard socket makefile() implementation calls dup() on the socket
-# file descriptor.  As a consequence, clients can call close() on the
-# parent socket and its makefile children in any order.  The underlying
-# socket isn't closed until they are all closed.
-
-# The implementation uses reference counting to keep the socket open
-# until the last client calls close().  SharedSocket keeps track of
-# the reference counting and SharedSocketClient provides an constructor
-# and close() method that call incref() and decref() correctly.
-
-import socket
-import errno
-from httplib import UnimplementedFileMode, HTTPException
-
-error = HTTPException
-
-class SharedSocket:
-    def __init__(self, sock):
-        self.sock = sock
-        self._refcnt = 0
-
-    def incref(self):
-        self._refcnt += 1
-
-    def decref(self):
-        self._refcnt -= 1
-        assert self._refcnt >= 0
-        if self._refcnt == 0:
-            self.sock.close()
-
-    def __del__(self):
-        self.sock.close()
-
-class SharedSocketClient:
-
-    def __init__(self, shared):
-        self._closed = 0
-        self._shared = shared
-        self._shared.incref()
-        self._sock = shared.sock
-
-    def close(self):
-        if not self._closed:
-            self._shared.decref()
-            self._closed = 1
-            self._shared = None
-
-class SSLFile(SharedSocketClient):
-    """File-like object wrapping an SSL socket."""
-
-    BUFSIZE = 8192
-
-    def __init__(self, sock, ssl, bufsize=None):
-        SharedSocketClient.__init__(self, sock)
-        self._ssl = ssl
-        self._buf = ''
-        self._bufsize = bufsize or self.__class__.BUFSIZE
-
-    def _read(self):
-        buf = ''
-        # put in a loop so that we retry on transient errors
-        while True:
-            try:
-                buf = self._ssl.read(self._bufsize)
-            except socket.sslerror, err:
-                if (err[0] == socket.SSL_ERROR_WANT_READ
-                    or err[0] == socket.SSL_ERROR_WANT_WRITE):
-                    continue
-                if (err[0] == socket.SSL_ERROR_ZERO_RETURN
-                    or err[0] == socket.SSL_ERROR_EOF):
-                    break
-                raise
-            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
-
-    def read(self, size=None):
-        L = [self._buf]
-        avail = len(self._buf)
-        while size is None or avail < size:
-            s = self._read()
-            if s == '':
-                break
-            L.append(s)
-            avail += len(s)
-        alldata = "".join(L)
-        if size is None:
-            self._buf = ''
-            return alldata
-        else:
-            self._buf = alldata[size:]
-            return alldata[:size]
-
-    def readline(self):
-        L = [self._buf]
-        self._buf = ''
-        while 1:
-            i = L[-1].find("\n")
-            if i >= 0:
-                break
-            s = self._read()
-            if s == '':
-                break
-            L.append(s)
-        if i == -1:
-            # loop exited because there is no more data
-            return "".join(L)
-        else:
-            alldata = "".join(L)
-            # XXX could do enough bookkeeping not to do a 2nd search
-            i = alldata.find("\n") + 1
-            line = alldata[:i]
-            self._buf = alldata[i:]
-            return line
-
-    def readlines(self, sizehint=0):
-        total = 0
-        inlist = []
-        while True:
-            line = self.readline()
-            if not line:
-                break
-            inlist.append(line)
-            total += len(line)
-            if sizehint and total >= sizehint:
-                break
-        return inlist
-
-    def fileno(self):
-        return self._sock.fileno()
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        line = self.readline()
-        if not line:
-            raise StopIteration
-        return line
-
-class FakeSocket(SharedSocketClient):
-
-    class _closedsocket:
-        def __getattr__(self, name):
-            raise error(9, 'Bad file descriptor')
-
-    def __init__(self, sock, ssl):
-        sock = SharedSocket(sock)
-        SharedSocketClient.__init__(self, sock)
-        self._ssl = ssl
-
-    def close(self):
-        SharedSocketClient.close(self)
-        self._sock = self.__class__._closedsocket()
-
-    def makefile(self, mode, bufsize=None):
-        if mode != 'r' and mode != 'rb':
-            raise UnimplementedFileMode()
-        return SSLFile(self._shared, self._ssl, bufsize)
-
-    def send(self, stuff, flags = 0):
-        return self._ssl.write(stuff)
-
-    sendall = send
-
-    def recv(self, len = 1024, flags = 0):
-        return self._ssl.read(len)
-
-    def __getattr__(self, attr):
-        return getattr(self._sock, attr)
-
diff --git a/ipapython/nsslib.py b/ipapython/nsslib.py
index 2052843..1710a7d 100644
--- a/ipapython/nsslib.py
+++ b/ipapython/nsslib.py
@@ -1,4 +1,5 @@
 # Authors: Rob Crittenden <rcrit...@redhat.com>
+#          John Dennis <jden...@redhat.com>
 #
 # Copyright (C) 2009    Red Hat
 # see file 'COPYING' for use and warranty information
@@ -19,19 +20,75 @@
 
 import httplib
 import getpass
-import socket
+import logging
 
 from nss.error import NSPRError
 import nss.io as io
 import nss.nss as nss
 import nss.ssl as ssl
 
-try:
-    from httplib import SSLFile
-    from httplib import FakeSocket
-except ImportError:
-    from ipapython.ipasslfile import SSLFile
-    from ipapython.ipasslfile import FakeSocket
+def auth_certificate_callback(sock, check_sig, is_server, certdb):
+    cert_is_valid = False
+
+    cert = sock.get_peer_certificate()
+
+    logging.debug("auth_certificate_callback: check_sig=%s is_server=%s\n%s",
+                  check_sig, is_server, str(cert))
+
+    pin_args = sock.get_pkcs11_pin_arg()
+    if pin_args is None:
+        pin_args = ()
+
+    # Define how the cert is being used based upon the is_server flag.  This may
+    # seem backwards, but isn't. If we're a server we're trying to validate a
+    # client cert. If we're a client we're trying to validate a server cert.
+    if is_server:
+        intended_usage = nss.certificateUsageSSLClient
+    else:
+        intended_usage = nss.certificateUsageSSLServer
+
+    try:
+        # If the cert fails validation it will raise an exception, the errno attribute
+        # will be set to the error code matching the reason why the validation failed
+        # and the strerror attribute will contain a string describing the reason.
+        approved_usage = cert.verify_now(certdb, check_sig, intended_usage, *pin_args)
+    except Exception, e:
+        logging.error('cert validation failed for "%s" (%s)', cert.subject, e.strerror)
+        cert_is_valid = False
+        return cert_is_valid
+
+    logging.debug("approved_usage = %s intended_usage = %s",
+                  ', '.join(nss.cert_usage_flags(approved_usage)),
+                  ', '.join(nss.cert_usage_flags(intended_usage)))
+
+    # Is the intended usage a proper subset of the approved usage
+    if approved_usage & intended_usage:
+        cert_is_valid = True
+    else:
+        cert_is_valid = False
+
+    # If this is a server, we're finished
+    if is_server or not cert_is_valid:
+        logging.debug('cert valid %s for "%s"', cert_is_valid,  cert.subject)
+        return cert_is_valid
+
+    # Certificate is OK.  Since this is the client side of an SSL
+    # connection, we need to verify that the name field in the cert
+    # matches the desired hostname.  This is our defense against
+    # man-in-the-middle attacks.
+
+    hostname = sock.get_hostname()
+    try:
+        # If the cert fails validation it will raise an exception
+        cert_is_valid = cert.verify_hostname(hostname)
+    except Exception, e:
+        logging.error('failed verifying socket hostname "%s" matches cert subject "%s" (%s)',
+                      hostname, cert.subject, e.strerror)
+        cert_is_valid = False
+        return cert_is_valid
+
+    logging.debug('cert valid %s for "%s"', cert_is_valid,  cert.subject)
+    return cert_is_valid
 
 def client_auth_data_callback(ca_names, chosen_nickname, password, certdb):
     cert = None
@@ -55,56 +112,32 @@ def client_auth_data_callback(ca_names, chosen_nickname, password, certdb):
                 return False
         return False
 
-class SSLFile(SSLFile):
-    """
-    Override the _read method so we can use the NSS recv method.
-    """
-    def _read(self):
-        buf = ''
-        while True:
-            try:
-                buf = self._ssl.recv(self._bufsize)
-            except NSPRError, e:
-                raise e
-            else:
-                break
-        return buf
-
-class NSSFakeSocket(FakeSocket):
-    def makefile(self, mode, bufsize=None):
-        if mode != 'r' and mode != 'rb':
-            raise httplib.UnimplementedFileMode()
-        return SSLFile(self._shared, self._ssl, bufsize)
-
-    def send(self, stuff, flags = 0):
-        return self._ssl.send(stuff)
-
-    sendall = send
-
 class NSSConnection(httplib.HTTPConnection):
     default_port = httplib.HTTPSConnection.default_port
 
-    def __init__(self, host, port=None, key_file=None, cert_file=None,
-                 ca_file='/etc/pki/tls/certs/ca-bundle.crt', strict=None,
-                 dbdir=None):
+    def __init__(self, host, port=None, strict=None, dbdir=None):
         httplib.HTTPConnection.__init__(self, host, port, strict)
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.ca_file = ca_file
 
         if not dbdir:
             raise RuntimeError("dbdir is required")
 
+        logging.debug('%s init %s', self.__class__.__name__, host)
         nss.nss_init(dbdir)
         ssl.set_domestic_policy()
         nss.set_password_callback(self.password_callback)
 
         # Create the socket here so we can do things like let the caller
         # override the NSS callbacks
-        self.sslsock = ssl.SSLSocket()
-        self.sslsock.set_ssl_option(ssl.SSL_SECURITY, True)
-        self.sslsock.set_ssl_option(ssl.SSL_HANDSHAKE_AS_CLIENT, True)
-        self.sslsock.set_handshake_callback(self.handshake_callback)
+        self.sock = ssl.SSLSocket()
+        self.sock.set_ssl_option(ssl.SSL_SECURITY, True)
+        self.sock.set_ssl_option(ssl.SSL_HANDSHAKE_AS_CLIENT, True)
+
+        # Provide a callback which notifies us when the SSL handshake is complete
+        self.sock.set_handshake_callback(self.handshake_callback)
+
+        # Provide a callback to verify the servers certificate
+        self.sock.set_auth_certificate_callback(auth_certificate_callback,
+                                           nss.get_default_certdb())
 
     def password_callback(self, slot, retry, password):
         if not retry and password: return password
@@ -114,43 +147,102 @@ class NSSConnection(httplib.HTTPConnection):
         """
         Verify callback. If we get here then the certificate is ok.
         """
-        if self.debuglevel > 0:
-            print "handshake complete, peer = %s" % (sock.get_peer_name())
+        logging.debug("handshake complete, peer = %s", sock.get_peer_name())
         pass
 
     def connect(self):
-        self.sslsock.set_hostname(self.host)
-
+        logging.debug("connect: host=%s port=%s", self.host, self.port)
+        self.sock.set_hostname(self.host)
         net_addr = io.NetworkAddress(self.host, self.port)
-
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sslsock.connect(net_addr)
-        self.sock = NSSFakeSocket(sock, self.sslsock)
+        logging.debug("connect: %s", net_addr)
+        self.sock.connect(net_addr)
 
 class NSSHTTPS(httplib.HTTP):
+    # We would like to use HTTP 1.1 not the older HTTP 1.0 but xmlrpclib
+    # and httplib do not play well together. httplib when the protocol
+    # is 1.1 will add a host header in the request. But xmlrpclib
+    # always adds a host header irregardless of the HTTP protocol
+    # version. That means the request ends up with 2 host headers,
+    # but Apache freaks out if it sees 2 host headers, a known Apache
+    # issue. httplib has a mechanism to skip adding the host header
+    # (i.e. skip_host in HTTPConnection.putrequest()) but xmlrpclib
+    # doesn't use it. Oh well, back to 1.0  :-(
+    #
+    #_http_vsn = 11
+    #_http_vsn_str = 'HTTP/1.1'
+
     _connection_class = NSSConnection
 
-    def __init__(self, host='', port=None, key_file=None, cert_file=None,
-                 ca_file='/etc/pki/tls/certs/ca-bundle.crt', strict=None):
+    def __init__(self, host='', port=None, strict=None, dbdir=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
+        self._setup(self._connection_class(host, port, strict, dbdir=dbdir))
+
+class NSPRConnection(httplib.HTTPConnection):
+    default_port = httplib.HTTPConnection.default_port
+
+    def __init__(self, host, port=None, strict=None):
+        httplib.HTTPConnection.__init__(self, host, port, strict)
+
+        logging.debug('%s init %s', self.__class__.__name__, host)
+        nss.nss_init_nodb()
+
+        self.sock = io.Socket()
+    def connect(self):
+        logging.debug("connect: host=%s port=%s", self.host, self.port)
+        net_addr = io.NetworkAddress(self.host, self.port)
+        logging.debug("connect: %s", net_addr)
+        self.sock.connect(net_addr)
+
+class NSPRHTTP(httplib.HTTP):
+    _http_vsn = 11
+    _http_vsn_str = 'HTTP/1.1'
+
+    _connection_class = NSPRConnection
+
+#------------------------------------------------------------------------------
 
 if __name__ == "__main__":
-    h = NSSConnection("www.verisign.com", 443, dbdir="/etc/pki/nssdb")
-    h.set_debuglevel(1)
-    h.request("GET", "/")
-    res = h.getresponse()
-    print res.status
-    data = res.read()
-    print data
-    h.close()
+    logging.basicConfig(level=logging.DEBUG,
+                        format='%(asctime)s %(levelname)-8s %(message)s',
+                        datefmt='%m-%d %H:%M',
+                        filename='nsslib.log',
+                        filemode='a')
+    # Create a seperate logger for the console
+    console_logger = logging.StreamHandler()
+    console_logger.setLevel(logging.DEBUG)
+    # set a format which is simpler for console use
+    formatter = logging.Formatter('%(levelname)s %(message)s')
+    console_logger.setFormatter(formatter)
+    # add the handler to the root logger
+    logging.getLogger('').addHandler(console_logger)
+    logging.info("Start")
+
+    if False:
+        conn = NSSConnection("www.verisign.com", 443, dbdir="/etc/pki/nssdb")
+        conn.set_debuglevel(1)
+        conn.connect()
+        conn.request("GET", "/")
+        response = conn.getresponse()
+        print response.status
+        #print response.msg
+        print response.getheaders()
+        data = response.read()
+        #print data
+        conn.close()
+
+    if True:
+        h = NSSHTTPS("www.verisign.com", 443, dbdir="/etc/pki/nssdb")
+        h.connect()
+        h.putrequest('GET', '/')
+        h.endheaders()
+        http_status, http_reason, headers = h.getreply()
+        print "status = %s %s" % (http_status, http_reason)
+        print "headers:\n%s" % headers
+        f = h.getfile()
+        data = f.read() # Get the raw HTML
+        f.close()
+        #print data
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 90028b4..035d631 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -125,30 +125,6 @@ def import_pkcs12(input_file, input_passwd, cert_database,
                  "-k", cert_passwd,
                  "-w", input_passwd])
 
-def client_auth_data_callback(ca_names, chosen_nickname, password, certdb):
-    cert = None
-    if chosen_nickname:
-        try:
-            cert = nss.find_cert_from_nickname(chosen_nickname, password)
-            priv_key = nss.find_key_by_any_cert(cert, password)
-            return cert, priv_key
-        except NSPRError, e:
-            logging.debug("client auth callback failed %s" % str(e))
-            return False
-    else:
-        nicknames = nss.get_cert_nicknames(certdb, nss.SEC_CERT_NICKNAMES_USER)
-        for nickname in nicknames:
-            try:
-                cert = nss.find_cert_from_nickname(nickname, password)
-                if cert.check_valid_times():
-                    if cert.has_signer_in_ca_names(ca_names):
-                        priv_key = nss.find_key_by_any_cert(cert, password)
-                        return cert, priv_key
-            except NSPRError, e:
-                logging.debug("client auth callback failed %s" % str(e))
-                return False
-        return False
-
 def get_value(s):
     """
     Parse out a name/value pair from a Javascript variable.
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 6fb0129..cf89c22 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -60,30 +60,6 @@ def ipa_self_signed():
     else:
         return False
 
-def client_auth_data_callback(ca_names, chosen_nickname, password, certdb):
-    cert = None
-    if chosen_nickname:
-        try:
-            cert = nss.find_cert_from_nickname(chosen_nickname, password)
-            priv_key = nss.find_key_by_any_cert(cert, password)
-            return cert, priv_key
-        except NSPRError, e:
-            logging.debug("client auth callback failed %s" % str(e))
-            return False
-    else:
-        nicknames = nss.get_cert_nicknames(certdb, nss.SEC_CERT_NICKNAMES_USER)
-        for nickname in nicknames:
-            try:
-                cert = nss.find_cert_from_nickname(nickname, password)
-                if cert.check_valid_times():
-                    if cert.has_signer_in_ca_names(ca_names):
-                        priv_key = nss.find_key_by_any_cert(cert, password)
-                        return cert, priv_key
-            except NSPRError, e:
-                logging.debug("client auth callback failed %s" % str(e))
-                return False
-        return False
-
 def find_cert_from_txt(cert, start=0):
     """
     Given a cert blob (str) which may or may not contian leading and
-- 
1.6.6.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to