def _doCertificateLogon(self, request): """Attempt to logon using the client certificate This can only succeed if: * the client certificate CN matches a username * cert_logins is not disabled in the configuration file """ from ccsd_session import startSession, startBasicSession from crcnetd.modules.ccs_contact import getUserCache # Check incoming peer certificate cert = request.channel.transport.socket.get_peer_certificate() subj = cert.get_subject() domain = config_get('network','domain', '') username = "******" % (subj.CN , domain) allow_login = config_getboolean(None, "cert_logins", True) if not allow_login: None # CN matches a MAC address #return startBasicSession(username, SESSION_RW) # Does the CN match a username? users = getUserCache(ADMIN_SESSION_ID) if username in users.keys(): if users[username]["enabled"]: # Make sure a session exists for the user return startSession(users[username]['login_id'], SESSION_RW) # CN matches a MAC address #return startBasicSession(username, SESSION_RW) return None
def initSessions(): global sessionLock try: # Get database connection parameters _dhost = config_get("database", "host") ccsd_session.dhost = _dhost!="" and _dhost or None log_info("host = %s" % ccsd_session.dhost) _ddatabase = config_get("database", "database") ccsd_session.database = _ddatabase!="" and _ddatabase or None log_info("database = %s" % ccsd_session.database) _duser = config_get("database", "user") ccsd_session.duser = _duser!="" and _duser or None log_info("duser = %s" % ccsd_session.duser) _dpass = config_get("database", "password") ccsd_session.dpass = _dpass!="" and _dpass or None # Does the admin want us to log query times ccsd_session.log_times = config_getboolean(None, "log_db_times", False) # Create a program wide 'admin' session which is always present ccsd_session.sessions[ADMIN_SESSION_ID] = \ ccsd_session("admin", SESSION_RW, "", -1, -1, ADMIN_SESSION_ID) # Load any other saved sessions ccsd_session.sessions.update(loadSessions()) # Initialise the lock sessionLock = threading.RLock() log_info("Successfully loaded sessions") except: log_fatal("Failed to load initial program state!", sys.exc_info())
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()
def registerResource(path, res_class, **kwargs): """Registers a resource for both HTTP and HTTPS access""" registerHTTPResource(path, res_class, **kwargs) use_ssl = config_getboolean(None, "use_ssl", True) if use_ssl: registerHTTPSResource(path, res_class, **kwargs)