X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=util%2Fgeniserver.py;fp=util%2Fgeniserver.py;h=c4ba7cf3fee647bdeda6060d99cb9b5ae64f3cd7;hb=181221b1bdafd624bc9eafede7f152e38730657b;hp=b8cc0470483d81969871d0a660ddc5f73f00c9e6;hpb=efb9b9866c3f2ce02f99bf0b80d18ee58eec4af4;p=sfa.git diff --git a/util/geniserver.py b/util/geniserver.py index b8cc0470..c4ba7cf3 100644 --- a/util/geniserver.py +++ b/util/geniserver.py @@ -10,25 +10,26 @@ import SimpleXMLRPCServer import sys import traceback +import threading import SocketServer -import BaseHTTPServer -import SimpleHTTPServer -import SimpleXMLRPCServer - -from excep import * -from cert import * -from credential import * - -import socket, os -from OpenSSL import SSL - -## -# Verification callback for pyOpenSSL. We do our own checking of keys because -# we have our own authentication spec. Thus we disable several of the normal -# prohibitions that OpenSSL places on certificates - -def verify_callback(conn, x509, err, depth, preverify): - # if the cert has been preverified, then it is ok +import BaseHTTPServer +import SimpleHTTPServer +import SimpleXMLRPCServer + +from excep import * +from cert import * +from credential import * + +import socket, os +from OpenSSL import SSL + +## +# Verification callback for pyOpenSSL. We do our own checking of keys because +# we have our own authentication spec. Thus we disable several of the normal +# prohibitions that OpenSSL places on certificates + +def verify_callback(conn, x509, err, depth, preverify): + # if the cert has been preverified, then it is ok if preverify: #print " preverified" return 1 @@ -71,90 +72,90 @@ def verify_callback(conn, x509, err, depth, preverify): print " error", err, "in verify_callback" return 0 - -## -# Taken from the web (XXX find reference). Implements an HTTPS xmlrpc server - -class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher): - def __init__(self, server_address, HandlerClass, key_file, cert_file, logRequests=True): - """Secure XML-RPC server. - - It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data. - """ - self.logRequests = logRequests - - SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, True, None) - SocketServer.BaseServer.__init__(self, server_address, HandlerClass) - ctx = SSL.Context(SSL.SSLv23_METHOD) - ctx.use_privatekey_file(key_file) - ctx.use_certificate_file(cert_file) - ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback) - ctx.set_app_data(self) - self.socket = SSL.Connection(ctx, socket.socket(self.address_family, - self.socket_type)) - self.server_bind() - self.server_activate() - - # _dispatch + +## +# Taken from the web (XXX find reference). Implements an HTTPS xmlrpc server + +class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher): + def __init__(self, server_address, HandlerClass, key_file, cert_file, logRequests=True): + """Secure XML-RPC server. + + It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data. + """ + self.logRequests = logRequests + + SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, True, None) + SocketServer.BaseServer.__init__(self, server_address, HandlerClass) + ctx = SSL.Context(SSL.SSLv23_METHOD) + ctx.use_privatekey_file(key_file) + ctx.use_certificate_file(cert_file) + ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback) + ctx.set_app_data(self) + self.socket = SSL.Connection(ctx, socket.socket(self.address_family, + self.socket_type)) + self.server_bind() + self.server_activate() + + # _dispatch # # Convert an exception on the server to a full stack trace and send it to # the client. - def _dispatch(self, method, params): - try: - return SimpleXMLRPCServer.SimpleXMLRPCDispatcher._dispatch(self, method, params) - except: - # can't use format_exc() as it is not available in jython yet (even - # in trunk). - type, value, tb = sys.exc_info() - raise xmlrpclib.Fault(1,''.join(traceback.format_exception(type, value, tb))) - -## -# taken from the web (XXX find reference). Implents HTTPS xmlrpc request handler - -class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - """Secure XML-RPC request handler class. - - It it very similar to SimpleXMLRPCRequestHandler but it uses HTTPS for transporting XML data. - """ - def setup(self): - self.connection = self.request - self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) - self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) - - def do_POST(self): - """Handles the HTTPS POST request. - - It was copied out from SimpleXMLRPCServer.py and modified to shutdown the socket cleanly. - """ - - try: - # get arguments - data = self.rfile.read(int(self.headers["content-length"])) - # In previous versions of SimpleXMLRPCServer, _dispatch - # could be overridden in this class, instead of in - # SimpleXMLRPCDispatcher. To maintain backwards compatibility, - # check to see if a subclass implements _dispatch and dispatch - # using that method if present. - response = self.server._marshaled_dispatch( - data, getattr(self, '_dispatch', None) - ) - except: # This should only happen if the module is buggy - # internal error, report as HTTP server error - self.send_response(500) - - self.end_headers() - else: - # got a valid XML RPC response - self.send_response(200) - self.send_header("Content-type", "text/xml") - self.send_header("Content-length", str(len(response))) - self.end_headers() - self.wfile.write(response) - - # shut down the connection - self.wfile.flush() - self.connection.shutdown() # Modified here! + def _dispatch(self, method, params): + try: + return SimpleXMLRPCServer.SimpleXMLRPCDispatcher._dispatch(self, method, params) + except: + # can't use format_exc() as it is not available in jython yet + # (evein in trunk). + type, value, tb = sys.exc_info() + raise xmlrpclib.Fault(1,''.join(traceback.format_exception(type, value, tb))) + +## +# taken from the web (XXX find reference). Implents HTTPS xmlrpc request handler + +class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): + """Secure XML-RPC request handler class. + + It it very similar to SimpleXMLRPCRequestHandler but it uses HTTPS for transporting XML data. + """ + def setup(self): + self.connection = self.request + self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) + self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) + + def do_POST(self): + """Handles the HTTPS POST request. + + It was copied out from SimpleXMLRPCServer.py and modified to shutdown the socket cleanly. + """ + + try: + # get arguments + data = self.rfile.read(int(self.headers["content-length"])) + # In previous versions of SimpleXMLRPCServer, _dispatch + # could be overridden in this class, instead of in + # SimpleXMLRPCDispatcher. To maintain backwards compatibility, + # check to see if a subclass implements _dispatch and dispatch + # using that method if present. + response = self.server._marshaled_dispatch( + data, getattr(self, '_dispatch', None) + ) + except: # This should only happen if the module is buggy + # internal error, report as HTTP server error + self.send_response(500) + + self.end_headers() + else: + # got a valid XML RPC response + self.send_response(200) + self.send_header("Content-type", "text/xml") + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + + # shut down the connection + self.wfile.flush() + self.connection.shutdown() # Modified here! ## # Implements an HTTPS XML-RPC server. Generally it is expected that GENI @@ -163,7 +164,7 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): # the credential, and verify that the user is using the key that matches the # GID supplied in the credential. -class GeniServer(): +class GeniServer(threading.Thread): ## # Create a new GeniServer object. @@ -171,7 +172,8 @@ class GeniServer(): # @param ip the ip address to listen on # @param port the port to listen on # @param key_file private key filename of registry - # @param cert_file certificate filename containing public key (could be a GID file) + # @param cert_file certificate filename containing public key + # (could be a GID file) def __init__(self, ip, port, key_file, cert_file): self.key = Keypair(filename = key_file) @@ -195,7 +197,7 @@ class GeniServer(): if not self.client_gid: raise MissingCallerGID(self.client_cred.get_subject()) - # make sure the client_gid matches the certificate that the client is using + # make sure the client_gid matches client's certificate peer_cert = self.server.peer_cert if not peer_cert.is_pubkey(self.client_gid.get_pubkey()): raise ConnectionKeyGIDMismatch(self.client_gid.get_subject())