Example #1
0
    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)
Example #2
0
    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)
Example #3
0
  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
Example #4
0
    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)
Example #5
0
    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()])
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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])
Example #9
0
  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)
Example #10
0
    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)
Example #11
0
    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
Example #12
0
    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
Example #13
0
  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()])
Example #14
0
    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
Example #15
0
 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)
Example #16
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")
            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
Example #17
0
    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)
Example #18
0
    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"
            )
Example #19
0
  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)
Example #20
0
 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)
Example #21
0
    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)
Example #22
0
  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()])
Example #23
0
  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)
Example #24
0
    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)
Example #25
0
  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])
Example #26
0
    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)
Example #27
0
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)
Example #28
0
  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]])
Example #29
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
Example #30
0
    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))