def testNonceStoreSimple(self): # Test creation and deletion of nonces. store = auth.NonceStore() nonce1 = store.NewNonce() self.assertNotEqual(nonce1, None) self.assertEqual(nonce1, store.GetNonce(nonce1)) self.assertEqual(None, store.GetNonce(nonce1)) # Check if new nonce is not equal to the previous one. nonce2 = store.NewNonce() self.assertNotEqual(nonce2, None) self.assertNotEqual(nonce1, nonce2) self.assertEqual(nonce2, store.GetNonce(nonce2)) self.assertEqual(None, store.GetNonce(nonce2))
def Start(db, port=0, is_master=False, server_cls=ThreadedHTTPServer, reqhandler_cls=DataServerHandler): """Start the data server.""" # This is the service that will handle requests to the data store. global SERVICE SERVICE = store.DataStoreService(db) # Create the command table for faster execution of remote calls. # Along with a method, each command has the required permissions. global CMDTABLE cmd = rdfvalue.DataStoreCommand.Command CMDTABLE = { cmd.DELETE_ATTRIBUTES: (SERVICE.DeleteAttributes, "w"), cmd.DELETE_SUBJECT: (SERVICE.DeleteSubject, "w"), cmd.DELETE_ATTRIBUTES_REGEX: (SERVICE.DeleteAttributesRegex, "w"), cmd.MULTI_SET: (SERVICE.MultiSet, "w"), cmd.MULTI_RESOLVE_REGEX: (SERVICE.MultiResolveRegex, "r"), cmd.RESOLVE_MULTI: (SERVICE.ResolveMulti, "r"), cmd.LOCK_SUBJECT: (SERVICE.LockSubject, "w"), cmd.EXTEND_SUBJECT: (SERVICE.ExtendSubject, "w"), cmd.UNLOCK_SUBJECT: (SERVICE.UnlockSubject, "w") } # Initialize nonce store for authentication. global NONCE_STORE NONCE_STORE = auth.NonceStore() server_port = port or config_lib.CONFIG["Dataserver.port"] if is_master: InitMasterServer(server_port) else: InitDataServer(server_port) try: server = server_cls(("", server_port), reqhandler_cls) server.serve_forever() except KeyboardInterrupt: print("Caught keyboard interrupt, stopping server at port %s" % server_port) except socket.error: print "Service already running at port %s" % server_port finally: if MASTER: MASTER.Stop() else: DATA_SERVER.Stop()
def testNonceStoreTooMany(self): with utils.Stubber(auth.NonceStore, "MAX_NONCES", 5): # Attempt to get a lot of nonces at once. store = auth.NonceStore() old_nonce = None for _ in xrange(0, auth.NonceStore.MAX_NONCES): old_nonce = store.NewNonce() self.assertNotEqual(old_nonce, None) # We cannot get any nonce now! nonce1 = store.NewNonce() self.assertEqual(nonce1, None) # If we remove one nonce, then we should be able to get a new one. self.assertEqual(old_nonce, store.GetNonce(old_nonce)) nonce1 = store.NewNonce() self.assertEqual(nonce1, store.GetNonce(nonce1))
def testNonceStoreInvalidateOldNonces(self): with utils.MultiStubber((auth.NonceStore, "NONCE_LEASE", 1), (auth.NonceStore, "MAX_NONCES", 5)): store = auth.NonceStore() now = 1000000 with test_lib.FakeTime(now): # Add a few nonces first. nonces = [] for _ in xrange(0, 5): nonces.append(store.NewNonce()) with test_lib.FakeTime(now + 2): # Two seconds have passed, therefore old nonces will disappear. nonce = store.NewNonce() self.assertEqual(nonce, store.GetNonce(nonce)) for nonce in nonces: self.assertEqual(store.GetNonce(nonce), None)
def testServerCredentials(self): user = config_lib.CONFIG["Dataserver.server_username"] pwd = config_lib.CONFIG["Dataserver.server_password"] # Use correct credentials. store = auth.NonceStore() nonce = store.NewNonce() token = auth.NonceStore.GenerateAuthToken(nonce, user, pwd) # Credentials must validate. self.assertTrue(store.ValidateAuthTokenServer(token)) self.assertEqual(store.GetNonce(nonce), None) # Use bad password. nonce = store.NewNonce() token = auth.NonceStore.GenerateAuthToken(nonce, user, "badpassword") # Credentials must fail. self.assertFalse(store.ValidateAuthTokenServer(token)) self.assertEqual(store.GetNonce(nonce), None) # Use bad nonce. token = auth.NonceStore.GenerateAuthToken("x" * auth.NONCE_SIZE, user, pwd) self.assertFalse(store.ValidateAuthTokenServer(token))
def Start(db, port=0, address_family=socket.AF_INET, is_master=False, server_cls=ThreadedHTTPServer, reqhandler_cls=DataServerHandler): """Start the data server.""" # This is the service that will handle requests to the data store. if reqhandler_cls.MASTER or reqhandler_cls.DATA_SERVER: logging.fatal("Attempt to start server with duplicate request handler.") if not reqhandler_cls.SERVICE: reqhandler_cls.SERVICE = store.DataStoreService(db) # Create the command table for faster execution of remote calls. # Along with a method, each command has the required permissions. cmd = rdf_data_server.DataStoreCommand.Command reqhandler_cls.CMDTABLE = { cmd.DELETE_ATTRIBUTES: (reqhandler_cls.SERVICE.DeleteAttributes, "w"), cmd.DELETE_SUBJECT: (reqhandler_cls.SERVICE.DeleteSubject, "w"), cmd.MULTI_SET: (reqhandler_cls.SERVICE.MultiSet, "w"), cmd.MULTI_RESOLVE_PREFIX: (reqhandler_cls.SERVICE.MultiResolvePrefix, "r"), cmd.RESOLVE_MULTI: (reqhandler_cls.SERVICE.ResolveMulti, "r"), cmd.LOCK_SUBJECT: (reqhandler_cls.SERVICE.LockSubject, "w"), cmd.EXTEND_SUBJECT: (reqhandler_cls.SERVICE.ExtendSubject, "w"), cmd.UNLOCK_SUBJECT: (reqhandler_cls.SERVICE.UnlockSubject, "w"), cmd.SCAN_ATTRIBUTES: (reqhandler_cls.SERVICE.ScanAttributes, "r") } # Initialize nonce store for authentication. if not reqhandler_cls.NONCE_STORE: reqhandler_cls.NONCE_STORE = auth.NonceStore() if port == 0 or port is None: logging.debug("No port was specified as a parameter. Expecting to find " "port in configuration file.") else: logging.debug("Port specified was '%i'. Ignoring configuration directive " "Dataserver.port.", port) server_port = port or config_lib.CONFIG["Dataserver.port"] if is_master: logging.debug("Master server running on port '%i'", server_port) reqhandler_cls.InitMasterServer(server_port) else: logging.debug("Non-master data server running on port '%i'", server_port) reqhandler_cls.InitDataServer(server_port) reqhandler_cls.InitHandlerTables() logging.info("Starting! master: " + str(is_master) + " with handler " + reqhandler_cls.__name__) try: server_cls.address_family = address_family server = server_cls(("", server_port), reqhandler_cls) server.serve_forever() except KeyboardInterrupt: print "Caught keyboard interrupt, stopping server at port %s" % server_port except socket.error: print "Service already running at port %s" % server_port finally: if reqhandler_cls.MASTER: reqhandler_cls.MASTER.Stop() else: reqhandler_cls.DATA_SERVER.Stop()
def testRegister(self): """Create master and register other servers.""" m = master.DataMaster(self.ports[0], self.mock_service) self.assertNotEqual(m, None) self.assertFalse(m.AllRegistered()) servers = [None] for (i, port) in enumerate(self.ports): if i == 0: # Skip master server. continue self.assertFalse(m.AllRegistered()) server = m.RegisterServer(self.host, port) servers.append(server) self.assertNotEqual(server, None) self.assertEqual(server.Address(), self.host) self.assertEqual(server.Port(), port) self.assertEqual(server.Index(), i) self.assertTrue(m.AllRegistered()) # Try to register something that does not exist. self.assertFalse(m.RegisterServer(self.host, 7004)) # Deregister a server. m.DeregisterServer(servers[1]) self.assertFalse(m.AllRegistered()) # Register again. m.RegisterServer(servers[1].Address(), servers[1].Port()) self.assertTrue(m.AllRegistered()) for port in self.ports: for response_sequence in [ [constants.RESPONSE_OK, constants.RESPONSE_SERVER_NOT_AUTHORIZED], [constants.RESPONSE_OK, constants.RESPONSE_SERVER_NOT_ALLOWED], [constants.RESPONSE_OK, constants.RESPONSE_NOT_MASTER_SERVER] ]: response_mocks = [] for response_status in response_sequence: response_mocks.append(MockResponse(response_status)) pool_class = GetMockHTTPConnectionPoolClass(response_mocks) with libutils.Stubber(urllib3.connectionpool, "HTTPConnectionPool", pool_class): m = data_server.StandardDataServer(port, data_server.DataServerHandler) m.handler_cls.NONCE_STORE = auth.NonceStore() self.assertRaises(errors.DataServerError, m._DoRegister) # Ensure two requests have been made. self.assertEqual(len(pool_class.requests), 2) # Ensure the register body is non-empty. self.assertTrue(pool_class.requests[1]["body"]) # Ensure that the register body is a valid rdfvalue. rdf_data_server.DataStoreRegistrationRequest.FromSerializedString( pool_class.requests[1]["body"]) # Ensure the requests are POST requests. self.assertEqual(pool_class.requests[0]["method"], "POST") self.assertEqual(pool_class.requests[1]["method"], "POST") # Ensure the correct URLs are hit according to the API. self.assertEqual(pool_class.requests[0]["url"], "/server/handshake") self.assertEqual(pool_class.requests[1]["url"], "/server/register")