Example #1
0
def doMaintenance():
    """Performs regular tasks to maintain the server"""
    
    # Memory Debugging
    max = config_getint(None, "log_refcounts", 0)
    if max > 0:
        str = "Refcounts at %s\n" % time.ctime()
        for n, c in get_refcounts()[:max]:
            str += '%10d %s\n' % (n, c.__name__)
        log_debug(str)

    # Thread tracking
    if ccsd_xmlrpc.log_threads:
        threads = getThreadStatus()
        log_info("%d threads alive" % len(threads))
        for c, ti in threads.items():
            log_debug("thread % 2s: [%s] [%s] %s" % \
                    (c, ti["status"], ti["age_str"], ti["name"]))
    
    # Trigger the maintenance event, in a thread so that any blocking
    # operations don't halt the mainloop!
    initThread(triggerEvent, ADMIN_SESSION_ID, "maintenance")
Example #2
0
def startCCSDServer(key, cert, cacert):
    """Initialises the CCSD Server.

    This function never returns as it enters the twisted mainloop
    """

    try:           
        # Local networks
        localnets = config_get(None, "local_networks", "127.0.0.0/8")

        # Register standard HTTP XMLRPC handler for local requests
        registerHTTPResource("RPC2", ccsd_local_xmlrpc, 
                localnets=localnets.split(","))

        # Register HTTPS XMLRPC Handler
        use_ssl = config_getboolean(None, "use_ssl", True)
        if use_ssl:
            registerHTTPSResource("RPC2", ccsd_xmlrpc)

        # Setup XMLRPC Handler configuration
        ccsd_xmlrpc.log_times = config_get(None, "log_times", None)
        ccsd_xmlrpc.profile = config_getboolean(None, "profile", False)
        ccsd_xmlrpc.prof_dir = config_get(None, "profile_dir", \
                DEFAULT_PROFILE_DIR)
        ccsd_xmlrpc.log_threads = config_get(None, "log_threads", None)
        ccsd_xmlrpc.max_threads = config_getint(None, "max_threads", 
                DEFAULT_MAX_THREADS)

        # SSL Context
        class SCF:
            def __init__(self, key, cert, cacert):
                self.mKey = key
                self.mCert = cert
                self.mCACert = cacert
                
            def verify(self, conn, cert, errnum, depth, ok):
                """Checks the certificate of an incoming connection"""
                # If there is already an error bail now
                if not ok:
                    return ok
                
                # Only perform further verification on client certs
                if depth>0:
                    return ok
                
                # At this point we know the certificate is signed by a 
                # trusted CA, check the issuer OU matches the incoming cert
                # OU and the incoming cert is not a server cert
                # XXX: Should look at using something like nsCertType rather
                # than the CN field for this.
                s = cert.get_subject()
                i = cert.get_issuer()
                if s.OU != i.OU:
                    log_warn("Rejected incoming connection from invalid " 
                            "SSL cert (%s). OU did not match." % s)
                    return 0
                if s.CN == "server":
                    log_warn("Rejected incoming connection from server SSL "
                            "cert (%s)." % s)
                    return 0
                return 1
                
            def getContext(self):
                """Create an SSL context."""
                ctx = SSL.Context(SSL.SSLv2_METHOD)
                # Add the CA certificate(s)
                store = ctx.get_cert_store()
                for cert in self.mCACert:
                    store.add_cert(cert)
                # Load the private key and certificate
                ctx.use_privatekey(self.mKey)
                ctx.use_certificate(self.mCert)
                ctx.set_verify(SSL.VERIFY_PEER | 
                        SSL.VERIFY_FAIL_IF_NO_PEER_CERT, self.verify)
                ctx.set_verify_depth(len(self.mCACert))
                return ctx

        # Port and logfile
        http_port = int(config_get(None, "http_port", 
            DEFAULT_HTTP_SERVER_PORT))
        https_port = int(config_get(None, "https_port", 
            DEFAULT_HTTPS_SERVER_PORT))
        logfile = config_get(None, "request_log", DEFAULT_REQUEST_LOG)

        # Pass off control to Twisted's mainloop
        threadable.init()
        suggestThreadpoolSize(ccsd_xmlrpc.max_threads)
        reactor.listenTCP(http_port, server.Site(_http_root, logfile))
        if use_ssl:
            reactor.listenSSL(https_port, server.Site(_https_root, logfile), \
                    SCF(key, cert, cacert))
        reactor.addSystemEventTrigger("before", "shutdown", shutdownHandler)
        log_info("Server Started. Ready to serve requests...")
    except:
        log_fatal("Could not initialise the server!", sys.exc_info())

    reactor.run()