def testOverridesFlowArgsThroughIfOverridesSpecified(self):
        override_flow_args = rdf_file_finder.FileFinderArgs(paths=["bar"])
        h = rr.ApiRobotCreateFlowHandler(robot_id="foo",
                                         override_flow_args=override_flow_args)

        args = api_flow.ApiCreateFlowArgs(client_id=self.client_id.Basename())
        args.flow.name = file_finder.FileFinder.__name__
        args.flow.args = rdf_file_finder.FileFinderArgs(paths=["foo"])

        f = h.Handle(args=args, token=self.token)
        self.assertEqual(f.args.paths, ["bar"])
Beispiel #2
0
  def testCopyingFlowWithRawBytesWithNonAsciiCharsInArgumentsWorks(self):
    # Literal is defined simply as "bytes" in its proto definition. We make sure
    # to assign ascii-incompatible value to it here.
    condition = rdf_file_finder.FileFinderCondition.ContentsLiteralMatch(
        literal="zażółć gęślą jaźń")
    action = rdf_file_finder.FileFinderAction.Download()
    args = rdf_file_finder.FileFinderArgs(
        action=action, conditions=[condition], paths=["a/b/*"])

    flow.GRRFlow.StartFlow(
        flow_name=flows_file_finder.FileFinder.__name__,
        args=args,
        client_id=self.client_id,
        token=self.token)

    # Navigate to client and select newly created flow.
    self.Open("/#/clients/C.0000000000000001/flows")
    self.Click("css=td:contains('FileFinder')")

    # Open wizard and launch the copy flow.
    self.Click("css=button[name=copy_flow]")
    self.Click("css=button:contains('Launch')")

    # Check that flows list got updated and that the new flow is selected.
    self.WaitUntil(self.IsElementPresent,
                   "css=grr-client-flows-list tr:contains('FileFinder'):nth(1)")
    self.WaitUntil(self.IsElementPresent, "css=grr-client-flows-list "
                   "tr:contains('FileFinder'):nth(0).row-selected")
Beispiel #3
0
  def testListHuntClients(self):
    hunt = implementation.GRRHunt.StartHunt(
        hunt_name=standard.GenericHunt.__name__,
        flow_runner_args=rdf_flows.FlowRunnerArgs(
            flow_name=file_finder.FileFinder.__name__),
        flow_args=rdf_file_finder.FileFinderArgs(
            paths=[os.path.join(self.base_path, "test.plist")],
            action=rdf_file_finder.FileFinderAction(action_type="DOWNLOAD"),),
        client_rate=0,
        token=self.token)
    hunt.Run()

    client_ids = self.SetupClients(5)
    self.AssignTasksToClients(client_ids=client_ids)
    action_mock = action_mocks.FileFinderClientMock()
    hunt_test_lib.TestHuntHelper(
        action_mock, client_ids, iteration_limit=10, token=self.token)

    result = self.handler.Handle(
        hunt_plugin.ApiListHuntClientsArgs(hunt_id=hunt.urn.Basename()),
        token=self.token)

    # TODO(user): This still uses data store internals and will fail on some
    # data stores.

    # This is not super deterministic, we start processing some
    # clients, run the hunt for a bit but there is no order to all
    # this. We should have some clients half finished though (i.e.,
    # with pending requests) and five clients in total.
    self.assertEqual(result.total_count, 5)
    clients = list(result.items)
    pending_requests = [client.pending_requests for client in clients]
    self.assertTrue(any(r.next_state) for r in pending_requests)
Beispiel #4
0
    def testCopyingFlowWithRawBytesWithNonAsciiCharsInArgumentsWorks(self):
        args = rdf_file_finder.FileFinderArgs(
            paths=["a/b/*"],
            upload_token=rdf_client.UploadToken(
                # Encrypted policy is defined simply as "bytes" in its proto
                # definition. We make sure to assign ascii-incompatible value
                # to it here.
                encrypted_policy="\xde\xad\xbe\xef"))
        flow.GRRFlow.StartFlow(flow_name=flows_file_finder.FileFinder.__name__,
                               args=args,
                               client_id=self.client_id,
                               token=self.token)

        # Navigate to client and select newly created flow.
        self.Open("/#/clients/C.0000000000000001/flows")
        self.Click("css=td:contains('FileFinder')")

        # Open wizard and launch the copy flow.
        self.Click("css=button[name=copy_flow]")
        self.Click("css=button:contains('Launch')")

        # Check that flows list got updated and that the new flow is selected.
        self.WaitUntil(
            self.IsElementPresent,
            "css=grr-client-flows-list tr:contains('FileFinder'):nth(1)")
        self.WaitUntil(
            self.IsElementPresent, "css=grr-client-flows-list "
            "tr:contains('FileFinder'):nth(0).row-selected")
