示例#1
0
  def testGetFileIndicatesCollectedSizeAfterCollection(self):
    # Find the file with FileFinder stat action, so that we can reference it
    # and trigger "Collect" operation on it.
    client_ref = self.api.Client(client_id=self.client_id)
    args = rdf_file_finder.FileFinderArgs(
        paths=[os.path.join(self.base_path, "numbers.txt")],
        action=rdf_file_finder.FileFinderAction.Stat()).AsPrimitiveProto()
    client_ref.CreateFlow(name=file_finder.FileFinder.__name__, args=args)

    client_mock = action_mocks.FileFinderClientMock()
    flow_test_lib.FinishAllFlowsOnClient(
        self.client_id, client_mock=client_mock)

    f = client_ref.File("fs/os" + os.path.join(self.base_path, "numbers.txt"))
    with flow_test_lib.TestWorker():
      operation = f.Collect()
      self.assertEqual(operation.GetState(), operation.STATE_RUNNING)
      flow_test_lib.FinishAllFlowsOnClient(
          self.client_id, client_mock=client_mock)
      self.assertEqual(operation.GetState(), operation.STATE_FINISHED)

    f = f.Get()
    self.assertNotEqual(f.data.hash.sha256, b"")
    self.assertGreater(f.data.hash.num_bytes, 0)
    self.assertGreater(f.data.last_collected, 0)
    self.assertGreater(f.data.last_collected_size, 0)
示例#2
0
    def testClickingOnInterrogateStartsInterrogateFlow(self):
        self.Open("/#/clients/%s" % self.client_id)

        # A click on the Interrogate button starts a flow, disables the button and
        # shows a loading icon within the button.
        self.Click("css=button:contains('Interrogate'):not([disabled])")
        self.WaitUntil(self.IsElementPresent,
                       "css=button:contains('Interrogate')[disabled]")
        self.WaitUntil(self.IsElementPresent,
                       "css=button:contains('Interrogate') i")

        # Get the started flow and finish it, this will re-enable the button.
        flow_test_lib.FinishAllFlowsOnClient(self.client_id,
                                             check_flow_errors=False)

        self.WaitUntilNot(self.IsElementPresent,
                          "css=button:contains('Interrogate')[disabled]")

        # Check if an Interrogate flow was started.
        self.Click("css=a[grrtarget='client.flows']")
        self.Click("css=td:contains('Interrogate')")
        self.WaitUntilContains(
            discovery.Interrogate.__name__, self.GetText,
            "css=table td.proto_key:contains('Flow name') "
            "~ td.proto_value")
示例#3
0
    def _RunListNamedPipesFlow(
        self,
        args: pipes.ListNamedPipesFlowArgs,
        pipe_results: Iterable[rdf_client.NamedPipe] = (),
        proc_results: Iterable[rdf_client.Process] = (),
    ) -> Sequence[pipes.ListNamedPipesFlowResult]:
        """Runs the flow listing named pipes with the given fake action results."""
        class ActionMock(action_mocks.ActionMock):
            def ListNamedPipes(
                self,
                args: None,
            ) -> Iterator[rdf_client.NamedPipe]:
                del args  # Unused.

                for pipe in pipe_results:
                    yield pipe

            def ListProcesses(
                self,
                args: None,
            ) -> Iterator[rdf_client.Process]:
                del args  # Unused.

                for proc in proc_results:
                    yield proc

        flow_id = flow_test_lib.StartAndRunFlow(
            pipes.ListNamedPipesFlow,
            client_mock=ActionMock(),
            client_id=self.client_id,
            flow_args=args,
        )

        flow_test_lib.FinishAllFlowsOnClient(self.client_id)
        return flow_test_lib.GetFlowResults(self.client_id, flow_id)
示例#4
0
文件: flow_test.py 项目: viszsec/grr
    def testValidatesParsersWereNotApplied(self, db: abstract_db.Database):
        token = _CreateToken(db)

        client_id = db_test_utils.InitializeClient(db)

        with mock.patch.object(
                artifact_registry, "REGISTRY",
                artifact_registry.ArtifactRegistry()) as registry:
            registry.RegisterArtifact(self.ECHO1337_ARTIFACT)

            flow_args = rdf_artifacts.ArtifactCollectorFlowArgs()
            flow_args.artifact_list = [self.ECHO1337_ARTIFACT.name]
            flow_args.apply_parsers = True

            flow_id = flow_test_lib.TestFlowHelper(
                collectors.ArtifactCollectorFlow.__name__,
                self.FakeExecuteCommand(),
                client_id=client_id,
                args=flow_args,
                token=token)

        flow_test_lib.FinishAllFlowsOnClient(client_id)

        args = flow_plugin.ApiListParsedFlowResultsArgs()
        args.client_id = client_id
        args.flow_id = flow_id

        with self.assertRaisesRegex(ValueError, "already parsed"):
            self.handler.Handle(args, token=token)
