cleaned up imports
[sfa.git] / sfa / util / server.py
index e6d3f3b..b5a966d 100644 (file)
@@ -19,12 +19,13 @@ import SimpleHTTPServer
 import SimpleXMLRPCServer
 from OpenSSL import SSL
 from Queue import Queue
+
 from sfa.trust.certificate import Keypair, Certificate
 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 sfa_logger
 
 ##
 # Verification callback for pyOpenSSL. We do our own checking of keys because
@@ -37,10 +38,6 @@ def verify_callback(conn, x509, err, depth, preverify):
        #print "  preverified"
        return 1
 
-    # we're only passing single certificates, not chains
-    if depth > 0:
-       #print "  depth > 0 in verify_callback"
-       return 0
 
     # the certificate verification done by openssl checks a number of things
     # that we aren't interested in, so we look out for those error messages
@@ -62,6 +59,10 @@ def verify_callback(conn, x509, err, depth, preverify):
        #print "  X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY"
        return 1
 
+    # allow chained certs with self-signed roots
+    if err == 19:
+        return 1
+    
     # allow certs that are untrusted
     if err == 21:
        #print "  X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE"
@@ -107,25 +108,24 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
             remote_addr = (remote_ip, remote_port) = self.connection.getpeername()
             self.api.remote_addr = remote_addr            
             response = self.api.handle(remote_addr, request, self.server.method_map)
-
-        
         except Exception, fault:
             # This should only happen if the module is buggy
             # internal error, report as HTTP server error
-            self.send_response(500)
-            self.end_headers()
-            traceback.print_exc()
-        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!
+            sfa_logger().log_exc("server.do_POST")
+            response = self.api.prepare_response(fault)
+            #self.send_response(500)
+            #self.end_headers()
+       
+        # got a valid 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!
 
 ##
 # Taken from the web (XXX find reference). Implements an HTTPS xmlrpc server
@@ -135,6 +135,7 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR
 
         It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data.
         """
+        sfa_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
@@ -149,9 +150,12 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR
            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_privatekey_file(key_file)        
         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')
         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)
         self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
                                                         self.socket_type))
@@ -164,6 +168,7 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR
     # the client.
 
     def _dispatch(self, method, params):
+        sfa_logger().debug("SecureXMLRPCServer._dispatch, method=%s"%method)
         try:
             return SimpleXMLRPCServer.SimpleXMLRPCDispatcher._dispatch(self, method, params)
         except:
@@ -244,15 +249,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()
-
+        sfa_logger().info("Starting SfaServer, interface=%s"%interface)
 
     ##
     # Register functions that will be served by the XMLRPC server. This
@@ -267,7 +273,6 @@ class SfaServer(threading.Thread):
 
     def noop(self, cred, anything):
         self.decode_authentication(cred)
-
         return anything
 
     ##