Beispiel #5
0
    def setUp(self):
        super(ApiGetHuntFileHandlerTest, self).setUp()

        self.handler = hunt_plugin.ApiGetHuntFileHandler()

        self.file_path = os.path.join(self.base_path, "test.plist")
        self.hunt = hunts.GRRHunt.StartHunt(
            hunt_name="GenericHunt",
            flow_runner_args=rdf_flows.FlowRunnerArgs(
                flow_name=file_finder.FileFinder.__name__),
            flow_args=rdf_file_finder.FileFinderArgs(
                paths=[self.file_path],
                action=rdf_file_finder.FileFinderAction(
                    action_type="DOWNLOAD"),
            ),
            client_rate=0,
            token=self.token)
        self.hunt.Run()

        self.results_urn = self.hunt.results_collection_urn
        self.aff4_file_path = "fs/os/%s" % self.file_path

        self.client_id = self.SetupClients(1)[0]
        self.AssignTasksToClients(client_ids=[self.client_id])
        action_mock = action_mocks.FileFinderClientMock()
        test_lib.TestHuntHelper(action_mock, [self.client_id],
                                token=self.token)
Beispiel #6
0
  def Run(self):

    def ReplaceCronJobUrn():
      jobs = list(cronjobs.CRON_MANAGER.ListJobs(token=self.token))
      return {jobs[0].Basename(): "CreateAndRunGeneicHuntFlow_1234"}

    flow_args = standard.CreateGenericHuntFlowArgs()
    flow_args.hunt_args.flow_args = rdf_file_finder.FileFinderArgs(
        paths=["c:\\windows\\system32\\notepad.*"])
    flow_args.hunt_args.flow_runner_args.flow_name = (
        file_finder.FileFinder.__name__)
    flow_args.hunt_runner_args.client_rule_set.rules = [
        rdf_foreman.ForemanClientRule(os=rdf_foreman.ForemanOsClientRule(
            os_windows=True))
    ]
    flow_args.hunt_runner_args.description = "Foobar! (cron)"

    self.Check(
        "CreateCronJob",
        args=cron_plugin.ApiCronJob(
            description="Foobar!",
            flow_name=standard.CreateAndRunGenericHuntFlow.__name__,
            periodicity=604800,
            lifetime=3600,
            flow_args=flow_args),
        replace=ReplaceCronJobUrn)
 def Check(path):
     router.CreateFlow(api_flow.ApiCreateFlowArgs(
         flow=api_flow.ApiFlow(
             name=file_finder.FileFinder.__name__,
             args=rdf_file_finder.FileFinderArgs(paths=[path])),
         client_id=self.client_id),
                       token=self.token)
Beispiel #8
0
    def testFileFinderThrottlingByFlowCountWorks(self):
        self.InitRouterConfig(
            self.__class__.FILE_FINDER_THROTTLED_ROUTER_CONFIG %
            self.token.username)

        args = []
        for p in ["tests.plist", "numbers.txt", "numbers.txt.ver2"]:
            args.append(
                rdf_file_finder.FileFinderArgs(
                    action=rdf_file_finder.FileFinderAction(
                        action_type="STAT"),
                    paths=[p]).AsPrimitiveProto())

        client_ref = self.api.Client(client_id=self.client_id.Basename())

        flow_obj = client_ref.CreateFlow(name=file_finder.FileFinder.__name__,
                                         args=args[0])
        self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)

        flow_obj = client_ref.CreateFlow(name=file_finder.FileFinder.__name__,
                                         args=args[1])
        self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)

        with self.assertRaisesRegexp(RuntimeError, "2 flows run since"):
            client_ref.CreateFlow(name=file_finder.FileFinder.__name__,
                                  args=args[2])
