def testWithHostname_MultipleClients(self): hostname = 'multclients.loc.group.example.com' client_id1 = 'C.1111111111111111' client_id2 = 'C.1111111111111112' data_store.REL_DB.WriteClientMetadata(client_id=client_id1, fleetspeak_enabled=False) data_store.REL_DB.WriteClientMetadata(client_id=client_id2, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=client_id1) client.knowledge_base.fqdn = hostname data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = rdf_objects.ClientSnapshot(client_id=client_id2) client.knowledge_base.fqdn = hostname data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) with self.assertRaises(errors.AmbiguousHostnameError) as context: grr_colab.Client.with_hostname(hostname) self.assertEqual(context.exception.hostname, hostname) self.assertItemsEqual([client_id1, client_id2], context.exception.clients)
def testSearch_MultipleKeywords(self): hostname = 'multkeywords.loc.group.example.com' client_id1 = 'C.1111111111111111' client_id2 = 'C.1111111111111112' data_store.REL_DB.WriteClientMetadata(client_id=client_id1, fleetspeak_enabled=False) data_store.REL_DB.WriteClientMetadata(client_id=client_id2, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=client_id1) client.knowledge_base.fqdn = hostname client.startup_info.client_info.labels.append('foo') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = rdf_objects.ClientSnapshot(client_id=client_id2) client.knowledge_base.fqdn = hostname client.startup_info.client_info.labels.append('bar') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) clients = grr_colab.Client.search(labels=['foo'], host=hostname) self.assertLen(clients, 1) self.assertEqual(clients[0].id, client_id1)
def SetupTestClientObject(self, client_nr, add_cert=True, arch="x86_64", install_time=None, last_boot_time=None, fqdn=None, kernel="4.0.0", memory_size=None, os_version="buster/sid", ping=None, system="Linux", labels=None): """Prepares a test client object.""" client_id = "C.1%015x" % client_nr client = rdf_objects.ClientSnapshot(client_id=client_id) client.startup_info.client_info = self._TestClientInfo() if last_boot_time is not None: client.startup_info.boot_time = last_boot_time client.knowledge_base.fqdn = fqdn or "Host-%x.example.com" % client_nr client.knowledge_base.os = system client.knowledge_base.users = [ rdf_client.User(username=u"user1"), rdf_client.User(username=u"user2"), ] client.os_version = os_version client.arch = arch client.kernel = kernel client.interfaces = self._TestInterfaces(client_nr) client.install_time = install_time client.hardware_info = rdf_client.HardwareInfo( system_manufacturer="System-Manufacturer-%x" % client_nr, bios_version="Bios-Version-%x" % client_nr) if memory_size is not None: client.memory_size = memory_size ping = ping or rdfvalue.RDFDatetime.Now() if add_cert: cert = self.ClientCertFromPrivateKey(config.CONFIG["Client.private_key"]) else: cert = None data_store.REL_DB.WriteClientMetadata( client_id, last_ping=ping, certificate=cert, fleetspeak_enabled=False) data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) if labels: data_store.REL_DB.AddClientLabels(client_id, u"GRR", labels) client_index.ClientIndex().AddClientLabels( client_id, data_store.REL_DB.ReadClientLabels(client_id)) return client
def Handle(self, args, token=None): audit_description = ",".join([ token.username + u"." + utils.SmartUnicode(name) for name in args.labels ]) audit_events = [] try: for client_id in args.client_ids: cid = unicode(client_id) data_store.REL_DB.RemoveClientLabels(cid, token.username, args.labels) labels_to_remove = set(args.labels) existing_labels = data_store.REL_DB.ReadClientLabels(cid) for label in existing_labels: labels_to_remove.discard(label.name) if labels_to_remove: idx = client_index.ClientIndex() idx.RemoveClientLabels(cid, labels_to_remove) audit_events.append( rdf_events.AuditEvent( user=token.username, action="CLIENT_REMOVE_LABEL", flow_name="handler.ApiRemoveClientsLabelsHandler", client=client_id.ToClientURN(), description=audit_description)) finally: events.Events.PublishMultipleEvents( {audit.AUDIT_EVENT: audit_events}, token=token)
def testRemovesUserLabelWhenSystemLabelWithSimilarNameAlsoExists(self): idx = client_index.ClientIndex() with aff4.FACTORY.Open(self.client_ids[0], mode="rw", token=self.token) as grr_client: grr_client.AddLabel(u"foo") grr_client.AddLabel(u"foo", owner=u"GRR") data_store.REL_DB.WriteClientMetadata( self.client_ids[0].Basename(), fleetspeak_enabled=False) data_store.REL_DB.AddClientLabels(self.client_ids[0].Basename(), self.token.username, [u"foo"]) data_store.REL_DB.AddClientLabels(self.client_ids[0].Basename(), u"GRR", [u"foo"]) idx.AddClientLabels(self.client_ids[0].Basename(), [u"foo"]) self.handler.Handle(client_plugin.ApiRemoveClientsLabelsArgs( client_ids=[self.client_ids[0]], labels=[u"foo"]), token=self.token) # AFF4 labels. labels = aff4.FACTORY.Open(self.client_ids[0], token=self.token).GetLabels() self.assertLen(labels, 1) self.assertEqual(labels[0].name, u"foo") self.assertEqual(labels[0].owner, u"GRR") # Relational labels. labels = data_store.REL_DB.ReadClientLabels( self.client_ids[0].Basename()) self.assertLen(labels, 1) self.assertEqual(labels[0].name, u"foo") self.assertEqual(labels[0].owner, u"GRR") # The label is still in the index. self.assertEqual(idx.LookupClients(["label:foo"]), [self.client_ids[0].Basename()])
def End(self, responses): """Finalize client registration.""" # Update summary and publish to the Discovery queue. del responses try: data_store.REL_DB.WriteClientSnapshot(self.state.client) except db.UnknownClientError: pass summary = self.state.client.GetSummary() summary.client_id = self.client_id summary.timestamp = rdfvalue.RDFDatetime.Now() summary.last_ping = summary.timestamp events.Events.PublishEvent("Discovery", summary, token=self.token) self.SendReply(summary) index = client_index.ClientIndex() index.AddClient(self.state.client) labels = self.state.client.startup_info.client_info.labels if labels: data_store.REL_DB.AddClientLabels(self.state.client.client_id, "GRR", labels)
def Handle(self, args, token=None): audit_description = ",".join([ token.username + u"." + utils.SmartUnicode(name) for name in args.labels ]) audit_events = [] try: for api_client_id in args.client_ids: audit_events.append( rdf_events.AuditEvent( user=token.username, action="CLIENT_ADD_LABEL", flow_name="handler.ApiAddClientsLabelsHandler", client=api_client_id.ToClientURN(), description=audit_description)) for api_client_id in args.client_ids: cid = unicode(api_client_id) try: data_store.REL_DB.AddClientLabels(cid, token.username, args.labels) idx = client_index.ClientIndex() idx.AddClientLabels(cid, args.labels) except db.UnknownClientError: # TODO(amoser): Remove after data migration. pass finally: events.Events.PublishMultipleEvents( {audit.AUDIT_EVENT: audit_events}, token=token)
def testStartupHandlerNewLabels(self): client_id = self.SetupClient(0, labels=[]) index = client_index.ClientIndex() labels = data_store.REL_DB.ReadClientLabels(client_id) self.assertEmpty(labels) snapshot = data_store.REL_DB.ReadClientSnapshot(client_id) self.assertEmpty(snapshot.startup_info.client_info.labels) search_result = index.LookupClients(["label:test_label"]) self.assertEmpty(search_result) with test_lib.ConfigOverrider({"Client.labels": ["test_label"]}): self._RunSendStartupInfo(client_id) # Just sending the startup info with an updated label should also write the # new label to the client_labels table and update the search index so the # client can now also be found using the new label. labels = data_store.REL_DB.ReadClientLabels(client_id) self.assertLen(labels, 1) self.assertEqual(labels[0].name, "test_label") search_result = index.LookupClients(["label:test_label"]) self.assertEqual(search_result, [client_id])
def WriteClientStartupInfo(self, client_id, new_si): """Handle a startup event.""" drift = rdfvalue.Duration.From(5, rdfvalue.MINUTES) current_si = data_store.REL_DB.ReadClientStartupInfo(client_id) # We write the updated record if the client_info has any changes # or the boot time is more than 5 minutes different. if (not current_si or current_si.client_info != new_si.client_info or not current_si.boot_time or current_si.boot_time - new_si.boot_time > drift): try: data_store.REL_DB.WriteClientStartupInfo(client_id, new_si) labels = new_si.client_info.labels if labels: data_store.REL_DB.AddClientLabels(client_id, "GRR", labels) index = client_index.ClientIndex() index.AddClientLabels(client_id, labels) if self._IsInterrogateNeeded(client_id, current_si, new_si): flow.StartFlow( client_id=client_id, flow_cls=discovery.Interrogate, creator="GRRWorker") except db.UnknownClientError: # On first contact with a new client, this write will fail. logging.info("Can't write StartupInfo for unknown client %s", client_id)
def Handle(self, args, token=None): end = args.count or sys.maxsize keywords = shlex.split(args.query) api_clients = [] if data_store.RelationalDBReadEnabled(): index = client_index.ClientIndex() clients = sorted( index.LookupClients(keywords))[args.offset:args.offset + end] client_infos = data_store.REL_DB.MultiReadClientFullInfo(clients) for client_info in itervalues(client_infos): api_clients.append(ApiClient().InitFromClientInfo(client_info)) else: index = client_index.CreateClientIndex(token=token) result_urns = sorted( index.LookupClients(keywords))[args.offset:args.offset + end] result_set = aff4.FACTORY.MultiOpen(result_urns, token=token) for child in sorted(result_set): api_clients.append(ApiClient().InitFromAff4Object(child)) UpdateClientsFromFleetspeak(api_clients) return ApiSearchClientsResult(items=api_clients)
def End(self): """Finalize client registration.""" # Update summary and publish to the Discovery queue. if data_store.RelationalDBWriteEnabled(): try: data_store.REL_DB.WriteClientSnapshot(self.state.client) except db.UnknownClientError: pass client = self._OpenClient() if data_store.RelationalDBReadEnabled(): summary = self.state.client.GetSummary() summary.client_id = self.client_id summary.timestamp = rdfvalue.RDFDatetime.Now() else: summary = client.GetSummary() self.Publish("Discovery", summary) self.SendReply(summary) # Update the client index client_index.CreateClientIndex(token=self.token).AddClient(client) if data_store.RelationalDBWriteEnabled(): try: index = client_index.ClientIndex() index.AddClient(self.state.client) labels = self.state.client.startup_info.client_info.labels if labels: data_store.REL_DB.AddClientLabels( self.state.client.client_id, u"GRR", labels) except db.UnknownClientError: # TODO(amoser): Remove after data migration. pass
def EnrolFleetspeakClient(self, client_id): """Enrols a Fleetspeak-enabled client for use with GRR. Args: client_id: GRR client-id for the client. Returns: True if the client is new, and actually got enrolled. This method is a no-op if the client already exists (in which case False is returned). """ client_urn = rdf_client.ClientURN(client_id) # If already enrolled, return. if data_store.RelationalDBEnabled(): try: data_store.REL_DB.ReadClientMetadata(client_id) return False except db.UnknownClientError: pass else: if aff4.FACTORY.ExistsWithType(client_urn, aff4_type=aff4_grr.VFSGRRClient, token=self.token): return False logging.info("Enrolling a new Fleetspeak client: %r", client_id) if data_store.RelationalDBEnabled(): now = rdfvalue.RDFDatetime.Now() data_store.REL_DB.WriteClientMetadata(client_id, first_seen=now, fleetspeak_enabled=True, last_ping=now) if data_store.AFF4Enabled(): # TODO(fleetspeak-team,grr-team): If aff4 isn't reliable enough, we can # catch exceptions from it and forward them to Fleetspeak by failing its # gRPC call. Fleetspeak will then retry with a random, perhaps healthier, # instance of the GRR frontend. with aff4.FACTORY.Create(client_urn, aff4_type=aff4_grr.VFSGRRClient, mode="rw", token=self.token) as client: client.Set(client.Schema.FLEETSPEAK_ENABLED, rdfvalue.RDFBool(True)) index = client_index.CreateClientIndex(token=self.token) index.AddClient(client) if data_store.RelationalDBEnabled(): client_obj = rdf_objects.ClientSnapshot( client_id=client_urn.Basename()) index = client_index.ClientIndex() index.AddClient(client_obj) # Publish the client enrollment message. events.Events.PublishEvent("ClientEnrollment", client_urn, token=self.token) return True
def testDoesNotRemoveSystemLabelFromSingleClient(self): idx = client_index.ClientIndex() with aff4.FACTORY.Open( self.client_ids[0], mode="rw", token=self.token) as grr_client: grr_client.AddLabel("foo", owner="GRR") data_store.REL_DB.WriteClientMetadata( self.client_ids[0].Basename(), fleetspeak_enabled=False) data_store.REL_DB.AddClientLabels(self.client_ids[0].Basename(), "GRR", ["foo"]) idx.AddClientLabels(self.client_ids[0].Basename(), ["foo"]) self.handler.Handle( client_plugin.ApiRemoveClientsLabelsArgs( client_ids=[self.client_ids[0]], labels=["foo"]), token=self.token) # AFF4 labels. labels = aff4.FACTORY.Open(self.client_ids[0], token=self.token).GetLabels() self.assertEqual(len(labels), 1) # Relational labels. labels = data_store.REL_DB.ReadClientLabels(self.client_ids[0].Basename()) self.assertEqual(len(labels), 1) # The label is still in the index. self.assertEqual( idx.LookupClients(["label:foo"]), [self.client_ids[0].Basename()])
def ProcessKnowledgeBase(self, responses): """Collect and store any extra non-kb artifacts.""" if not responses.success: raise flow_base.FlowError( "Error while collecting the knowledge base: %s" % responses.status) kb = responses.First() # Information already present in the knowledge base takes precedence. if not kb.os: kb.os = self.state.os if not kb.fqdn: kb.fqdn = self.state.fqdn self.state.client.knowledge_base = kb non_kb_artifacts = config.CONFIG[ "Artifacts.non_kb_interrogate_artifacts"] if non_kb_artifacts: self.CallFlow(collectors.ArtifactCollectorFlow.__name__, artifact_list=non_kb_artifacts, knowledge_base=kb, next_state=compatibility.GetName( self.ProcessArtifactResponses)) try: # Update the client index for the rdf_objects.ClientSnapshot. client_index.ClientIndex().AddClient(self.state.client) except db.UnknownClientError: pass
def Handle(self, args, context=None): for api_client_id in args.client_ids: cid = str(api_client_id) data_store.REL_DB.AddClientLabels(cid, context.username, args.labels) idx = client_index.ClientIndex() idx.AddClientLabels(cid, args.labels)
def ProcessKnowledgeBase(self, responses): """Collect and store any extra non-kb artifacts.""" if not responses.success: raise flow.FlowError( "Error while collecting the knowledge base: %s" % responses.status) kb = responses.First() if data_store.AFF4Enabled(): # AFF4 client. client = self._OpenClient(mode="rw") with client: client.Set(client.Schema.KNOWLEDGE_BASE, kb) # Copy usernames. usernames = [ user.username for user in kb.users if user.username ] client.AddAttribute( client.Schema.USERNAMES(" ".join(usernames))) self.CopyOSReleaseFromKnowledgeBase(kb, client) # rdf_objects.ClientSnapshot. # Information already present in the knowledge base takes precedence. if not kb.os: kb.os = self.state.os if not kb.fqdn: kb.fqdn = self.state.fqdn self.state.client.knowledge_base = kb if data_store.RelationalDBReadEnabled(): existing_client = data_store.REL_DB.ReadClientSnapshot( self.client_id) if existing_client is None: # This is the first time we interrogate this client. In that case, we # need to store basic information about this client right away so follow # up flows work properly. data_store.REL_DB.WriteClientSnapshot(self.state.client) self.CallFlow(collectors.ArtifactCollectorFlow.__name__, artifact_list=config. CONFIG["Artifacts.non_kb_interrogate_artifacts"], knowledge_base=kb, next_state="ProcessArtifactResponses") if data_store.AFF4Enabled(): # Update the client index for the AFF4 client. client_index.CreateClientIndex(token=self.token).AddClient(client) if data_store.RelationalDBWriteEnabled(): try: # Update the client index for the rdf_objects.ClientSnapshot. client_index.ClientIndex().AddClient(self.state.client) except db.UnknownClientError: pass
def Start(self): """Sign the CSR from the client.""" if self.args.csr.type != rdf_crypto.Certificate.Type.CSR: raise ValueError("Must be called with CSR") csr = rdf_crypto.CertificateSigningRequest(self.args.csr.pem) # Verify the CSR. This is not strictly necessary but doesn't harm either. try: csr.Verify(csr.GetPublicKey()) except rdf_crypto.VerificationError: raise flow.FlowError("CSR for client %s did not verify: %s" % (self.client_id, csr.AsPEM())) # Verify that the CN is of the correct form. The common name should refer # to a client URN. self.cn = rdf_client.ClientURN.FromPublicKey(csr.GetPublicKey()) if self.cn != csr.GetCN(): raise ValueError("CSR CN %s does not match public key %s." % (csr.GetCN(), self.cn)) logging.info("Will sign CSR for: %s", self.cn) cert = rdf_crypto.RDFX509Cert.ClientCertFromCSR(csr) # This check is important to ensure that the client id reported in the # source of the enrollment request is the same as the one in the # certificate. We use the ClientURN to ensure this is also of the correct # form for a client name. if self.cn != self.client_id: raise flow.FlowError("Certificate name %s mismatch for client %s" % (self.cn, self.client_id)) now = rdfvalue.RDFDatetime.Now() if data_store.AFF4Enabled(): with aff4.FACTORY.Create(self.client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token) as client: # Set and write the certificate to the client record. client.Set(client.Schema.CERT, cert) client.Set(client.Schema.FIRST_SEEN, now) index = client_index.CreateClientIndex(token=self.token) index.AddClient(client) if data_store.RelationalDBWriteEnabled(): data_store.REL_DB.WriteClientMetadata(self.client_id, certificate=cert, fleetspeak_enabled=False) index = client_index.ClientIndex() index.AddClient( rdf_objects.ClientSnapshot(client_id=self.client_id)) # Publish the client enrollment message. events.Events.PublishEvent("ClientEnrollment", self.client_urn, token=self.token) self.Log("Enrolled %s successfully", self.client_id)
def Platform(self, responses): """Stores information about the platform.""" if responses.success: response = responses.First() client = self.state.client client.os_release = response.release client.os_version = response.version client.kernel = response.kernel client.arch = response.machine client.knowledge_base.os = response.system # Store these for later, there might be more accurate data # coming in from the artifact collector. self.state.fqdn = response.fqdn self.state.os = response.system existing_client = data_store.REL_DB.ReadClientSnapshot( self.client_id) if existing_client is None: # This is the first time we interrogate this client. In that case, we # need to store basic information about this client right away so # follow up flows work properly. data_store.REL_DB.WriteClientSnapshot(self.state.client) try: # Update the client index client_index.ClientIndex().AddClient(client) except db.UnknownClientError: pass # No support for OS X cloud machines as yet. if response.system in ["Linux", "Windows"]: self.CallClient(server_stubs.GetCloudVMMetadata, rdf_cloud.BuildCloudMetadataRequests(), next_state=compatibility.GetName( self.CloudMetadata)) known_system_type = True else: # We failed to get the Platform info, maybe there is a stored # system we can use to get at least some data. client = data_store.REL_DB.ReadClientSnapshot(self.client_id) known_system_type = client and client.knowledge_base.os self.Log("Could not retrieve Platform info.") if known_system_type: # We will accept a partial KBInit rather than raise, so pass # require_complete=False. self.CallFlow(artifact.KnowledgeBaseInitializationFlow.__name__, require_complete=False, lightweight=self.args.lightweight, next_state=compatibility.GetName( self.ProcessKnowledgeBase)) else: self.Log( "Unknown system type, skipping KnowledgeBaseInitializationFlow" )
def _CheckClientKwIndex(self, keywords, expected_count): # Tests that the client index has expected_count results when # searched for keywords. # AFF4 index. index = client_index.CreateClientIndex(token=self.token) self.assertEqual(len(index.LookupClients(keywords)), expected_count) # Relational index. index = client_index.ClientIndex() self.assertEqual(len(index.LookupClients(keywords)), expected_count)
def Handle(self, args, token=None): for client_id in args.client_ids: cid = unicode(client_id) data_store.REL_DB.RemoveClientLabels(cid, token.username, args.labels) labels_to_remove = set(args.labels) existing_labels = data_store.REL_DB.ReadClientLabels(cid) for label in existing_labels: labels_to_remove.discard(label.name) if labels_to_remove: idx = client_index.ClientIndex() idx.RemoveClientLabels(cid, labels_to_remove)
def testSearch_NoResults(self): client_id1 = 'C.1111111111111111' client_id2 = 'C.1111111111111112' data_store.REL_DB.WriteClientMetadata(client_id=client_id1, fleetspeak_enabled=False) data_store.REL_DB.WriteClientMetadata(client_id=client_id2, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=client_id1) client.startup_info.client_info.labels.append('foo') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = rdf_objects.ClientSnapshot(client_id=client_id2) client.startup_info.client_info.labels.append('bar') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) clients = grr_colab.Client.search(labels=['quux']) self.assertEmpty(clients)
def _CheckLabelIndex(self): """Check that label indexes are updated.""" index = client_index.CreateClientIndex(token=self.token) # AFF4 index. self.assertItemsEqual( list(index.LookupClients(["label:Label2"])), [self.client_id]) # Relational index. self.assertItemsEqual( client_index.ClientIndex().LookupClients(["label:Label2"]), [self.client_id.Basename()])
def testWithHostname_SingleClient(self): hostname = 'user.loc.group.example.com' data_store.REL_DB.WriteClientMetadata( client_id=ClientTest.FAKE_CLIENT_ID, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=ClientTest.FAKE_CLIENT_ID) client.knowledge_base.fqdn = hostname data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = grr_colab.Client.with_hostname(hostname) self.assertEqual(client.id, ClientTest.FAKE_CLIENT_ID) self.assertEqual(client.hostname, hostname)
def testSearch_SingleKeyword(self): client_id1 = 'C.1111111111111111' client_id2 = 'C.1111111111111112' data_store.REL_DB.WriteClientMetadata(client_id=client_id1, fleetspeak_enabled=False) data_store.REL_DB.WriteClientMetadata(client_id=client_id2, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=client_id1) client.startup_info.client_info.labels.append('foo') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = rdf_objects.ClientSnapshot(client_id=client_id2) client.startup_info.client_info.labels.append('bar') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) clients = grr_colab.Client.search(labels=['foo']) self.assertLen(clients, 1) self.assertEqual(clients[0].id, client_id1)
def testSearch_MultipleResults(self): client_id1 = 'C.1111111111111111' client_id2 = 'C.1111111111111112' data_store.REL_DB.WriteClientMetadata( client_id=client_id1, fleetspeak_enabled=False) data_store.REL_DB.WriteClientMetadata( client_id=client_id2, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=client_id1) client.startup_info.client_info.labels.append('foo') client.startup_info.client_info.labels.append('bar') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) client = rdf_objects.ClientSnapshot(client_id=client_id2) client.startup_info.client_info.labels.append('bar') data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) clients = grr_colab.Client.search(labels=['bar']) self.assertLen(clients, 2) self.assertCountEqual([_.id for _ in clients], [client_id1, client_id2])
def AddClientLabel(self, client_id, owner, name): if data_store.RelationalDBReadEnabled(): if hasattr(client_id, "Basename"): client_id = client_id.Basename() data_store.REL_DB.AddClientLabels(client_id, owner, [name]) client_index.ClientIndex().AddClientLabels(client_id, [name]) else: with aff4.FACTORY.Open(client_id, mode="rw", token=self.token) as client_obj: client_obj.AddLabel(name, owner=owner) with client_index.CreateClientIndex(token=self.token) as index: index.AddClient(client_obj)
def ClientFixture(client_id, token=None, age=None): """Creates a client fixture with a predefined VFS tree.""" if hasattr(client_id, "Basename"): client_id = client_id.Basename() LegacyClientFixture(client_id, age=age, token=token) if not data_store.RelationalDBReadEnabled(): return data_migration.Migrate(thread_count=1) db_client_snapshot = data_store.REL_DB.ReadClientSnapshot(client_id) client_index.ClientIndex().AddClient(db_client_snapshot)
def testDoesNotRemoveSystemLabelFromSingleClient(self): data_store.REL_DB.WriteClientMetadata( self.client_ids[0], fleetspeak_enabled=False) data_store.REL_DB.AddClientLabels(self.client_ids[0], u"GRR", [u"foo"]) idx = client_index.ClientIndex() idx.AddClientLabels(self.client_ids[0], [u"foo"]) self.handler.Handle( client_plugin.ApiRemoveClientsLabelsArgs( client_ids=[self.client_ids[0]], labels=[u"foo"]), context=self.context) labels = data_store.REL_DB.ReadClientLabels(self.client_ids[0]) self.assertLen(labels, 1) # The label is still in the index. self.assertEqual(idx.LookupClients(["label:foo"]), [self.client_ids[0]])
def ProcessKnowledgeBase(self, responses): """Collect and store any extra non-kb artifacts.""" if not responses.success: raise flow.FlowError( "Error while collecting the knowledge base: %s" % responses.status) kb = responses.First() if data_store.AFF4Enabled(): # AFF4 client. client = self._OpenClient(mode="rw") client.Set(client.Schema.KNOWLEDGE_BASE, kb) # Copy usernames. usernames = [user.username for user in kb.users if user.username] client.AddAttribute(client.Schema.USERNAMES(" ".join(usernames))) self.CopyOSReleaseFromKnowledgeBase(kb, client) client.Flush() # rdf_objects.ClientSnapshot. # Information already present in the knowledge base takes precedence. if not kb.os: kb.os = self.state.os if not kb.fqdn: kb.fqdn = self.state.fqdn self.state.client.knowledge_base = kb self.CallFlow(collectors.ArtifactCollectorFlow.__name__, artifact_list=config. CONFIG["Artifacts.non_kb_interrogate_artifacts"], next_state="ProcessArtifactResponses") if data_store.AFF4Enabled(): # Update the client index for the AFF4 client. client_index.CreateClientIndex(token=self.token).AddClient(client) if data_store.RelationalDBWriteEnabled(): try: # Update the client index for the rdf_objects.ClientSnapshot. client_index.ClientIndex().AddClient(self.state.client) except db.UnknownClientError: pass
def testAddLookupClients(self): index = client_index.ClientIndex() clients = self._SetupClients(2) for client_id, client in iteritems(clients): data_store.REL_DB.WriteClientMetadata(client_id, fleetspeak_enabled=False) index.AddClient(client) # Check unique identifiers. self.assertEqual(index.LookupClients(["192.168.0.1"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["2001:aBcd::1"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["ip:192.168.0.1"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["ip:2001:abcd::1"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["host-2"]), ["C.1000000000000002"]) self.assertEqual(index.LookupClients(["C.1000000000000002"]), ["C.1000000000000002"]) self.assertEqual(index.LookupClients(["aabbccddee01"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["mac:aabbccddee01"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["aa:bb:cc:dd:ee:01"]), ["C.1000000000000001"]) self.assertEqual(index.LookupClients(["mac:aa:bb:cc:dd:ee:01"]), ["C.1000000000000001"]) # IP prefixes of octets should work: self.assertCountEqual(index.LookupClients(["192.168.0"]), list(clients)) # Hostname prefixes of tokens should work. self.assertEqual(index.LookupClients(["host-2.example"]), ["C.1000000000000002"]) # Intersections should work. self.assertEqual(index.LookupClients(["192.168.0", "Host-2"]), ["C.1000000000000002"]) # Universal keyword should find everything. self.assertCountEqual(index.LookupClients(["."]), list(clients))