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")
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()