示例#5
0
  def testArtifactCollectorIndicatesCollectedSizeAfterCollection(self):
    registry_stub = artifact_registry.ArtifactRegistry()
    source = rdf_artifacts.ArtifactSource(
        type=rdf_artifacts.ArtifactSource.SourceType.FILE,
        attributes={
            "paths": [os.path.join(self.base_path, "numbers.txt")],
        })
    artifact = rdf_artifacts.Artifact(
        name="FakeArtifact", sources=[source], doc="fake artifact doc")
    registry_stub.RegisterArtifact(artifact)

    client_ref = self.api.Client(client_id=self.client_id)
    with mock.patch.object(artifact_registry, "REGISTRY", registry_stub):
      args = rdf_artifacts.ArtifactCollectorFlowArgs(
          artifact_list=["FakeArtifact"]).AsPrimitiveProto()
      client_ref.CreateFlow(
          name=collectors.ArtifactCollectorFlow.__name__, args=args)

      client_mock = action_mocks.FileFinderClientMock()
      flow_test_lib.FinishAllFlowsOnClient(
          self.client_id, client_mock=client_mock)

    f = client_ref.File("fs/os" +
                        os.path.join(self.base_path, "numbers.txt")).Get()
    self.assertNotEqual(f.data.hash.sha256, b"")
    self.assertGreater(f.data.hash.num_bytes, 0)
    self.assertGreater(f.data.last_collected, 0)
    self.assertGreater(f.data.last_collected_size, 0)
示例#6
0
文件: flow_test.py 项目: viszsec/grr
    def testEmptyResults(self, db: abstract_db.Database):
        token = _CreateToken(db)
        client_id = db_test_utils.InitializeClient(db)

        fake_artifact = rdf_artifacts.Artifact(name="FakeArtifact",
                                               doc="Lorem ipsum.",
                                               sources=[])

        with mock.patch.object(
                artifact_registry, "REGISTRY",
                artifact_registry.ArtifactRegistry()) as registry:
            registry.RegisterArtifact(fake_artifact)

            flow_args = rdf_artifacts.ArtifactCollectorFlowArgs()
            flow_args.artifact_list = [fake_artifact.name]
            flow_args.apply_parsers = False

            flow_id = flow_test_lib.TestFlowHelper(
                collectors.ArtifactCollectorFlow.__name__,
                self.FakeExecuteCommand(),
                client_id=client_id,
                args=flow_args,
                token=token)

            flow_test_lib.FinishAllFlowsOnClient(client_id)

        args = flow_plugin.ApiListParsedFlowResultsArgs(client_id=client_id,
                                                        flow_id=flow_id,
                                                        offset=0,
                                                        count=1024)

        result = self.handler.Handle(args, token=token)
        self.assertEmpty(result.errors)
        self.assertEmpty(result.items)
示例#7
0
    def testLogsWarningIfBtimeNotSupported(self, db: abstract_db.Database):
        client_id = self.client_id
        db.WriteClientMetadata(client_id, fleetspeak_enabled=True)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id
        snapshot.knowledge_base.os = "Linux"
        snapshot.startup_info.client_info.timeline_btime_support = False
        db.WriteClientSnapshot(snapshot)

        with temp.AutoTempDirPath() as tempdir:
            args = rdf_timeline.TimelineArgs(root=tempdir.encode("utf-8"))

            flow_id = flow_test_lib.TestFlowHelper(
                timeline_flow.TimelineFlow.__name__,
                action_mocks.ActionMock(timeline_action.Timeline),
                client_id=client_id,
                token=self.token,
                args=args)

            flow_test_lib.FinishAllFlowsOnClient(client_id)

        log_entries = db.ReadFlowLogEntries(client_id,
                                            flow_id,
                                            offset=0,
                                            count=1)
        self.assertLen(log_entries, 1)
        self.assertRegex(log_entries[0].message, "birth time is not supported")
