X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Futil%2Fserver.py;h=fadd4cad5b095fae3459ced1e3502a69abe06ac6;hb=3eea82897aba845da0d12c1ba56012e599f58853;hp=505c7889a289e4cb6fb81a615703dab88786e22a;hpb=9c3a451f7d42b349462d2c80f81644c5a150b2f2;p=sfa.git diff --git a/sfa/util/server.py b/sfa/util/server.py index 505c7889..fadd4cad 100644 --- a/sfa/util/server.py +++ b/sfa/util/server.py @@ -6,27 +6,26 @@ # TODO: investigate ways to combine this with existing PLC server? ## -### $Id$ -### $URL$ - import sys +import socket, os import traceback import threading -import socket, os +from Queue import Queue import SocketServer import BaseHTTPServer import SimpleHTTPServer import SimpleXMLRPCServer from OpenSSL import SSL -from Queue import Queue -#import sfa.util.sfalogging from sfa.trust.certificate import Keypair, Certificate +from sfa.trust.trustedroot import TrustedRootList +from sfa.util.config import Config from sfa.trust.credential import * from sfa.util.faults import * from sfa.plc.api import SfaAPI from sfa.util.cache import Cache -#from sfa.util.debug import log +from sfa.util.sfalogging import logger + ## # 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 @@ -78,7 +77,7 @@ def verify_callback(conn, x509, err, depth, preverify): return 0 ## -# taken from the web (XXX find reference). Implents HTTPS xmlrpc request handler +# taken from the web (XXX find reference). Implements HTTPS xmlrpc request handler class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): """Secure XML-RPC request handler class. @@ -111,7 +110,7 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): except Exception, fault: # This should only happen if the module is buggy # internal error, report as HTTP server error - traceback.print_exc() + logger.log_exc("server.do_POST") response = self.api.prepare_response(fault) #self.send_response(500) #self.end_headers() @@ -135,6 +134,7 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data. """ + logger.debug("SecureXMLRPCServer.__init__, server_address=%s, cert_file=%s"%(server_address,cert_file)) self.logRequests = logRequests self.interface = None self.key_file = key_file @@ -153,6 +153,10 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR ctx.use_certificate_file(cert_file) # If you wanted to verify certs against known CAs.. this is how you would do it #ctx.load_verify_locations('/etc/sfa/trusted_roots/plc.gpo.gid') + config = Config() + trusted_cert_files = TrustedRootList(config.get_trustedroots_dir()).get_file_list() + for cert_file in trusted_cert_files: + ctx.load_verify_locations(cert_file) ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback) ctx.set_verify_depth(5) ctx.set_app_data(self) @@ -167,14 +171,41 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR # the client. def _dispatch(self, method, params): + logger.debug("SecureXMLRPCServer._dispatch, method=%s"%method) 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). + # (even in trunk). type, value, tb = sys.exc_info() raise xmlrpclib.Fault(1,''.join(traceback.format_exception(type, value, tb))) + # override this one from the python 2.7 code + # originally defined in class TCPServer + def shutdown_request(self, request): + """Called to shutdown and close an individual request.""" + # ---------- + # the std python 2.7 code just attempts a request.shutdown(socket.SHUT_WR) + # this works fine with regular sockets + # However we are dealing with an instance of OpenSSL.SSL.Connection instead + # This one only supports shutdown(), and in addition this does not + # always perform as expected + # ---------- std python 2.7 code + try: + #explicitly shutdown. socket.close() merely releases + #the socket and waits for GC to perform the actual close. + request.shutdown(socket.SHUT_WR) + except socket.error: + pass #some platforms may raise ENOTCONN here + # ---------- + except TypeError: + # we are dealing with an OpenSSL.Connection object, + # try to shut it down but never mind if that fails + try: request.shutdown() + except: pass + # ---------- + self.close_request(request) + ## From Active State code: http://code.activestate.com/recipes/574454/ # This is intended as a drop-in replacement for the ThreadingMixIn class in # module SocketServer of the standard lib. Instead of spawning a new thread @@ -247,15 +278,16 @@ class SfaServer(threading.Thread): # @param cert_file certificate filename containing public key # (could be a GID file) - def __init__(self, ip, port, key_file, cert_file): + def __init__(self, ip, port, key_file, cert_file,interface): threading.Thread.__init__(self) self.key = Keypair(filename = key_file) self.cert = Certificate(filename = cert_file) #self.server = SecureXMLRPCServer((ip, port), SecureXMLRpcRequestHandler, key_file, cert_file) self.server = ThreadedServer((ip, port), SecureXMLRpcRequestHandler, key_file, cert_file) + self.server.interface=interface self.trusted_cert_list = None self.register_functions() - + logger.info("Starting SfaServer, interface=%s"%interface) ## # Register functions that will be served by the XMLRPC server. This