Beispiel #9
0
    def _CreateHuntFromHunt(self):
        flow_args = rdf_file_finder.FileFinderArgs(
            paths=["a/*", "b/*"],
            action=rdf_file_finder.FileFinderAction(action_type="STAT"))
        flow_runner_args = rdf_flows.FlowRunnerArgs(
            flow_name=file_finder.FileFinder.__name__)
        client_rule_set = self._CreateForemanClientRuleSet()
        source_h = self.CreateHunt(flow_args=flow_args,
                                   flow_runner_args=flow_runner_args,
                                   description="foo-description",
                                   client_rule_set=client_rule_set)

        ref = rdf_hunts.FlowLikeObjectReference.FromHuntId(
            source_h.urn.Basename())

        # Modify flow_args so that there are differences.
        flow_args.paths = ["b/*", "c/*"]
        client_rule_set.rules[0].regex.field = "FQDN"
        output_plugins = [
            output_plugin.OutputPluginDescriptor(
                plugin_name="TestOutputPlugin")
        ]
        new_h = self.CreateHunt(flow_args=flow_args,
                                flow_runner_args=flow_runner_args,
                                description="bar-description",
                                client_rule_set=client_rule_set,
                                output_plugins=output_plugins,
                                original_object=ref)

        return new_h, source_h
Beispiel #10
0
    def _CreateHuntFromFlow(self):
        self.client_id = self.SetupClient(0)

        flow_args = rdf_file_finder.FileFinderArgs(
            paths=["a/*", "b/*"],
            action=rdf_file_finder.FileFinderAction(action_type="STAT"))
        flow_runner_args = rdf_flows.FlowRunnerArgs(
            flow_name=file_finder.FileFinder.__name__)
        flow_urn = flow.GRRFlow.StartFlow(client_id=self.client_id,
                                          args=flow_args,
                                          runner_args=flow_runner_args,
                                          token=self.token)

        ref = rdf_hunts.FlowLikeObjectReference.FromFlowIdAndClientId(
            flow_urn.Basename(), self.client_id.Basename())
        # Modify flow_args so that there are differences.
        flow_args.paths = ["b/*", "c/*"]
        flow_args.action.action_type = "DOWNLOAD"
        flow_args.conditions = [
            rdf_file_finder.FileFinderCondition(
                condition_type="SIZE",
                size=rdf_file_finder.FileFinderSizeCondition(min_file_size=42))
        ]
        return self.CreateHunt(flow_args=flow_args,
                               flow_runner_args=flow_runner_args,
                               original_object=ref), flow_urn
Beispiel #11
0
    def testCopyACLErrorIsCorrectlyDisplayed(self):
        args = rdf_file_finder.FileFinderArgs(paths=["a/b/*"])
        flow.GRRFlow.StartFlow(flow_name=flows_file_finder.FileFinder.__name__,
                               args=args,
                               client_id=self.client_id,
                               token=self.token)

        # Navigate to client and select newly created flow.
        self.Open("/#/clients/C.0000000000000001/flows")
        self.Click("css=td:contains('FileFinder')")

        # Stub out the API handler to guarantee failure.
        with mock.patch.object(
                api_call_router_with_approval_checks.
                ApiCallRouterWithApprovalChecks,
                "CreateFlow") as create_flow_mock:
            # The error has to be an ACL error, since ACL errors are not handled
            # by the global errors handler and are not automatically displayed.
            create_flow_mock.side_effect = [
                access_control.UnauthorizedAccess("oh no!")
            ]

            # Open wizard and launch the copy flow.
            self.Click("css=button[name=copy_flow]")
            self.Click("css=button:contains('Launch')")

        self.WaitUntil(self.IsElementPresent,
                       "css=.modal-dialog .text-danger:contains('oh no!')")

        # Check that closing the dialog doesn't change flow selection.
        self.Click("css=button[name=Close]")
        self.WaitUntil(self.IsElementPresent,
                       "css=grr-client-flows-view tr.row-selected")
Beispiel #12
0
 def Check(path):
     with self.assertRaises(access_control.UnauthorizedAccess):
         router.CreateFlow(api_flow.ApiCreateFlowArgs(
             flow=api_flow.ApiFlow(
                 name=file_finder.FileFinder.__name__,
                 args=rdf_file_finder.FileFinderArgs(paths=[path])),
             client_id=self.client_id),
                           token=self.token)
Beispiel #13
0
 def _RunFileFinder(self,
                    paths,
                    action,
                    conditions=None,
                    follow_links=True):
     return self.RunAction(client_file_finder.FileFinderOS,
                           arg=rdf_file_finder.FileFinderArgs(
                               paths=paths,
                               action=action,
                               conditions=conditions,
                               process_non_regular_files=True,
                               follow_links=follow_links))