示例#8
0
    def testExecutePythonHackWithResult(self):
        client_id = db_test_utils.InitializeClient(data_store.REL_DB)

        code = """
magic_return_str = str(py_args["foobar"])
    """

        maintenance_utils.UploadSignedConfigBlob(
            content=code.encode("utf-8"),
            aff4_path="aff4:/config/python_hacks/quux")

        flow_id = flow_test_lib.TestFlowHelper(
            administrative.ExecutePythonHack.__name__,
            client_mock=action_mocks.ActionMock(standard.ExecutePython),
            client_id=client_id,
            hack_name="quux",
            py_args={"foobar": 42},
            token=self.token)

        flow_test_lib.FinishAllFlowsOnClient(client_id=client_id)

        results = flow_test_lib.GetFlowResults(client_id=client_id,
                                               flow_id=flow_id)
        self.assertLen(results, 1)
        self.assertIsInstance(results[0],
                              administrative.ExecutePythonHackResult)
        self.assertEqual(results[0].result_string, "42")
示例#9
0
    def _Collect(self, path: str, signed_url: str) -> str:
        """Runs the large file collection flow.

    Args:
      path: A path to the file to collect.
      signed_url: A signed URL to the where the file should be sent to.

    Returns:
      An identifier of the flow that was created.
    """
        args = large_file.CollectLargeFileFlowArgs()
        args.signed_url = signed_url
        args.path_spec.pathtype = rdf_paths.PathSpec.PathType.OS
        args.path_spec.path = path

        action_mock = action_mocks.ActionMock.With({
            "CollectLargeFile":
            large_file_action.CollectLargeFileAction,
        })

        flow_id = flow_test_lib.TestFlowHelper(
            large_file.CollectLargeFileFlow.__name__,
            action_mock,
            client_id=self.client_id,
            creator=self.test_username,
            args=args)

        flow_test_lib.FinishAllFlowsOnClient(self.client_id)

        return flow_id
示例#10
0
    def testNoLogsIfBtimeSupported(self, db: abstract_db.Database):
        client_id = self.client_id
        db.WriteClientMetadata(client_id, fleetspeak_enabled=True)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id
        snapshot.knowledge_base.os = "Linux"
        snapshot.startup_info.client_info.timeline_btime_support = True
        db.WriteClientSnapshot(snapshot)

        with temp.AutoTempDirPath() as tempdir:
            args = rdf_timeline.TimelineArgs(root=tempdir.encode("utf-8"))

            flow_id = flow_test_lib.TestFlowHelper(
                timeline_flow.TimelineFlow.__name__,
                action_mocks.ActionMock(timeline_action.Timeline),
                client_id=client_id,
                creator=self.test_username,
                args=args)

            flow_test_lib.FinishAllFlowsOnClient(client_id)

        log_entries = db.ReadFlowLogEntries(client_id,
                                            flow_id,
                                            offset=0,
                                            count=1)
        self.assertEmpty(log_entries)
示例#11
0
  def testValidatesFlowName(self, db: abstract_db.Database):
    context = _CreateContext(db)

    class FakeFlow(flow_base.FlowBase):

      def Start(self):
        self.CallState("End")

      def End(self, responses: flow_responses.Responses) -> None:
        del responses  # Unused.

    client_id = db_test_utils.InitializeClient(db)
    flow_id = flow_test_lib.TestFlowHelper(
        FakeFlow.__name__,
        client_id=client_id,
        token=access_control.ACLToken(username=context.username))

    flow_test_lib.FinishAllFlowsOnClient(client_id)

    args = flow_plugin.ApiListParsedFlowResultsArgs()
    args.client_id = client_id
    args.flow_id = flow_id

    with self.assertRaisesRegex(ValueError, "artifact-collector"):
      self.handler.Handle(args, context=context)
