diff options
author | Andrew Gaffney <agaffney@gentoo.org> | 2006-06-15 12:22:43 +0000 |
---|---|---|
committer | Andrew Gaffney <agaffney@gentoo.org> | 2006-06-15 12:22:43 +0000 |
commit | f1ffee7ab366f56abf5975670c286c07ea469222 (patch) | |
tree | 8fac06044a1f8e2670ed14e388467f1f15d55415 /client | |
parent | initial commit of secure xmlrpc client module (diff) | |
download | scire-f1ffee7ab366f56abf5975670c286c07ea469222.tar.gz scire-f1ffee7ab366f56abf5975670c286c07ea469222.tar.bz2 scire-f1ffee7ab366f56abf5975670c286c07ea469222.zip |
update of new xmlrpc classes
svn path=/; revision=101
Diffstat (limited to 'client')
-rw-r--r-- | client/SecureXMLRPCClient.py | 132 | ||||
-rwxr-xr-x | client/scirec.py | 32 |
2 files changed, 122 insertions, 42 deletions
diff --git a/client/SecureXMLRPCClient.py b/client/SecureXMLRPCClient.py index 145be65..33b2db9 100644 --- a/client/SecureXMLRPCClient.py +++ b/client/SecureXMLRPCClient.py @@ -1,36 +1,30 @@ import httplib import xmlrpclib import socket +import time from OpenSSL import SSL class SecureXMLRPCClient(xmlrpclib.ServerProxy): def __init__(self, host, port, client_cert, client_key, verify_cert_func=None): - self.__host = host - self.__port = port - self.__handler = "/RPC2" - self.__transport = SafeTransport(host, port, client_cert, client_key, verify_cert_func) - self.__encoding = None - self.__verbose = False - self.__allow_none = True + xmlrpclib.ServerProxy.__init__(self, "https://" + host + ":" + str(port), transport=SafeTransport(self.__host, client_cert, client_key, verify_cert_func), encoding="utf-8", allow_none=True) class SafeTransport(xmlrpclib.Transport): - def __init__(self, host, port, client_cert, client_key, verify_cert_func=None): + def __init__(self, host, client_cert, client_key, verify_cert_func=None): self.__host = host - self.__port = port self.__client_cert = client_cert self.__client_key = client_key self.__verify_cert_func = verify_cert_func def make_connection(self, host): -# host, extra_headers, x509 = self.get_host_info(host) - return HTTPS(self.__host, self.__port, self.__client_key, self.__client_cert, self.__verify_cert_func) + host, extra_headers, x509 = self.get_host_info(host) + return HTTPS(host, self.__client_key, self.__client_cert, self.__verify_cert_func) class HTTPS(httplib.HTTP): - def __init__(self, host='', port=None, key_file=None, cert_file=None, verify_cert_func=None): - self._setup(HTTPSConnection(host, port, key_file, cert_file, verify_cert_func)) + def __init__(self, host='', key_file=None, cert_file=None, verify_cert_func=None): + self._setup(HTTPSConnection(host, key_file, cert_file, verify_cert_func)) # we never actually use these for anything, but we keep them # here for compatibility with post-1.5.2 CVS. @@ -40,8 +34,8 @@ class HTTPS(httplib.HTTP): class HTTPSConnection(httplib.HTTPConnection): default_port = httplib.HTTPS_PORT - def __init__(self, host, port=None, key_file=None, cert_file=None, verify_cert_func=None): - httplib.HTTPConnection.__init__(self, host, port, None) + def __init__(self, host, key_file=None, cert_file=None, verify_cert_func=None): + httplib.HTTPConnection.__init__(self, host, None, None) self.verify_cert_func = verify_cert_func self.key_file = key_file self.cert_file = cert_file @@ -55,5 +49,111 @@ class HTTPSConnection(httplib.HTTPConnection): ctx.use_certificate_file(self.cert_file) # Set up client - self.sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) +# self.sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + real_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock = SSLWrapper(SSL.Connection(ctx, real_sock)) self.sock.connect((self.host, self.port)) + self.sock = SSLConnWrapper(self.sock) + print str(self.sock) + +class ConnWrapper: + ''' + Base class for implementing the rest of the wrappers in this module. + Operates by taking a connection argument which is used when 'self' doesn't + provide the functionality being requested. + ''' + def __init__(self, connection) : + print "ConnWrapper.__init__()" + self.connection = connection + + def __getattr__(self, function) : + return getattr(self.connection, function) + +class SSLConn2File(ConnWrapper): + ''' + Wrapper for SSL.Connection that makes it look like a file object for use + with xmlrpclib. + ''' + def __init__(self, connection): + print "SSLConn2File.__init__()" + ConnWrapper.__init__(self, connection) + self.buf = '' + self.closed = False + + def flush (self) : + pass + + def close(self) : + self.closed = True + + def readline(self, length=None) : + # inspect the internal buffer, if there's a newline there, use that. + # else, we need to fill the buffer up and do the same thing. + def bufManip(location) : + ''' + Update self.buf as if there were a newline at the offset @location. + Then return the string up to the newline. + ''' + result = self.buf[0 : location + 1] + self.buf = self.buf[location + 1:] + return result + + start_time = time.time() + + nl_loc = self.buf.find('\n') + if nl_loc != -1 : + return bufManip(nl_loc) + + segments = [] + while self.buf.find('\n') == -1 : + newdata = self.connection.recv(4096) + if len(newdata) : + segments.append(newdata) + if newdata.find('\n') != -1 : + self.buf += ''.join(segments) + nl_loc = self.buf.find('\n') + return bufManip(nl_loc) + else : + # if we get to here, it means we weren't able to fetch any + # more data with newlines (probably EOF). Just return the + # contents of the internal buffer. + self.buf += ''.join(segments) + return self.buf + +class SSLConnWrapper(ConnWrapper): + ''' + Proxy class to provide makefile function on SSL Connection objects. + ''' + def __init__(self, connection): + print "SSLConnWrapper.__init__()" + ConnWrapper.__init__(self, connection) + + def makefile(self, mode, bufsize = 0): + print "SSLConnWrapper.makefile()" +# (_, _) = (mode, bufsize) +# return SSLConn2File(self.connection) + print str(dir(self.connection)) + print str(self.connection) + fo = socket._fileobject(self.connection, mode, bufsize) + print str(fo) + return fo + + def shutdown(self, _) : + return self.connection.shutdown() + +class SSLWrapper(ConnWrapper): + ''' + Proxy class to inject the accept method to generate the *next* proxy class. + ''' + def __init__(self, connection) : + print "SSLWrapper.__init__()" + ConnWrapper.__init__(self, connection) + + def accept(self) : + (conn, whatsit) = self.connection.accept() + return (SSLConnWrapper(conn), whatsit) + +# def connect(self, addr): +# print "SSLWrapper.connect()" +# conn = self.connection.connect(addr) +# return SSLConnWrapper(conn) diff --git a/client/scirec.py b/client/scirec.py index 109d431..9f8fbee 100755 --- a/client/scirec.py +++ b/client/scirec.py @@ -3,10 +3,13 @@ from OpenSSL import SSL import certgen import sys, os, select, socket +from SecureXMLRPCClient import SecureXMLRPCClient +import xmlrpclib config_dir = "/tmp" def verify_server_cert(conn, cert, errnum, depth, ok): + print cert.digest("sha1") if not os.path.isfile(config_dir + "/known_servers"): print "Recording server's cert digest in known_servers" known_servers_file = open(config_dir + "/known_servers", "w") @@ -31,29 +34,6 @@ if __name__ == "__main__": if not os.path.isfile(config_dir + "/client.key") or not os.path.isfile(config_dir + "/client.cert"): generate_cert_and_key() - # Initialize context - ctx = SSL.Context(SSL.SSLv23_METHOD) - ctx.set_verify(SSL.VERIFY_PEER, verify_server_cert) # Demand a certificate - ctx.use_privatekey_file('/tmp/client.key') - ctx.use_certificate_file('/tmp/client.cert') -# ctx.load_verify_locations('/tmp/CA.cert') - - # Set up client - sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) - sock.connect(('localhost', 9876)) - - while 1: - line = sys.stdin.readline() - if line == '': - break - try: - sock.send(line) - sys.stdout.write(sock.recv(1024)) - sys.stdout.flush() - except SSL.Error: - print 'Connection died unexpectedly' - break - - sock.shutdown() - sock.close() - + client = SecureXMLRPCClient("localhost", 9876, "/tmp/client.cert", "/tmp/client.key", verify_server_cert) +# client = xmlrpclib.ServerProxy("https://localhost:9876") + print client.say_hello() |