Beispiel #14
0
  def testNoThrottlingDoneByDefault(self):
    self.InitRouterConfig(
        self.__class__.FILE_FINDER_ROUTER_CONFIG % self.token.username)

    args = rdf_file_finder.FileFinderArgs(
        action=rdf_file_finder.FileFinderAction(action_type="STAT"),
        paths=["tests.plist"]).AsPrimitiveProto()

    client_ref = self.api.Client(client_id=self.client_id.Basename())

    # Create 60 flows in a row to check that no throttling is applied.
    for _ in range(20):
      flow_obj = client_ref.CreateFlow(
          name=file_finder.FileFinder.__name__, args=args)
      self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)
Beispiel #15
0
  def testFileFinderMaxFileSizeOverrideWorks(self):
    self.InitRouterConfig(self.__class__.FILE_FINDER_MAX_SIZE_OVERRIDE_CONFIG %
                          self.token.username)

    args = rdf_file_finder.FileFinderArgs(
        action=rdf_file_finder.FileFinderAction(action_type="DOWNLOAD"),
        paths=["tests.plist"]).AsPrimitiveProto()

    client_ref = self.api.Client(client_id=self.client_id.Basename())

    flow_obj = client_ref.CreateFlow(
        name=file_finder.FileFinder.__name__, args=args)
    flow_args = self.api.types.UnpackAny(flow_obj.data.args)
    self.assertEqual(flow_args.action.download.max_size, 5000000)
    self.assertEqual(flow_args.action.download.oversized_file_policy,
                     flow_args.action.download.SKIP)
Beispiel #16
0
  def testDownloadActionSkip(self):
    action = rdf_file_finder.FileFinderAction.Download(
        max_size=0, oversized_file_policy="SKIP")
    args = rdf_file_finder.FileFinderArgs(
        action=action,
        paths=[os.path.join(self.base_path, "hello.exe")],
        process_non_regular_files=True)

    transfer_store = MockTransferStore()
    executor = ClientActionExecutor()
    executor.RegisterWellKnownFlow(transfer_store)
    results = executor.Execute(client_file_finder.FileFinderOS, args)

    self.assertEqual(len(transfer_store.blobs), 0)
    self.assertEqual(len(results), 1)
    self.assertFalse(results[0].HasField("transferred_file"))
    self.assertTrue(results[0].HasField("stat_entry"))
Beispiel #17
0
  def testFileFinderThrottlingByDuplicateIntervalWorks(self):
    self.InitRouterConfig(self.__class__.FILE_FINDER_THROTTLED_ROUTER_CONFIG %
                          self.token.username)

    args = rdf_file_finder.FileFinderArgs(
        action=rdf_file_finder.FileFinderAction(action_type="STAT"),
        paths=["tests.plist"]).AsPrimitiveProto()

    client_ref = self.api.Client(client_id=self.client_id.Basename())

    flow_obj = client_ref.CreateFlow(
        name=file_finder.FileFinder.__name__, args=args)
    self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)

    flow_obj_2 = client_ref.CreateFlow(
        name=file_finder.FileFinder.__name__, args=args)
    self.assertEqual(flow_obj.flow_id, flow_obj_2.flow_id)
Beispiel #18
0
  def testDownloadActionDefault(self):
    action = rdf_file_finder.FileFinderAction.Download()
    args = rdf_file_finder.FileFinderArgs(
        action=action,
        paths=[os.path.join(self.base_path, "hello.exe")],
        process_non_regular_files=True)

    transfer_store = MockTransferStore()
    executor = ClientActionExecutor()
    executor.RegisterWellKnownFlow(transfer_store)
    results = executor.Execute(client_file_finder.FileFinderOS, args)

    self.assertEqual(len(results), 1)
    with open(os.path.join(self.base_path, "hello.exe"), "rb") as filedesc:
      actual = transfer_store.Retrieve(results[0].transferred_file)
      expected = filedesc.read()
      self.assertEqual(actual, expected)