示例#12
0
    def testEdrAgentCollection(self):
        client_id = db_test_utils.InitializeClient(data_store.REL_DB)

        artifact_source = rdf_artifacts.ArtifactSource()
        artifact_source.type = rdf_artifacts.ArtifactSource.SourceType.COMMAND
        artifact_source.attributes = {"cmd": "/bin/echo", "args": ["1337"]}

        artifact = rdf_artifacts.Artifact()
        artifact.name = "Foo"
        artifact.doc = "Lorem ipsum."
        artifact.sources = [artifact_source]

        class FooParser(parsers.SingleResponseParser):

            supported_artifacts = ["Foo"]

            def ParseResponse(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                response: rdf_client_action.ExecuteResponse,
            ) -> Iterator[rdf_client.EdrAgent]:
                edr_agent = rdf_client.EdrAgent()
                edr_agent.name = "echo"
                edr_agent.agent_id = response.stdout.decode("utf-8")

                yield edr_agent

        class EchoActionMock(action_mocks.InterrogatedClient):
            def ExecuteCommand(
                self,
                args: rdf_client_action.ExecuteRequest,
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                response = rdf_client_action.ExecuteResponse()
                response.stdout = " ".join(args.args).encode("utf-8")
                response.exit_status = 0

                return [response]

        with mock.patch.object(
                artifact_registry, "REGISTRY",
                artifact_registry.ArtifactRegistry()) as registry:
            registry.RegisterArtifact(artifact)

            with test_lib.ConfigOverrider({"Artifacts.edr_agents": ["Foo"]}):
                with parser_test_lib._ParserContext("Foo", FooParser):
                    flow_test_lib.TestFlowHelper(
                        discovery.Interrogate.__name__,
                        client_mock=EchoActionMock(),
                        client_id=client_id,
                        creator=self.test_username)

                    flow_test_lib.FinishAllFlowsOnClient(client_id)

        snapshot = data_store.REL_DB.ReadClientSnapshot(client_id)
        self.assertLen(snapshot.edr_agents, 1)
        self.assertEqual(snapshot.edr_agents[0].name, "echo")
        self.assertEqual(snapshot.edr_agents[0].agent_id, "1337")
示例#13
0
    def testParsesArtifactCollectionResults(self, db: abstract_db.Database):
        context = _CreateContext(db)

        with mock.patch.object(
                artifact_registry, "REGISTRY",
                artifact_registry.ArtifactRegistry()) as registry:
            registry.RegisterArtifact(self.ECHO1337_ARTIFACT)

            flow_args = rdf_artifacts.ArtifactCollectorFlowArgs()
            flow_args.artifact_list = [self.ECHO1337_ARTIFACT.name]
            flow_args.apply_parsers = False

            client_id = db_test_utils.InitializeClient(db)
            flow_id = flow_test_lib.TestFlowHelper(
                collectors.ArtifactCollectorFlow.__name__,
                self.FakeExecuteCommand(),
                client_id=client_id,
                args=flow_args,
                creator=context.username)

            flow_test_lib.FinishAllFlowsOnClient(client_id)

        class FakeParser(
                abstract_parser.SingleResponseParser[
                    rdf_client_action.ExecuteResponse], ):

            supported_artifacts = [self.ECHO1337_ARTIFACT.name]

            def ParseResponse(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                response: rdf_client_action.ExecuteResponse,
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                precondition.AssertType(response,
                                        rdf_client_action.ExecuteResponse)

                parsed_response = rdf_client_action.ExecuteResponse()
                parsed_response.stdout = response.stdout
                parsed_response.stderr = b"4815162342"
                return [parsed_response]

        with parser_test_lib._ParserContext("Fake", FakeParser):
            args = flow_plugin.ApiListParsedFlowResultsArgs(
                client_id=client_id, flow_id=flow_id, offset=0, count=1024)

            result = self.handler.Handle(args, context=context)

        self.assertEmpty(result.errors)
        self.assertLen(result.items, 1)

        response = result.items[0].payload
        self.assertIsInstance(response, rdf_client_action.ExecuteResponse)
        self.assertEqual(response.stdout, b"1337")
        self.assertEqual(response.stderr, b"4815162342")
示例#14
0
  def _RunUpdateFlow(self, client_id):
    gui_test_lib.CreateFileVersion(
        client_id,
        "fs/os/c/a.txt",
        "Hello World".encode("utf-8"),
        timestamp=gui_test_lib.TIME_0)
    gui_test_lib.CreateFolder(
        client_id, "fs/os/c/TestFolder", timestamp=gui_test_lib.TIME_0)
    gui_test_lib.CreateFolder(
        client_id, "fs/os/c/bin/TestBinFolder", timestamp=gui_test_lib.TIME_0)

    flow_test_lib.FinishAllFlowsOnClient(client_id)
示例#15
0
  def _Collect(self, root: bytes) -> Iterator[timeline_pb2.TimelineEntry]:
    args = rdf_timeline.TimelineArgs(root=root)

    flow_id = flow_test_lib.TestFlowHelper(
        timeline_flow.TimelineFlow.__name__,
        action_mocks.ActionMock(timeline_action.Timeline),
        client_id=self.client_id,
        creator=self.test_username,
        args=args)

    flow_test_lib.FinishAllFlowsOnClient(self.client_id)

    return timeline_flow.ProtoEntries(client_id=self.client_id, flow_id=flow_id)
示例#16
0
  def _Collect(self, root):
    args = rdf_timeline.TimelineArgs(root=root)

    flow_id = flow_test_lib.TestFlowHelper(
        timeline_flow.TimelineFlow.__name__,
        action_mocks.ActionMock(timeline_action.Timeline),
        client_id=self.client_id,
        token=self.token,
        args=args)

    flow_test_lib.FinishAllFlowsOnClient(self.client_id)

    return timeline_flow.Entries(client_id=self.client_id, flow_id=flow_id)
示例#17
0
    def _YaraProcessScan(
        self,
        args: rdf_memory.YaraProcessScanRequest,
        action_mock: Optional[action_mocks.ActionMock] = None,
    ) -> None:
        if action_mock is None:
            action_mock = action_mocks.ActionMock()

        flow_test_lib.TestFlowHelper(memory.YaraProcessScan.__name__,
                                     action_mock,
                                     client_id=self.client_id,
                                     creator=self.test_username,
                                     args=args)

        flow_test_lib.FinishAllFlowsOnClient(self.client_id)
示例#18
0
文件: memory_test.py 项目: syth3/grr
    def _YaraProcessScan(
        self,
        args,
        action_mock=None,
    ):
        if action_mock is None:
            action_mock = action_mocks.ActionMock()

        flow_test_lib.TestFlowHelper(memory.YaraProcessScan.__name__,
                                     action_mock,
                                     client_id=self.client_id,
                                     token=self.token,
                                     args=args)

        flow_test_lib.FinishAllFlowsOnClient(self.client_id)
示例#19
0
  def _RunUpdateFlow(self, client_id):
    gui_test_lib.CreateFileVersion(
        client_id,
        "fs/os/c/a.txt",
        "Hello World".encode("utf-8"),
        timestamp=gui_test_lib.TIME_0)
    gui_test_lib.CreateFolder(
        client_id, "fs/os/c/TestFolder", timestamp=gui_test_lib.TIME_0)
    gui_test_lib.CreateFolder(
        client_id, "fs/os/c/bin/TestBinFolder", timestamp=gui_test_lib.TIME_0)

    flow_test_lib.FinishAllFlowsOnClient(
        client_id,
        client_mock=action_mocks.MultiGetFileClientMock(),
        check_flow_errors=False)
示例#20
0
  def testClientFileFinderIndicatesCollectedSizeAfterCollection(self):
    client_ref = self.api.Client(client_id=self.client_id)
    args = rdf_file_finder.FileFinderArgs(
        paths=[os.path.join(self.base_path, "numbers.txt")],
        action=rdf_file_finder.FileFinderAction.Download(),
        follow_links=True).AsPrimitiveProto()
    client_ref.CreateFlow(name=file_finder.ClientFileFinder.__name__, args=args)

    flow_test_lib.FinishAllFlowsOnClient(
        self.client_id, client_mock=action_mocks.ClientFileFinderClientMock())

    f = client_ref.File("fs/os" +
                        os.path.join(self.base_path, "numbers.txt")).Get()
    self.assertNotEqual(f.data.hash.sha256, b"")
    self.assertGreater(f.data.hash.num_bytes, 0)
    self.assertGreater(f.data.last_collected, 0)
    self.assertGreater(f.data.last_collected_size, 0)
示例#21
0
    def testReportsArtifactCollectionErrors(self, db: abstract_db.Database):
        context = _CreateContext(db)

        with mock.patch.object(
                artifact_registry, "REGISTRY",
                artifact_registry.ArtifactRegistry()) as registry:
            registry.RegisterArtifact(self.ECHO1337_ARTIFACT)

            flow_args = rdf_artifacts.ArtifactCollectorFlowArgs()
            flow_args.artifact_list = [self.ECHO1337_ARTIFACT.name]
            flow_args.apply_parsers = False

            client_id = db_test_utils.InitializeClient(db)
            flow_id = flow_test_lib.TestFlowHelper(
                collectors.ArtifactCollectorFlow.__name__,
                self.FakeExecuteCommand(),
                client_id=client_id,
                args=flow_args,
                creator=context.username)

            flow_test_lib.FinishAllFlowsOnClient(client_id)

        class FakeParser(
                abstract_parser.SingleResponseParser[
                    rdf_client_action.ExecuteResponse], ):

            supported_artifacts = [self.ECHO1337_ARTIFACT.name]

            def ParseResponse(
                self, knowledge_base: rdf_client.KnowledgeBase,
                response: rdf_client_action.ExecuteResponse
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                del knowledge_base, response  # Unused.
                raise abstract_parser.ParseError("Lorem ipsum.")

        with parser_test_lib._ParserContext("Fake", FakeParser):
            args = flow_plugin.ApiListParsedFlowResultsArgs(
                client_id=client_id, flow_id=flow_id, offset=0, count=1024)

            result = self.handler.Handle(args, context=context)

        self.assertEmpty(result.items)
        self.assertLen(result.errors, 1)
        self.assertEqual(result.errors[0], "Lorem ipsum.")
示例#22
0
  def testFileFinderIndicatesCollectedSizeAfterCollection(self):
    client_ref = self.api.Client(client_id=self.client_id)
    # TODO(user): for symlink-related test scenarions, this should require
    # follow_links to be True. However, unlike the ClientFileFinder test
    # below, this one doesn't care about this setting. Fix the
    # FileFinder/ClientFileFinder behavior to match each other.
    args = rdf_file_finder.FileFinderArgs(
        paths=[os.path.join(self.base_path, "numbers.txt")],
        action=rdf_file_finder.FileFinderAction.Download()).AsPrimitiveProto()
    client_ref.CreateFlow(name=file_finder.FileFinder.__name__, args=args)

    flow_test_lib.FinishAllFlowsOnClient(
        self.client_id, client_mock=action_mocks.FileFinderClientMock())

    f = client_ref.File("fs/os" +
                        os.path.join(self.base_path, "numbers.txt")).Get()
    self.assertNotEqual(f.data.hash.sha256, b"")
    self.assertGreater(f.data.hash.num_bytes, 0)
    self.assertGreater(f.data.last_collected, 0)
    self.assertGreater(f.data.last_collected_size, 0)
示例#23
0
文件: flow_test.py 项目: x35029/grr
 def ProcessFlow():
     time.sleep(1)
     client_mock = action_mocks.ListProcessesMock([])
     flow_test_lib.FinishAllFlowsOnClient(client_urn,
                                          client_mock=client_mock)
示例#24
0
文件: vfs_test.py 项目: esmat777/grr
 def ProcessOperation():
     time.sleep(1)
     flow_test_lib.FinishAllFlowsOnClient(self.client_id)
示例#25
0
    def testRefreshFileStartsFlow(self):
        self.Open("/#/clients/C.0000000000000001/vfs/fs/os/c/Downloads/")

        # Select a file and start a flow by requesting a newer version.
        self.Click("css=tr:contains(\"a.txt\")")
        self.Click("css=li[heading=Download]")
        self.Click("css=button:contains(\"Collect from the client\")")

        # Create a new file version (that would have been created by the flow
        # otherwise) and finish the flow.

        # Make sure that the flow has started (when button is clicked, the HTTP
        # API request is sent asynchronously).
        def MultiGetFileStarted():
            return compatibility.GetName(transfer.MultiGetFile) in [
                f.flow_class_name
                for f in data_store.REL_DB.ReadAllFlowObjects(
                    client_id=self.client_id)
            ]

        self.WaitUntil(MultiGetFileStarted)

        flow_test_lib.FinishAllFlowsOnClient(self.client_id,
                                             check_flow_errors=False)

        time_in_future = rdfvalue.RDFDatetime.Now() + rdfvalue.DurationSeconds(
            "1h")
        # We have to make sure that the new version will not be within a second
        # from the current one, otherwise the previous one and the new one will
        # be indistinguishable in the UI (as it has a 1s precision when
        # displaying versions).
        gui_test_lib.CreateFileVersion(self.client_id,
                                       "fs/os/c/Downloads/a.txt",
                                       "The newest version!".encode("utf-8"),
                                       timestamp=time_in_future)

        # Once the flow has finished, the file view should update and add the
        # newly created, latest version of the file to the list. The selected
        # option should still be "HEAD".
        self.WaitUntilContains("HEAD", self.GetText,
                               "css=.version-dropdown > option[selected]")

        # The file table should also update and display the new timestamp.
        self.WaitUntilContains(gui_test_lib.DateTimeString(time_in_future),
                               self.GetText,
                               "css=.version-dropdown > option:nth(1)")

        # The file table should also update and display the new timestamp.
        self.WaitUntil(
            self.IsElementPresent,
            "css=grr-file-table tbody > tr td:contains(\"%s\")" %
            (gui_test_lib.DateTimeString(time_in_future)))

        # Make sure the file content has changed.
        self.Click("css=li[heading=TextView]")
        self.WaitUntilContains("The newest version!", self.GetText,
                               "css=div.monospace pre")

        # Go to the flow management screen and check that there was a new flow.
        self.Click("css=a:contains('Manage launched flows')")
        self.Click("css=grr-flows-list tr:contains('MultiGetFile')")
        self.WaitUntilContains(transfer.MultiGetFile.__name__, self.GetText,
                               "css=#main_bottomPane")

        self.WaitUntilContains(
            "c/Downloads/a.txt", self.GetText,
            "css=#main_bottomPane table > tbody td.proto_key:contains(\"Path\") "
            "~ td.proto_value")
示例#26
0
文件: flow_test.py 项目: viszsec/grr
    def testUsesCollectionTimeFiles(self, db: abstract_db.Database):
        token = _CreateToken(db)
        client_id = db_test_utils.InitializeClient(db)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id
        snapshot.knowledge_base.os = "redox"
        db.WriteClientSnapshot(snapshot)

        with temp.AutoTempFilePath() as temp_filepath:
            fake_artifact_source = rdf_artifacts.ArtifactSource(
                type=rdf_artifacts.ArtifactSource.SourceType.FILE,
                attributes={
                    "paths": [temp_filepath],
                })

            fake_artifact = rdf_artifacts.Artifact(
                name="FakeArtifact",
                doc="Lorem ipsum.",
                sources=[fake_artifact_source])

            flow_args = rdf_artifacts.ArtifactCollectorFlowArgs()
            flow_args.artifact_list = [fake_artifact.name]
            flow_args.apply_parsers = False

            with io.open(temp_filepath, mode="wb") as temp_filedesc:
                temp_filedesc.write(b"OLD")

            with mock.patch.object(
                    artifact_registry, "REGISTRY",
                    artifact_registry.ArtifactRegistry()) as registry:
                registry.RegisterArtifact(fake_artifact)

                # First, we run the artifact collector to collect the old file and save
                # the flow id to parse the results later.
                flow_id = flow_test_lib.TestFlowHelper(
                    collectors.ArtifactCollectorFlow.__name__,
                    action_mocks.FileFinderClientMock(),
                    client_id=client_id,
                    args=flow_args,
                    token=token)

                flow_test_lib.FinishAllFlowsOnClient(client_id)

            with io.open(temp_filepath, mode="wb") as temp_filedesc:
                temp_filedesc.write(b"NEW")

            with mock.patch.object(
                    artifact_registry, "REGISTRY",
                    artifact_registry.ArtifactRegistry()) as registry:
                registry.RegisterArtifact(fake_artifact)

                # Now, we run the artifact collector again to collect the new file to
                # update to this version on the server. The parsing should be performed
                # against the previous flow.
                flow_test_lib.TestFlowHelper(
                    collectors.ArtifactCollectorFlow.__name__,
                    action_mocks.FileFinderClientMock(),
                    client_id=client_id,
                    args=flow_args,
                    token=token)

                flow_test_lib.FinishAllFlowsOnClient(client_id)

        class FakeFileParser(abstract_parser.SingleFileParser):

            supported_artifacts = [fake_artifact.name]

            def ParseFile(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                pathspec: rdf_paths.PathSpec,
                filedesc: file_store.BlobStream,
            ) -> Iterable[rdfvalue.RDFBytes]:
                del knowledge_base, pathspec  # Unused.
                return [rdfvalue.RDFBytes(filedesc.Read())]

        with parser_test_lib._ParserContext("FakeFile", FakeFileParser):
            args = flow_plugin.ApiListParsedFlowResultsArgs(
                client_id=client_id, flow_id=flow_id, offset=0, count=1024)

            result = self.handler.Handle(args, token=token)

        self.assertEmpty(result.errors)
        self.assertLen(result.items, 1)

        response = result.items[0].payload
        self.assertEqual(response, b"OLD")