summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2006-06-07 15:47:10 +0000
committerNarayan Desai <desai@mcs.anl.gov>2006-06-07 15:47:10 +0000
commit79c62a02345661661a56f2a0028e9dadeaa522c9 (patch)
tree5302a69187d186171ab5131a2d4d69570e82e13d /src
parent2ff7b9da07e194c78708b94dc5cf8d11347b96fd (diff)
downloadbcfg2-79c62a02345661661a56f2a0028e9dadeaa522c9.tar.gz
bcfg2-79c62a02345661661a56f2a0028e9dadeaa522c9.tar.bz2
bcfg2-79c62a02345661661a56f2a0028e9dadeaa522c9.zip
Step 2 of SSL client cert integration
* Make the client use pyOpenSSL (so that ca support can be implemented) * Make the server handle SSL errors more cleanly Remaining SSL client cert integration steps: * Implement the CertMgr plugin (ChrisV) * Implement server side cert policies * Implement no-cert fallback mode for client git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1872 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src')
-rw-r--r--src/lib/Client/Proxy.py100
-rw-r--r--src/lib/Server/Component.py15
2 files changed, 103 insertions, 12 deletions
diff --git a/src/lib/Client/Proxy.py b/src/lib/Client/Proxy.py
index 0e86c959c..9c2837817 100644
--- a/src/lib/Client/Proxy.py
+++ b/src/lib/Client/Proxy.py
@@ -1,19 +1,115 @@
'''Cobalt proxy provides client access to cobalt components'''
__revision__ = '$Revision$'
-import logging, socket, time, xmlrpclib, ConfigParser, httplib
+import logging, socket, time, xmlrpclib, ConfigParser, httplib, OpenSSL
class CobaltComponentError(Exception):
'''This error signals component connection errors'''
pass
+def verify_cb(conn, cert, errnum, depth, ok):
+ print 'Got certificate: %s' % cert.get_subject()
+ return ok
+
+class poSSLFile:
+ def __init__(self, sock, master):
+ self.sock = sock
+ self.master = master
+ self.read = self.sock.read
+ self.master.count += 1
+
+ def close(self):
+ self.master.count -= 1
+ if not self.master.count:
+ self.sock.close()
+
+ def readline(self):
+ data = ''
+ char = self.read(1)
+ while char != '\n':
+ data += char
+ char = self.read(1)
+ print data
+ return data
+
+ def read(self, size=None):
+ print "in read"
+ if size:
+ data = ''
+ while not data:
+ try:
+ data = self.sock.read(size)
+ except ZeroReturnError:
+ print "caught ssl error; retrying"
+ return data
+
+class pSockMaster:
+ def __init__(self, connection):
+ self._connection = connection
+ self.sendall = self._connection.send
+ self.count = 1
+
+ def makefile(self, mode, bufsize=None):
+ return poSSLFile(self._connection, self)
+
+ def close(self):
+ self.count -= 1
+ if not self.count:
+ self._connection.close()
+
+class PHTTPSConnection(httplib.HTTPSConnection):
+ "This class allows communication via SSL."
+
+ def __init__(self, host, port=None, key_file=None, cert_file=None,
+ strict=None):
+ httplib.HTTPSConnection.__init__(self, host, port, strict)
+ self.ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
+ self.ctx.set_verify(OpenSSL.SSL.VERIFY_PEER, verify_cb)
+ self.ctx.use_privatekey_file ('/tmp/keys/client.pkey')
+ self.ctx.use_certificate_file('/tmp/keys/client.cert')
+ self.ctx.load_verify_locations('/tmp/keys/CA.cert')
+
+ def connect(self):
+ "Connect to a host on a given (SSL) port."
+ self._sock = OpenSSL.SSL.Connection(self.ctx,
+ socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+ self._sock.connect((self.host, self.port))
+ self.sock = pSockMaster(self._sock)
+
+class PHTTPS(httplib.HTTPS):
+ _connection_class = PHTTPSConnection
+
class SafeTransport(xmlrpclib.Transport):
"""Handles an HTTPS transaction to an XML-RPC server."""
def make_connection(self, host):
# create a HTTPS connection object from a host descriptor
# host may be a string, or a (host, x509-dict) tuple
host, extra_headers, x509 = self.get_host_info(host)
- return httplib.HTTPS(host, None, '/tmp/keys/client.pkey', '/tmp/keys/client.cert')
+ return PHTTPS(host, None, '/tmp/keys/client.pkey', '/tmp/keys/client.cert')
+
+ def _parse_response(self, file, sock):
+ # read response from input file/socket, and parse it
+
+ p, u = self.getparser()
+
+ while 1:
+ if sock:
+ response = sock.recv(1024)
+ else:
+ try:
+ response = file.read(1024)
+ except OpenSSL.SSL.ZeroReturnError:
+ break
+ if not response:
+ break
+ if self.verbose:
+ print "body:", repr(response)
+ p.feed(response)
+
+ file.close()
+ p.close()
+
+ return u.close()
class SafeProxy:
'''Wrapper for proxy'''
diff --git a/src/lib/Server/Component.py b/src/lib/Server/Component.py
index 3315276b2..e88b5cabe 100644
--- a/src/lib/Server/Component.py
+++ b/src/lib/Server/Component.py
@@ -67,12 +67,6 @@ class SSLServer(BaseHTTPServer.HTTPServer):
print cert.get_pubkey()
return ok
-
-# print cert.subject_name_hash()
-#
-# print dir(cert.get_pubkey())
-# return ok
-
def handle_request(self):
"""Handle one request, possibly blocking."""
try:
@@ -83,10 +77,11 @@ class SSLServer(BaseHTTPServer.HTTPServer):
try:
self.process_request(request, client_address)
except Exception, err:
- print err
- if err[0][0][0] == 'SSL routines':
- log.error("%s from %s" % (err[0][0][2], client_address[0]))
- else:
+ print err, type(err)
+ try:
+ if err[0][0][0] == 'SSL routines':
+ log.error("%s from %s" % (err[0][0][2], client_address[0]))
+ except:
log.error("Unknown socket I/O failure from %s" % (client_address[0]), exc_info=1)
self.close_request(request)