Beispiel #19
0
  def setUp(self):
    super(ApiGetHuntFilesArchiveHandlerTest, self).setUp()

    self.handler = hunt_plugin.ApiGetHuntFilesArchiveHandler()

    self.hunt = implementation.GRRHunt.StartHunt(
        hunt_name=standard.GenericHunt.__name__,
        flow_runner_args=rdf_flows.FlowRunnerArgs(
            flow_name=file_finder.FileFinder.__name__),
        flow_args=rdf_file_finder.FileFinderArgs(
            paths=[os.path.join(self.base_path, "test.plist")],
            action=rdf_file_finder.FileFinderAction(action_type="DOWNLOAD"),),
        client_rate=0,
        token=self.token)
    self.hunt.Run()

    client_ids = self.SetupClients(10)
    self.AssignTasksToClients(client_ids=client_ids)
    action_mock = action_mocks.FileFinderClientMock()
    hunt_test_lib.TestHuntHelper(action_mock, client_ids, token=self.token)
    def testFileFinderHashMaxFileSizeCanBeOverriden(self):
        router = self._CreateRouter(
            file_finder_flow=rr.RobotRouterFileFinderFlowParams(
                enabled=True, max_file_size=42))

        ha = rdf_file_finder.FileFinderHashActionOptions()
        ha.max_size = 80
        ha.oversized_file_policy = ha.OversizedFilePolicy.HASH_TRUNCATED

        path = "/foo/bar"
        handler = router.CreateFlow(api_flow.ApiCreateFlowArgs(
            flow=api_flow.ApiFlow(name=file_finder.FileFinder.__name__,
                                  args=rdf_file_finder.FileFinderArgs(
                                      paths=[path],
                                      action=rdf_file_finder.FileFinderAction(
                                          action_type="HASH", hash=ha))),
            client_id=self.client_id),
                                    token=self.token)

        ha = handler.override_flow_args.action.hash
        self.assertEqual(ha.oversized_file_policy, ha.OversizedFilePolicy.SKIP)
        self.assertEqual(ha.max_size, 42)
    def testFileFinderDownloadMaxFileSizeCanBeOverriden(self):
        router = self._CreateRouter(
            file_finder_flow=rr.RobotRouterFileFinderFlowParams(
                enabled=True, max_file_size=42))

        da = rdf_file_finder.FileFinderDownloadActionOptions()
        da.max_size = 80
        da.oversized_file_policy = da.OversizedFilePolicy.DOWNLOAD_TRUNCATED

        path = "/foo/bar"
        handler = router.CreateFlow(api_flow.ApiCreateFlowArgs(
            flow=api_flow.ApiFlow(name=file_finder.FileFinder.__name__,
                                  args=rdf_file_finder.FileFinderArgs(
                                      paths=[path],
                                      action=rdf_file_finder.FileFinderAction(
                                          action_type="DOWNLOAD",
                                          download=da))),
            client_id=self.client_id),
                                    token=self.token)

        da = handler.override_flow_args.action.download
        self.assertEqual(da.oversized_file_policy, da.OversizedFilePolicy.SKIP)
        self.assertEqual(da.max_size, 42)
Beispiel #22
0
    def Handle(self, args, token=None):
        client_urn = self.GetClientTarget(args, token=token)

        size_condition = rdf_file_finder.FileFinderCondition(
            condition_type=rdf_file_finder.FileFinderCondition.Type.SIZE,
            size=rdf_file_finder.FileFinderSizeCondition(
                max_file_size=args.max_file_size))

        file_finder_args = rdf_file_finder.FileFinderArgs(
            paths=args.paths,
            action=rdf_file_finder.FileFinderAction(action_type=args.action),
            conditions=[size_condition])

        # Check our flow throttling limits, will raise if there are problems.
        throttler = throttle.FlowThrottler(
            daily_req_limit=config_lib.CONFIG.Get("API.DailyFlowRequestLimit"),
            dup_interval=config_lib.CONFIG.Get("API.FlowDuplicateInterval"))
        throttler.EnforceLimits(client_urn,
                                token.username,
                                file_finder.FileFinder.__name__,
                                file_finder_args,
                                token=token)

        # Limit the whole flow to 200MB so if a glob matches lots of small files we
        # still don't have too much impact.
        runner_args = rdf_flows.FlowRunnerArgs(
            client_id=client_urn,
            flow_name=file_finder.FileFinder.__name__,
            network_bytes_limit=200 * 1000 * 1000)

        flow_id = flow.GRRFlow.StartFlow(runner_args=runner_args,
                                         token=token,
                                         args=file_finder_args)

        return ApiStartRobotGetFilesOperationResult(
            operation_id=utils.SmartUnicode(flow_id))
