diff -r 4cf5e664c847 -r 3406d3bf05d4 iro/xmlrpc/SecureXMLRPCServer.py --- a/iro/xmlrpc/SecureXMLRPCServer.py Wed Mar 21 19:41:55 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -""" -SecureXMLRPCServer module using pyOpenSSL 0.5 -Written 0907.2002 -by Michal Wallace -http://www.sabren.net/ - -This acts exactly like SimpleXMLRPCServer -from the standard python library, but -uses secure connections. The technique -and classes should work for any SocketServer -style server. However, the code has not -been extensively tested. - -This code is in the public domain. -It is provided AS-IS WITH NO WARRANTY WHATSOEVER. -""" -import SocketServer -import os, socket -import SimpleXMLRPCServer -from OpenSSL import SSL - -class SSLWrapper: - """ - This whole class exists just to filter out a parameter - passed in to the shutdown() method in SimpleXMLRPC.doPOST() - """ - def __init__(self, conn): - """ - Connection is not yet a new-style class, - so I'm making a proxy instead of subclassing. - """ - self.__dict__["conn"] = conn - def __getattr__(self,name): - return getattr(self.__dict__["conn"], name) - def __setattr__(self,name, value): - setattr(self.__dict__["conn"], name, value) - def shutdown(self, how=1): - """ - SimpleXMLRpcServer.doPOST calls shutdown(1), - and Connection.shutdown() doesn't take - an argument. So we just discard the argument. - """ - self.__dict__["conn"].shutdown() - def accept(self): - """ - This is the other part of the shutdown() workaround. - Since servers create new sockets, we have to infect - them with our magic. :) - """ - c, a = self.__dict__["conn"].accept() - return (SSLWrapper(c), a) - - - -class SecureTCPServer(SocketServer.TCPServer): - """ - Just like TCPServer, but use a socket. - This really ought to let you specify the key and certificate files. - """ - def __init__(self, server_address, RequestHandlerClass,certificate,privatekey): - SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass) - - ## Same as normal, but make it secure: - ctx = SSL.Context(SSL.SSLv23_METHOD) - ctx.set_options(SSL.OP_NO_SSLv2) - - ctx.use_privatekey_file (privatekey) - ctx.use_certificate_file(certificate) - - self.socket = SSLWrapper(SSL.Connection(ctx, socket.socket(self.address_family, - self.socket_type))) - self.server_bind() - self.server_activate() - - -class SecureXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - def setup(self): - """ - We need to use socket._fileobject Because SSL.Connection - doesn't have a 'dup'. Not exactly sure WHY this is, but - this is backed up by comments in socket.py and SSL/connection.c - """ - self.connection = self.request # for doPOST - self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) - self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) - - -class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, SecureTCPServer): - def __init__(self, addr, - requestHandler=SecureXMLRPCRequestHandler, - certificate="server.cert",privatekey="server.pem", - logRequests=1): - """ - This is the exact same code as SimpleXMLRPCServer.__init__ - except it calls SecureTCPServer.__init__ instead of plain - old TCPServer.__init__ - """ - self.funcs = {} - self.logRequests = logRequests - self.instance = None - SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self,False,None) - SecureTCPServer.__init__(self, addr, requestHandler,certificate=certificate,privatekey=privatekey) - - -def test(): - server = SecureXMLRPCServer.SecureXMLRPCServer(("localhost", 8000),requestHandler=SecureXMLRPCRequestHandler,certificate="./certs/test.cert.pem",privatekey="./certs/test.key.pem") - server.register_introspection_functions() - server.register_function(lambda x: x*x, 'square') - server.serve_forever() - -if __name__ == '__main__': - test() -