def Start(self): """Start off all the tests.""" self.state.client = rdf_objects.ClientSnapshot( client_id=self.client_id) self.state.fqdn = None self.state.os = None # ClientInfo should be collected early on since we might need the client # version later on to know what actions a client supports. self.CallClient(server_stubs.GetClientInfo, next_state=compatibility.GetName(self.ClientInfo)) self.CallClient(server_stubs.GetPlatformInfo, next_state=compatibility.GetName(self.Platform)) self.CallClient(server_stubs.GetMemorySize, next_state=compatibility.GetName(self.StoreMemorySize)) self.CallClient(server_stubs.GetInstallDate, next_state=compatibility.GetName(self.InstallDate)) self.CallClient(server_stubs.GetConfiguration, next_state=compatibility.GetName( self.ClientConfiguration)) self.CallClient(server_stubs.GetLibraryVersions, next_state=compatibility.GetName(self.ClientLibraries)) self.CallClient(server_stubs.EnumerateInterfaces, next_state=compatibility.GetName( self.EnumerateInterfaces)) self.CallClient(server_stubs.EnumerateFilesystems, next_state=compatibility.GetName( self.EnumerateFilesystems))
def Start(self): """Start off all the tests.""" self.state.client = rdf_objects.ClientSnapshot( client_id=self.client_id) self.state.fqdn = None self.state.os = None if data_store.AFF4Enabled(): # Make sure we always have a VFSDirectory with a pathspec at fs/os pathspec = rdf_paths.PathSpec( path="/", pathtype=rdf_paths.PathSpec.PathType.OS) urn = pathspec.AFF4Path(self.client_urn) with aff4.FACTORY.Create(urn, standard.VFSDirectory, mode="w", token=self.token) as fd: fd.Set(fd.Schema.PATHSPEC, pathspec) # ClientInfo should be collected early on since we might need the client # version later on to know what actions a client supports. self.CallClient(server_stubs.GetClientInfo, next_state="ClientInfo") self.CallClient(server_stubs.GetPlatformInfo, next_state="Platform") self.CallClient(server_stubs.GetMemorySize, next_state="StoreMemorySize") self.CallClient(server_stubs.GetInstallDate, next_state="InstallDate") self.CallClient(server_stubs.GetConfiguration, next_state="ClientConfiguration") self.CallClient(server_stubs.GetLibraryVersions, next_state="ClientLibraries") self.CallClient(server_stubs.EnumerateInterfaces, next_state="EnumerateInterfaces") self.CallClient(server_stubs.EnumerateFilesystems, next_state="EnumerateFilesystems")
def ConvertVFSGRRClient(client): """Converts from `VFSGRRClient` to `rdfvalues.objects.ClientSnapshot`.""" snapshot = rdf_objects.ClientSnapshot(client_id=client.urn.Basename()) snapshot.filesystems = client.Get(client.Schema.FILESYSTEM) snapshot.hostname = client.Get(client.Schema.HOSTNAME) snapshot.fqdn = client.Get(client.Schema.FQDN) snapshot.os_release = client.Get(client.Schema.OS_RELEASE) snapshot.os_version = utils.SmartStr(client.Get(client.Schema.OS_VERSION)) snapshot.arch = client.Get(client.Schema.ARCH) snapshot.install_time = client.Get(client.Schema.INSTALL_DATE) snapshot.knowledge_base = client.Get(client.Schema.KNOWLEDGE_BASE) snapshot.startup_info.boot_time = client.Get(client.Schema.LAST_BOOT_TIME) snapshot.startup_info.client_info = client.Get(client.Schema.CLIENT_INFO) conf = client.Get(client.Schema.GRR_CONFIGURATION) or [] for key in conf or []: snapshot.grr_configuration.Append(key=key, value=utils.SmartStr(conf[key])) lib = client.Get(client.Schema.LIBRARY_VERSIONS) or [] for key in lib or []: snapshot.library_versions.Append(key=key, value=utils.SmartStr(lib[key])) snapshot.kernel = client.Get(client.Schema.KERNEL) snapshot.volumes = client.Get(client.Schema.VOLUMES) snapshot.interfaces = client.Get(client.Schema.INTERFACES) snapshot.hardware_info = client.Get(client.Schema.HARDWARE_INFO) snapshot.memory_size = client.Get(client.Schema.MEMORY_SIZE) snapshot.cloud_instance = client.Get(client.Schema.CLOUD_INSTANCE) return snapshot
def testClientStartupInfo(self): """StartupInfo is written to a separate table, make sure the merge works.""" d = self.db client_id = self.InitializeClient() client = rdf_objects.ClientSnapshot(client_id=client_id, kernel="12.3") client.startup_info = rdf_client.StartupInfo(boot_time=123) client.knowledge_base.fqdn = "test1234.examples.com" d.WriteClientSnapshot(client) client = d.ReadClientSnapshot(client_id) self.assertEqual(client.startup_info.boot_time, 123) client.kernel = "12.4" client.startup_info = rdf_client.StartupInfo(boot_time=124) d.WriteClientSnapshot(client) client.kernel = "12.5" client.startup_info = rdf_client.StartupInfo(boot_time=125) d.WriteClientSnapshot(client) hist = d.ReadClientSnapshotHistory(client_id) self.assertLen(hist, 3) startup_infos = [cl.startup_info for cl in hist] self.assertEqual([si.boot_time for si in startup_infos], [125, 124, 123]) # StartupInfos written using WriteClient show up in the StartupInfoHistory. history = d.ReadClientStartupInfoHistory(client_id) self.assertLen(history, 3) self.assertEqual(startup_infos, history)
def testGetGRRVersionString_NoVersion(self): snapshot = rdf_objects.ClientSnapshot() snapshot.startup_info.client_info.client_description = "GRR windows amd64" snapshot.startup_info.client_info.client_name = "Foo" self.assertEqual( snapshot.GetGRRVersionString(), "GRR windows amd64 %s" % rdf_objects._UNKNOWN_GRR_VERSION)
def testGetGRRVersionString(self): snapshot = rdf_objects.ClientSnapshot() snapshot.startup_info.client_info.client_description = "GRR windows amd64" snapshot.startup_info.client_info.client_name = "Foo" snapshot.startup_info.client_info.client_version = 1234 self.assertEqual(snapshot.GetGRRVersionString(), "GRR windows amd64 1234")
def Start(self): """Start off all the tests.""" # Create the objects we need to exist. self.Load() client_id = self.client_id.Basename() self.state.client = rdf_objects.ClientSnapshot(client_id=client_id) self.state.fqdn = None self.state.os = None # Make sure we always have a VFSDirectory with a pathspec at fs/os pathspec = rdf_paths.PathSpec(path="/", pathtype=rdf_paths.PathSpec.PathType.OS) urn = pathspec.AFF4Path(self.client_id) with aff4.FACTORY.Create(urn, standard.VFSDirectory, mode="w", token=self.token) as fd: fd.Set(fd.Schema.PATHSPEC, pathspec) self.CallClient(server_stubs.GetPlatformInfo, next_state="Platform") self.CallClient(server_stubs.GetMemorySize, next_state="StoreMemorySize") self.CallClient(server_stubs.GetInstallDate, next_state="InstallDate") self.CallClient(server_stubs.GetClientInfo, next_state="ClientInfo") self.CallClient(server_stubs.GetConfiguration, next_state="ClientConfiguration") self.CallClient(server_stubs.GetLibraryVersions, next_state="ClientLibraries") self.CallClient(server_stubs.EnumerateInterfaces, next_state="EnumerateInterfaces") self.CallClient(server_stubs.EnumerateFilesystems, next_state="EnumerateFilesystems")
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 _ResponseToClientsFullInfo(self, response): """Creates a ClientFullInfo object from a database response.""" c_full_info = None prev_cid = None for row in response: (cid, fs, crt, ping, clk, ip, foreman, first, last_client_ts, last_crash_ts, last_startup_ts, client_obj, client_startup_obj, last_startup_obj, label_owner, label_name) = row if cid != prev_cid: if c_full_info: yield db_utils.IntToClientID(prev_cid), c_full_info metadata = rdf_objects.ClientMetadata( certificate=crt, fleetspeak_enabled=fs, first_seen=mysql_utils.TimestampToRDFDatetime(first), ping=mysql_utils.TimestampToRDFDatetime(ping), clock=mysql_utils.TimestampToRDFDatetime(clk), ip=mysql_utils.StringToRDFProto(rdf_client_network.NetworkAddress, ip), last_foreman_time=mysql_utils.TimestampToRDFDatetime(foreman), startup_info_timestamp=mysql_utils.TimestampToRDFDatetime( last_startup_ts), last_crash_timestamp=mysql_utils.TimestampToRDFDatetime( last_crash_ts)) if client_obj is not None: l_snapshot = rdf_objects.ClientSnapshot.FromSerializedBytes( client_obj) l_snapshot.timestamp = mysql_utils.TimestampToRDFDatetime( last_client_ts) l_snapshot.startup_info = rdf_client.StartupInfo.FromSerializedBytes( client_startup_obj) l_snapshot.startup_info.timestamp = l_snapshot.timestamp else: l_snapshot = rdf_objects.ClientSnapshot( client_id=db_utils.IntToClientID(cid)) if last_startup_obj is not None: startup_info = rdf_client.StartupInfo.FromSerializedBytes( last_startup_obj) startup_info.timestamp = mysql_utils.TimestampToRDFDatetime( last_startup_ts) else: startup_info = None prev_cid = cid c_full_info = rdf_objects.ClientFullInfo( metadata=metadata, labels=[], last_snapshot=l_snapshot, last_startup_info=startup_info) if label_owner and label_name: c_full_info.labels.append( rdf_objects.ClientLabel(name=label_name, owner=label_owner)) if c_full_info: yield db_utils.IntToClientID(prev_cid), c_full_info
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 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 testClientWriteToUnknownClient(self): d = self.db client_id = "C.fc413187fefa1dcf" with self.assertRaises(db.UnknownClientError) as context: d.WriteClientSnapshot( rdf_objects.ClientSnapshot(client_id=client_id)) self.assertEqual(context.exception.client_id, client_id)
def testWriteClientSnapshotHistoryUpdatesLastTimestampIfNewer(self): client_id = self.InitializeClient() client_old = rdf_objects.ClientSnapshot(client_id=client_id) client_old.kernel = "1.0.0" self.db.WriteClientSnapshot(client_old) old_timestamp = self.db.ReadClientSnapshot(client_id).timestamp client_new = rdf_objects.ClientSnapshot(client_id=client_id) client_new.kernel = "2.0.0" client_new.timestamp = rdfvalue.RDFDatetime.Now() self.db.WriteClientSnapshotHistory([client_new]) info = self.db.ReadClientFullInfo(client_id) self.assertEqual(info.last_snapshot.kernel, "2.0.0") self.assertGreater(info.last_snapshot.timestamp, old_timestamp) self.assertGreater(info.last_startup_info.timestamp, old_timestamp)
def testWriteClientSnapshotHistoryDoesNotUpdateLastTimestampIfOlder(self): client_id = self.InitializeClient() client_new = rdf_objects.ClientSnapshot(client_id=client_id) client_new.kernel = "2.0.0" self.db.WriteClientSnapshot(client_new) new_timestamp = self.db.ReadClientSnapshot(client_id).timestamp client_old = rdf_objects.ClientSnapshot(client_id=client_id) client_old.kernel = "1.0.0" client_old.timestamp = new_timestamp - rdfvalue.Duration("1d") self.db.WriteClientSnapshotHistory([client_old]) info = self.db.ReadClientFullInfo(client_id) self.assertEqual(info.last_snapshot.kernel, "2.0.0") self.assertEqual(info.last_snapshot.timestamp, new_timestamp) self.assertEqual(info.last_startup_info.timestamp, new_timestamp)
def testWriteClientSnapshotHistoryRaiseAttributeError(self): client_id = self.InitializeClient() client = rdf_objects.ClientSnapshot(client_id=client_id) client.kernel = "1.2.3" client.startup_info.client_info.client_version = 42 with self.assertRaisesRegexp(AttributeError, "timestamp"): self.db.WriteClientSnapshotHistory([client])
def testClientSummary(self): d = self.db client_id_1 = self.InitializeClient() client_id_2 = self.InitializeClient() client_id_3 = self.InitializeClient() d.WriteClientSnapshot( rdf_objects.ClientSnapshot( client_id=client_id_1, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1234.examples.com"), kernel="12.3")) d.WriteClientSnapshot( rdf_objects.ClientSnapshot( client_id=client_id_1, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1234.examples.com"), kernel="12.4")) d.WriteClientSnapshot( rdf_objects.ClientSnapshot( client_id=client_id_2, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1235.examples.com"), kernel="12.4")) hist = d.ReadClientSnapshotHistory(client_id_1) self.assertEqual(len(hist), 2) # client_3 should be excluded - no snapshot yet res = d.MultiReadClientSnapshot([client_id_1, client_id_2, client_id_3]) self.assertEqual(len(res), 3) self.assertIsInstance(res[client_id_1], rdf_objects.ClientSnapshot) self.assertIsInstance(res[client_id_2], rdf_objects.ClientSnapshot) self.assertIsInstance(res[client_id_1].timestamp, rdfvalue.RDFDatetime) self.assertIsNotNone(res[client_id_2].timestamp) self.assertEqual(res[client_id_1].knowledge_base.fqdn, "test1234.examples.com") self.assertEqual(res[client_id_1].kernel, "12.4") self.assertEqual(res[client_id_2].knowledge_base.fqdn, "test1235.examples.com") self.assertFalse(res[client_id_3])
def testWriteClientSnapshotHistoryRaiseOnNonExistingClient(self): client_id = "C.0000000000000000" client = rdf_objects.ClientSnapshot(client_id=client_id) client.kernel = "1.2.3" client.timestamp = rdfvalue.RDFDatetime.FromHumanReadable("2001-01-01") with self.assertRaises(db.UnknownClientError) as context: self.db.WriteClientSnapshotHistory([client]) self.assertEqual(context.exception.client_id, client_id)
def testHostname(self): hostname = 'hostname.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 = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) self.assertEqual(client.hostname, hostname)
def testArch(self): arch = 'x42' 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.arch = arch data_store.REL_DB.WriteClientSnapshot(client) client = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) self.assertEqual(client.arch, arch)
def testKernel(self): kernel = '0.0.0' 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.kernel = kernel data_store.REL_DB.WriteClientSnapshot(client) client = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) self.assertEqual(client.kernel, kernel)
def MakeClient(): client = rdf_objects.ClientSnapshot(client_id="C.0000000000000000") base_pb = objects_pb2.ClientSnapshot() # pylint: disable=line-too-long text_format.Merge( r""" os_release: "Ubuntu" os_version: "14.4" interfaces: { addresses: { address_type: INET packed_bytes: "\177\000\000\001" } addresses: { address_type: INET6 packed_bytes: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001" } } interfaces: { mac_address: "\001\002\003\004\001\002\003\004\001\002\003\004" addresses: { address_type: INET packed_bytes: "\010\010\010\010" } addresses: { address_type: INET6 packed_bytes: "\376\200\001\002\003\000\000\000\000\000\000\000\000\000\000\000" } } knowledge_base: { users: { username: "******" full_name: "Good Guy Joe" } users: { username: "******" full_name: "Ok Guy Fred" } fqdn: "test123.examples.com" os: "Linux" } cloud_instance: { cloud_type: GOOGLE google: { unique_id: "us-central1-a/myproject/1771384456894610289" } } """, base_pb) # pylint: enable=line-too-long client.ParseFromBytes(base_pb.SerializeToString()) return client
def testIfaces(self): ifname = 'test_ifname' 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.interfaces = [rdf_client_network.Interface(ifname=ifname)] data_store.REL_DB.WriteClientSnapshot(client) client = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) self.assertLen(client.ifaces, 1) self.assertEqual(client.ifaces[0].ifname, ifname)
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 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 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 testFailuresAreLogged(self): client_id = "C.4815162342abcdef" now = rdfvalue.RDFDatetime.Now() data_store.REL_DB.WriteClientMetadata(client_id=client_id, last_ping=now) snapshot = rdf_objects.ClientSnapshot(client_id=client_id) snapshot.knowledge_base.os = "fakeos" data_store.REL_DB.WriteClientSnapshot(snapshot) raising_artifact_source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.COMMAND, attributes={ "cmd": "/bin/echo", "args": ["1"], }) raising_artifact = rdf_artifacts.Artifact( name="RaisingArtifact", doc="Lorem ipsum.", sources=[raising_artifact_source]) registry = artifact_registry.ArtifactRegistry() with mock.patch.object(artifact_registry, "REGISTRY", registry): registry.RegisterArtifact(raising_artifact) flow_id = flow_test_lib.TestFlowHelper( collectors.ArtifactCollectorFlow.__name__, client_mock=action_mocks.ActionMock(standard.ExecuteCommand), client_id=client_id, artifact_list=["RaisingArtifact"], apply_parsers=True, check_flow_errors=True, token=self.token) results = flow_test_lib.GetFlowResults(client_id=client_id, flow_id=flow_id) self.assertLen(results, 1) self.assertEqual(results[0].stdout, "1\n".encode("utf-8")) logs = data_store.REL_DB.ReadFlowLogEntries(client_id=client_id, flow_id=flow_id, offset=0, count=1024) # Log should contain two entries. First one about successful execution of # the command (not interesting), the other one containing the error about # unsuccessful parsing. self.assertLen(logs, 2) self.assertIn("It was bound to happen.", logs[1].message)
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 testWriteClientSnapshotHistoryUpdatesLastTimestampIfNotSet(self): client_id = self.InitializeClient() client_new = rdf_objects.ClientSnapshot(client_id=client_id) client_new.kernel = "1.0.0" client_new.timestamp = rdfvalue.RDFDatetime.FromHumanReadable("2010-01-01") self.db.WriteClientSnapshotHistory([client_new]) info = self.db.ReadClientFullInfo(client_id) self.assertEqual(info.last_snapshot.kernel, "1.0.0") self.assertEqual(info.last_snapshot.timestamp, rdfvalue.RDFDatetime.FromHumanReadable("2010-01-01")) self.assertEqual(info.last_startup_info.timestamp, rdfvalue.RDFDatetime.FromHumanReadable("2010-01-01"))
def testGetSummaryEdrAgents(self): snapshot = rdf_objects.ClientSnapshot() snapshot.client_id = "C.0123456789012345" snapshot.edr_agents.append( rdf_client.EdrAgent(name="foo", agent_id="1337")) snapshot.edr_agents.append( rdf_client.EdrAgent(name="bar", agent_id="108")) summary = snapshot.GetSummary() self.assertLen(summary.edr_agents, 2) self.assertEqual(summary.edr_agents[0].name, "foo") self.assertEqual(summary.edr_agents[1].name, "bar") self.assertEqual(summary.edr_agents[0].agent_id, "1337") self.assertEqual(summary.edr_agents[1].agent_id, "108")
def _SetupLastPingClients(self, now): time_past = now - rdfvalue.Duration("1d") client_ids_to_ping = {} for i in range(10): client_id = self.InitializeClient() self.db.WriteClientSnapshot( rdf_objects.ClientSnapshot(client_id=client_id)) ping = (time_past if i % 2 == 0 else now) self.db.WriteClientMetadata(client_id, last_ping=ping) client_ids_to_ping[client_id] = ping return client_ids_to_ping