Example #1
0
    def testClientStartupInfo(self):
        """StartupInfo is written to a separate table, make sure the merge works."""
        d = self.db

        client_id = "C.fc413187fefa1dcf"
        self._InitializeClient(client_id)

        client = objects.Client(client_id=client_id, kernel="12.3")
        client.startup_info = rdf_client.StartupInfo(boot_time=123)
        client.knowledge_base.fqdn = "test1234.examples.com"
        d.WriteClient(client)

        client = d.ReadClient(client_id)
        self.assertEqual(client.startup_info.boot_time, 123)

        client.kernel = "12.4"
        client.startup_info = rdf_client.StartupInfo(boot_time=124)
        d.WriteClient(client)

        client.kernel = "12.5"
        client.startup_info = rdf_client.StartupInfo(boot_time=125)
        d.WriteClient(client)

        hist = d.ReadClientHistory(client_id)
        self.assertEqual(len(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.assertEqual(len(history), 3)
        self.assertEqual(startup_infos, history)
Example #2
0
    def testStartupHistory(self):
        d = self.db

        client_id = "C.0000000050000001"
        si = rdf_client.StartupInfo(boot_time=1)

        with self.assertRaises(db.UnknownClientError):
            d.WriteClientStartupInfo(client_id, si)

        self._InitializeClient(client_id)

        d.WriteClientStartupInfo(client_id, si)
        si.boot_time = 2
        d.WriteClientStartupInfo(client_id, si)
        si.boot_time = 3
        d.WriteClientStartupInfo(client_id, si)

        last_is = d.ReadClientStartupInfo(client_id)
        self.assertIsInstance(last_is, rdf_client.StartupInfo)
        self.assertEqual(last_is.boot_time, 3)
        self.assertIsInstance(last_is.timestamp, rdfvalue.RDFDatetime)

        hist = d.ReadClientStartupInfoHistory(client_id)
        self.assertEqual(len(hist), 3)
        self.assertEqual([si.boot_time for si in hist], [3, 2, 1])
        self.assertIsInstance(hist[0].timestamp, rdfvalue.RDFDatetime)
        self.assertGreater(hist[0].timestamp, hist[1].timestamp)
        self.assertGreater(hist[1].timestamp, hist[2].timestamp)

        md = self.db.ReadClientMetadata(client_id)
        self.assertEqual(md.startup_info_timestamp, hist[0].timestamp)

        self.assertIsNone(d.ReadClientStartupInfo("C.0000000000000000"))
        self.assertEqual(d.ReadClientStartupInfoHistory("C.0000000000000000"),
                         [])
Example #3
0
    def testWriteClientSnapshotHistoryUpdatesOnlyLastClientTimestamp(self):
        client_id = self.InitializeClient()

        client_old = objects.ClientSnapshot(client_id=client_id)
        client_old.kernel = "1.0.0"
        client_old.startup_info.client_info.client_name = "foo"
        self.db.WriteClientSnapshot(client_old)

        old_timestamp = self.db.ReadClientSnapshot(client_id).timestamp

        startup_info = rdf_client.StartupInfo()
        startup_info.client_info.client_name = "bar"
        self.db.WriteClientStartupInfo(client_id, startup_info)

        startup_timestamp = self.db.ReadClientStartupInfo(client_id).timestamp

        client_new = objects.ClientSnapshot(client_id=client_id)
        client_new.kernel = "2.0.0"
        client_new.startup_info.client_info.client_name = "baz"
        client_new.timestamp = rdfvalue.RDFDatetime.Lerp(
            0.5, start_time=old_timestamp, end_time=startup_timestamp)
        self.db.WriteClientSnapshotHistory([client_new])

        info = self.db.ReadClientFullInfo(client_id)
        last_snapshot = info.last_snapshot
        last_startup_info = info.last_startup_info
        self.assertEqual(last_snapshot.kernel, "2.0.0")
        self.assertEqual(last_snapshot.startup_info.client_info.client_name,
                         "baz")
        self.assertEqual(last_snapshot.timestamp, client_new.timestamp)
        self.assertEqual(last_startup_info.client_info.client_name, "bar")
        self.assertEqual(last_startup_info.timestamp, startup_timestamp)
Example #4
0
  def testReadAllClientsFullInfoReadsMultipleClientsWithMultipleLabels(self):
    d = self.db

    for i in range(10):
      client_id = "C.000000005000000%d" % i
      self._InitializeClient(client_id)

      cl = objects.ClientSnapshot(
          client_id=client_id,
          knowledge_base=rdf_client.KnowledgeBase(
              fqdn="test%d.examples.com" % i),
          kernel="12.3.%d" % i)
      d.WriteClientSnapshot(cl)
      d.WriteClientMetadata(client_id, certificate=CERT)
      si = rdf_client.StartupInfo(boot_time=i)
      d.WriteClientStartupInfo(client_id, si)
      d.AddClientLabels(
          client_id, "test_owner",
          ["test_label-a-%d" % i, "test_label-b-%d" % i])

    c_infos = sorted(
        d.ReadAllClientsFullInfo(), key=lambda c: c.last_snapshot.client_id)
    for i, full_info in enumerate(c_infos):
      self.assertEqual(full_info.last_snapshot.client_id,
                       "C.000000005000000%d" % i)
      self.assertEqual(full_info.metadata.certificate, CERT)
      self.assertEqual(full_info.last_startup_info.boot_time, i)
      self.assertEqual(
          sorted(full_info.labels, key=lambda l: l.name), [
              objects.ClientLabel(
                  owner="test_owner", name="test_label-a-%d" % i),
              objects.ClientLabel(
                  owner="test_owner", name="test_label-b-%d" % i)
          ])
Example #5
0
    def testReadClientStartupInfo(self):
        d = self.db

        client_id = self.InitializeClient()

        d.WriteClientStartupInfo(client_id,
                                 rdf_client.StartupInfo(boot_time=1337))
        d.WriteClientStartupInfo(client_id,
                                 rdf_client.StartupInfo(boot_time=2000))

        last_is = d.ReadClientStartupInfo(client_id)
        self.assertIsInstance(last_is, rdf_client.StartupInfo)
        self.assertEqual(last_is.boot_time, 2000)
        self.assertIsInstance(last_is.timestamp, rdfvalue.RDFDatetime)

        md = self.db.ReadClientMetadata(client_id)
        self.assertEqual(md.startup_info_timestamp, last_is.timestamp)
Example #6
0
    def _SetUpReadClientStartupInfoHistoryTest(self):
        d = self.db

        self.client_id = self.InitializeClient()

        timestamps = [rdfvalue.RDFDatetime.Now()]

        si = rdf_client.StartupInfo(boot_time=1)
        d.WriteClientStartupInfo(self.client_id, si)
        timestamps.append(d.ReadClientStartupInfo(self.client_id).timestamp)

        timestamps.append(rdfvalue.RDFDatetime.Now())

        si = rdf_client.StartupInfo(boot_time=2)
        d.WriteClientStartupInfo(self.client_id, si)
        timestamps.append(d.ReadClientStartupInfo(self.client_id).timestamp)

        timestamps.append(rdfvalue.RDFDatetime.Now())

        return timestamps
Example #7
0
    def testReadClientStartupInfoHistory(self):
        d = self.db

        client_id = self.InitializeClient()
        d.WriteClientStartupInfo(client_id,
                                 rdf_client.StartupInfo(boot_time=1))
        d.WriteClientStartupInfo(client_id,
                                 rdf_client.StartupInfo(boot_time=2))
        d.WriteClientStartupInfo(client_id,
                                 rdf_client.StartupInfo(boot_time=3))

        hist = d.ReadClientStartupInfoHistory(client_id)
        self.assertEqual(len(hist), 3)
        self.assertEqual([si.boot_time for si in hist], [3, 2, 1])
        self.assertIsInstance(hist[0].timestamp, rdfvalue.RDFDatetime)
        self.assertGreater(hist[0].timestamp, hist[1].timestamp)
        self.assertGreater(hist[1].timestamp, hist[2].timestamp)

        md = self.db.ReadClientMetadata(client_id)
        self.assertEqual(md.startup_info_timestamp, hist[0].timestamp)
Example #8
0
  def Run(self, unused_arg, ttl=None):
    """Returns the startup information."""
    logging.debug("Sending startup information.")
    boot_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(psutil.boot_time())
    response = rdf_client.StartupInfo(
        boot_time=boot_time, client_info=GetClientInformation())

    self.grr_worker.SendReply(
        response,
        session_id=self.well_known_session_id,
        response_id=0,
        request_id=0,
        priority=rdf_flows.GrrMessage.Priority.LOW_PRIORITY,
        message_type=rdf_flows.GrrMessage.Type.MESSAGE,
        require_fastpoll=False,
        ttl=ttl)
Example #9
0
    def _SetupFullInfoClients(self):
        for i in range(10):
            client_id = self.InitializeClient("C.000000005000000%d" % i)

            cl = objects.ClientSnapshot(
                client_id=client_id,
                knowledge_base=rdf_client.KnowledgeBase(
                    fqdn="test%d.examples.com" % i),
                kernel="12.3.%d" % i)
            self.db.WriteClientSnapshot(cl)
            self.db.WriteClientMetadata(client_id, certificate=CERT)
            si = rdf_client.StartupInfo(boot_time=i)
            self.db.WriteClientStartupInfo(client_id, si)
            self.db.AddClientLabels(
                client_id, "test_owner",
                ["test_label-a-%d" % i,
                 "test_label-b-%d" % i])
Example #10
0
  def ProcessMessage(self, message=None, event=None):
    client_id = message.source
    # Older client versions do not sent the RDFValue type name explicitly.
    if event is None:
      event = rdf_client.StartupInfo(message.args)

    client_info = event.client_info

    if client_info.client_version < 2910:
      python_hack_root_urn = config_lib.CONFIG.Get("Config.python_hack_root")
      hack_urn = python_hack_root_urn.Add("find_fix.py")

      fd = aff4.FACTORY.Open(hack_urn, token=self.token)
      python_blob = fd.Get(fd.Schema.BINARY)
      if python_blob is None:
        raise flow.FlowError("Python hack %s not found." % hack_urn)

      self.CallClient(
          client_id, standard_actions.ExecutePython, python_code=python_blob)
Example #11
0
    def ProcessMessage(self, message=None, event=None):
        """Handle a startup event."""
        _ = event
        # We accept unauthenticated messages so there are no errors but we don't
        # store the results.
        if (message.auth_state !=
                rdf_flows.GrrMessage.AuthorizationState.AUTHENTICATED):
            return

        client_id = message.source

        client = aff4.FACTORY.Create(client_id,
                                     aff4_grr.VFSGRRClient,
                                     mode="rw",
                                     token=self.token)
        old_info = client.Get(client.Schema.CLIENT_INFO)
        old_boot = client.Get(client.Schema.LAST_BOOT_TIME, 0)
        startup_info = rdf_client.StartupInfo(message.payload)
        info = startup_info.client_info

        # Only write to the datastore if we have new information.
        new_data = (info.client_name, info.client_version, info.revision,
                    info.build_time, info.client_description)
        old_data = (old_info.client_name, old_info.client_version,
                    old_info.revision, old_info.build_time,
                    old_info.client_description)

        if new_data != old_data:
            client.Set(client.Schema.CLIENT_INFO(info))

        client.AddLabels(*info.labels, owner="GRR")

        # Allow for some drift in the boot times (5 minutes).
        if abs(int(old_boot) - int(startup_info.boot_time)) > 300 * 1e6:
            client.Set(client.Schema.LAST_BOOT_TIME(startup_info.boot_time))

        client.Close()

        events.Events.PublishEventInline("ClientStartup",
                                         message,
                                         token=self.token)
Example #12
0
    def testReadClientFullInfoReturnsCorrectResult(self):
        d = self.db

        client_id = self.InitializeClient()

        cl = objects.ClientSnapshot(client_id=client_id,
                                    knowledge_base=rdf_client.KnowledgeBase(
                                        fqdn="test1234.examples.com"),
                                    kernel="12.3")
        d.WriteClientSnapshot(cl)
        d.WriteClientMetadata(client_id, certificate=CERT)
        si = rdf_client.StartupInfo(boot_time=1)
        d.WriteClientStartupInfo(client_id, si)
        d.AddClientLabels(client_id, "test_owner", ["test_label"])

        full_info = d.ReadClientFullInfo(client_id)
        self.assertEqual(full_info.last_snapshot, cl)
        self.assertEqual(full_info.metadata.certificate, CERT)
        self.assertEqual(full_info.last_startup_info, si)
        self.assertEqual(
            full_info.labels,
            [objects.ClientLabel(owner="test_owner", name="test_label")])
Example #13
0
    def testFullInfo(self):
        d = self.db

        client_id = "C.0000000050000001"
        self._InitializeClient(client_id)

        cl = objects.Client(client_id=client_id,
                            knowledge_base=rdf_client.KnowledgeBase(
                                fqdn="test1234.examples.com"),
                            kernel="12.3")
        d.WriteClient(cl)
        d.WriteClientMetadata(client_id, certificate=CERT)
        si = rdf_client.StartupInfo(boot_time=1)
        d.WriteClientStartupInfo(client_id, si)
        d.AddClientLabels(client_id, "test_owner", ["test_label"])

        full_info = d.ReadFullInfoClient(client_id)
        self.assertEqual(full_info["client"], cl)
        self.assertEqual(full_info["metadata"].certificate, CERT)
        self.assertEqual(full_info["last_startup_info"], si)
        self.assertEqual(
            full_info["labels"],
            [objects.ClientLabel(owner="test_owner", name="test_label")])