Beispiel #23
0
  def testCopyHuntHandlesLiteralExpressionCorrectly(self):
    """Literals are raw bytes. Testing that raw bytes are processed right."""
    literal_match = rdf_file_finder.FileFinderContentsLiteralMatchCondition(
        literal="foo\x0d\xc8bar")

    implementation.GRRHunt.StartHunt(
        hunt_name=standard.GenericHunt.__name__,
        description="model hunt",
        flow_runner_args=rdf_flows.FlowRunnerArgs(
            flow_name=file_finder.FileFinder.__name__),
        flow_args=rdf_file_finder.FileFinderArgs(
            conditions=[
                rdf_file_finder.FileFinderCondition(
                    condition_type="CONTENTS_LITERAL_MATCH",
                    contents_literal_match=literal_match)
            ],
            paths=["/tmp/evil.txt"]),
        token=self.token)

    self.Open("/#main=ManageHunts")
    self.Click("css=tr:contains('model hunt')")
    self.Click("css=button[name=CopyHunt]:not([disabled])")

    # Wait until dialog appears.
    self.WaitUntil(self.IsTextPresent, "What to run?")

    # Check that non-default values of sample hunt are prefilled.
    self.WaitUntilEqual("foo\\x0d\\xc8bar", self.GetValue,
                        "css=grr-new-hunt-wizard-form "
                        "label:contains('Literal') ~ * input:text")

    # Click on "Next" button.
    self.Click("css=grr-new-hunt-wizard-form button.Next")
    self.WaitUntil(self.IsTextPresent, "Output Processing")
    # Click on "Next" button
    self.Click("css=grr-new-hunt-wizard-form button.Next")
    self.WaitUntil(self.IsTextPresent, "Where to run?")
    # Click on "Next" button
    self.Click("css=grr-new-hunt-wizard-form button.Next")
    self.WaitUntil(self.IsTextPresent, "Review")

    # Check that the arguments summary is present.
    self.WaitUntil(self.IsTextPresent, file_finder.FileFinder.__name__)
    self.WaitUntil(self.IsTextPresent, "foo\\x0d\\xc8bar")

    # Click on "Run" button
    self.Click("css=grr-new-hunt-wizard-form button.Next")
    self.WaitUntil(self.IsTextPresent, "Created Hunt")
    # Close the window and check that the hunt was created.
    self.Click("css=button.Next")

    hunts_root = aff4.FACTORY.Open("aff4:/hunts", token=self.token)
    hunts_list = sorted(list(hunts_root.ListChildren()), key=lambda x: x.age)

    self.assertEqual(len(hunts_list), 2)
    last_hunt = aff4.FACTORY.Open(hunts_list[-1], token=self.token)

    # Check that the hunt was created with a correct literal value.
    self.assertEqual(last_hunt.args.flow_runner_args.flow_name,
                     file_finder.FileFinder.__name__)
    self.assertEqual(last_hunt.args.flow_args.conditions[0]
                     .contents_literal_match.literal, "foo\x0d\xc8bar")
Beispiel #24
0
  def testFileFinderWorkflowWorks(self):
    self.InitRouterConfig(
        self.__class__.FILE_FINDER_ROUTER_CONFIG % self.token.username)

    client_ref = self.api.Client(client_id=self.client_id.Basename())

    args = rdf_file_finder.FileFinderArgs(
        paths=[
            os.path.join(self.base_path, "test.plist"),
            os.path.join(self.base_path, "numbers.txt"),
            os.path.join(self.base_path, "numbers.txt.ver2")
        ],
        action=rdf_file_finder.FileFinderAction(
            action_type=rdf_file_finder.FileFinderAction.Action.DOWNLOAD)
    ).AsPrimitiveProto()
    flow_obj = client_ref.CreateFlow(
        name=file_finder.FileFinder.__name__, args=args)
    self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)

    # Now run the flow we just started.
    client_id = rdf_client.ClientURN(flow_obj.client_id)
    flow_urn = client_id.Add("flows").Add(flow_obj.flow_id)
    for _ in flow_test_lib.TestFlowHelper(
        flow_urn,
        client_id=client_id,
        client_mock=action_mocks.FileFinderClientMock(),
        token=self.token):
      pass

    # Refresh flow.
    flow_obj = client_ref.Flow(flow_obj.flow_id).Get()
    self.assertEqual(flow_obj.data.state, flow_obj.data.TERMINATED)

    # Check that we got 3 results (we downloaded 3 files).
    results = list(flow_obj.ListResults())
    self.assertEqual(len(results), 3)
    # We expect results to be FileFinderResult.
    self.assertItemsEqual(
        [os.path.basename(r.payload.stat_entry.pathspec.path)
         for r in results], ["test.plist", "numbers.txt", "numbers.txt.ver2"])

    # Now downloads the files archive.
    zip_stream = StringIO.StringIO()
    flow_obj.GetFilesArchive().WriteToStream(zip_stream)
    zip_fd = zipfile.ZipFile(zip_stream)

    # Now check that the archive has only "test.plist" file, as it's the
    # only file that matches the whitelist (see FILE_FINDER_ROUTER_CONFIG).
    # There should be 3 items in the archive: the hash of the "test.plist"
    # file, the symlink to this hash and the MANIFEST file.
    namelist = zip_fd.namelist()
    self.assertEqual(len(namelist), 3)

    # First component of every path in the archive is the containing folder,
    # we should strip it.
    namelist = [os.path.join(*n.split(os.sep)[1:]) for n in namelist]
    with open(os.path.join(self.base_path, "test.plist")) as test_plist_fd:
      test_plist_hash = hashlib.sha256(test_plist_fd.read()).hexdigest()
    self.assertEqual(
        sorted([
            # pyformat: disable
            os.path.join(self.client_id.Basename(), "fs", "os",
                         self.base_path.strip("/"), "test.plist"),
            os.path.join("hashes", test_plist_hash),
            "MANIFEST"
            # pyformat: enable
        ]),
        sorted(namelist))
Beispiel #25
0
    def testFlowDuplicateLimit(self):
        # Disable the request limit checking by setting it to 0.
        throttler = throttle.FlowThrottler(
            daily_req_limit=0, dup_interval=rdfvalue.Duration("1200s"))

        # Running the same flow immediately should fail
        with test_lib.FakeTime(self.BASE_TIME):
            throttler.EnforceLimits(self.client_id,
                                    self.token.username,
                                    "DummyLogFlow",
                                    None,
                                    token=self.token)

            flow.GRRFlow.StartFlow(client_id=self.client_id,
                                   flow_name="DummyLogFlow",
                                   token=self.token)

            with self.assertRaises(throttle.ErrorFlowDuplicate):
                throttler.EnforceLimits(self.client_id,
                                        self.token.username,
                                        "DummyLogFlow",
                                        None,
                                        token=self.token)

        # Doing the same outside the window should work
        with test_lib.FakeTime(self.BASE_TIME + 1200 + 1):
            throttler.EnforceLimits(self.client_id,
                                    self.token.username,
                                    "DummyLogFlow",
                                    None,
                                    token=self.token)

            flow.GRRFlow.StartFlow(client_id=self.client_id,
                                   flow_name="DummyLogFlow",
                                   token=self.token)

            with self.assertRaises(throttle.ErrorFlowDuplicate):
                throttler.EnforceLimits(self.client_id,
                                        self.token.username,
                                        "DummyLogFlow",
                                        None,
                                        token=self.token)

        # Now try a flow with more complicated args
        args = rdf_file_finder.FileFinderArgs(
            paths=["/tmp/1", "/tmp/2"],
            action=rdf_file_finder.FileFinderAction(action_type="STAT"))

        with test_lib.FakeTime(self.BASE_TIME):
            throttler.EnforceLimits(self.client_id,
                                    self.token.username,
                                    file_finder.FileFinder.__name__,
                                    args,
                                    token=self.token)

            flow.GRRFlow.StartFlow(
                client_id=self.client_id,
                flow_name=file_finder.FileFinder.__name__,
                token=self.token,
                paths=["/tmp/1", "/tmp/2"],
                action=rdf_file_finder.FileFinderAction(action_type="STAT"))

            with self.assertRaises(throttle.ErrorFlowDuplicate):
                throttler.EnforceLimits(self.client_id,
                                        self.token.username,
                                        file_finder.FileFinder.__name__,
                                        args,
                                        token=self.token)

            # Different args should succeed.
            args = rdf_file_finder.FileFinderArgs(
                paths=["/tmp/1", "/tmp/3"],
                action=rdf_file_finder.FileFinderAction(action_type="STAT"))

            throttler.EnforceLimits(self.client_id,
                                    self.token.username,
                                    file_finder.FileFinder.__name__,
                                    args,
                                    token=self.token)