def testDarwinClientMatchesIffOsDarwinIsSelected(self): r0 = foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False) r1 = foreman_rules.ForemanOsClientRule( os_windows=True, os_linux=False, os_darwin=True) client_id = self.SetupClient(0, system="Darwin") info = data_store.REL_DB.ReadClientFullInfo(client_id) self.assertFalse(r0.Evaluate(info)) self.assertTrue(r1.Evaluate(info))
def testDarwinClientMatchesIffOsDarwinIsSelected(self): r0 = foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False) r1 = foreman_rules.ForemanOsClientRule( os_windows=True, os_linux=False, os_darwin=True) client_id_dar = self.SetupClient(0, system="Darwin") self.assertFalse( r0.Evaluate(aff4.FACTORY.Open(client_id_dar, token=self.token))) self.assertTrue( r1.Evaluate(aff4.FACTORY.Open(client_id_dar, token=self.token)))
def testWindowsClientDoesNotMatchRuleWithNoOsSelected(self): r = foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=False, os_darwin=False) client_id = self.SetupClient(0, system="Windows") info = data_store.REL_DB.ReadClientFullInfo(client_id) self.assertFalse(r.Evaluate(info))
def Run(self): def ReplaceCronJobUrn(): jobs = list(aff4_cronjobs.GetCronManager().ListJobs(token=self.token)) return {jobs[0]: "CreateAndRunGenericHuntFlow_1234"} flow_name = file_finder.FileFinder.__name__ flow_args = rdf_file_finder.FileFinderArgs( paths=["c:\\windows\\system32\\notepad.*"]) hunt_runner_args = rdf_hunts.HuntRunnerArgs() hunt_runner_args.client_rule_set.rules = [ foreman_rules.ForemanClientRule( os=foreman_rules.ForemanOsClientRule(os_windows=True)) ] hunt_runner_args.description = "Foobar! (cron)" self.Check( "CreateCronJob", args=cron_plugin.ApiCreateCronJobArgs( description="Foobar!", flow_name=flow_name, flow_args=flow_args, hunt_runner_args=hunt_runner_args, periodicity=604800, lifetime=3600), replace=ReplaceCronJobUrn)
def testCopyHuntPreservesRuleType(self): self.StartHunt( description="model hunt", flow_runner_args=rdf_flow_runner.FlowRunnerArgs( flow_name=transfer.GetFile.__name__), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.NTFS, )), client_rule_set=foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule(os_darwin=True)) ]), creator=self.token.username) 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?") # Click on "Next" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsElementPresent, "css=grr-wizard-form:contains('Hunt parameters')") # Click on "Next" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "How to process results") # Click on "Next" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Where to run?") self.WaitUntil( self.IsElementPresent, "css=grr-new-hunt-wizard-form " "label:contains('Os darwin') ~ * input:checked")
def testWindowsClientDoesNotMatchRuleWithNoOsSelected(self): r = foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=False, os_darwin=False) client_id_win = self.SetupClient(0, system="Windows") self.assertFalse( r.Evaluate(aff4.FACTORY.Open(client_id_win, token=self.token)))
def testForemanRulesWorkCorrectlyWithStandardHunt(self): client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule(os_windows=True)) ]) hunt_obj = rdf_hunt_objects.Hunt(client_rule_set=client_rule_set, client_rate=0, args=self.GetFileHuntArgs()) hunt_obj.args.hunt_type = hunt_obj.args.HuntType.STANDARD data_store.REL_DB.WriteHuntObject(hunt_obj) hunt.StartHunt(hunt_obj.hunt_id) # Check matching client. client_id = self.SetupClient(0, system="Windows") foreman_obj = foreman.Foreman() foreman_obj.AssignTasksToClient(client_id) flows = data_store.REL_DB.ReadAllFlowObjects(client_id=client_id) self.assertLen(flows, 1) # Check non-matching client. client_id = self.SetupClient(1, system="Linux") foreman_obj.AssignTasksToClient(client_id) flows = data_store.REL_DB.ReadAllFlowObjects(client_id=client_id) self.assertEmpty(flows)
def testOperatingSystemSelection(self): """Tests that we can distinguish based on operating system.""" self.SetupClient(1, system="Windows XP") self.SetupClient(2, system="Linux") self.SetupClient(3, system="Windows 7") with utils.Stubber(flow, "StartAFF4Flow", self.StartFlow): # Now setup the filters now = rdfvalue.RDFDatetime.Now() expires = now + rdfvalue.Duration("1h") foreman_obj = foreman.GetForeman(token=self.token) # Make a new rule rule = foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule") # Matches Windows boxes rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule(os_windows=True)) ]) # Will run Test Flow rule.actions.Append(flow_name="Test Flow", argv=rdf_protodict.Dict(foo="bar")) # Clear the rule set and add the new rule to it. rule_set = foreman_obj.Schema.RULES() rule_set.Append(rule) # Assign it to the foreman foreman_obj.Set(foreman_obj.Schema.RULES, rule_set) foreman_obj.Close() self.clients_launched = [] foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") # Make sure that only the windows machines ran self.assertEqual(len(self.clients_launched), 2) self.assertEqual(self.clients_launched[0][0], rdf_client.ClientURN(u"C.1000000000000001")) self.assertEqual(self.clients_launched[1][0], rdf_client.ClientURN(u"C.1000000000000003")) self.clients_launched = [] # Run again - This should not fire since it did already foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") self.assertEqual(len(self.clients_launched), 0)
def testEvaluatesNegativeIfNestedRuleEvaluatesNegative(self): r = foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)) client_id_win = self.SetupClient(0, system="Windows") # The Windows client doesn't match rule r self.assertFalse( r.Evaluate(data_store.REL_DB.ReadClientFullInfo(client_id_win)))
def testEvaluatesNegativeIfNestedRuleEvaluatesNegative(self): r = foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)) client_id_win = self.SetupClient(0, system="Windows") # The Windows client doesn't match rule r self.assertFalse( r.Evaluate(aff4.FACTORY.Open(client_id_win, token=self.token)))
def testEvaluatesPositiveInMatchAllModeIfAllRuleMatch(self): # Instantiate a rule set that matches if all of its two # operating system rules match rs = foreman_rules.ForemanClientRuleSet( match_mode=foreman_rules.ForemanClientRuleSet.MatchMode.MATCH_ALL, rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=True)) ]) client_id_lin = self.SetupClient(0, system="Linux") # All of the set's rules have os_linux=False, so the whole set matches self.assertTrue( rs.Evaluate(data_store.REL_DB.ReadClientFullInfo(client_id_lin)))
def testEvaluatesPositiveInMatchAnyModeIfOneRuleMatches(self): # Instantiate a rule set that matches if any of its two # operating system rules matches rs = foreman_rules.ForemanClientRuleSet( match_mode=foreman_rules.ForemanClientRuleSet.MatchMode.MATCH_ANY, rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=True)) ]) client_id_dar = self.SetupClient(0, system="Darwin") # One of the set's rules has os_darwin=True, so the whole set matches # with the match any match mode self.assertTrue( rs.Evaluate(aff4.FACTORY.Open(client_id_dar, token=self.token)))
def testEvaluatesNegativeInMatchAnyModeIfNoRuleMatches(self): # Instantiate a rule set that matches if any of its two # operating system rules matches rs = foreman_rules.ForemanClientRuleSet( match_mode=foreman_rules.ForemanClientRuleSet.MatchMode.MATCH_ANY, rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=True)) ]) client_id_win = self.SetupClient(0, system="Windows") # None of the set's rules has os_windows=True, so the whole set doesn't # match self.assertFalse( rs.Evaluate(data_store.REL_DB.ReadClientFullInfo(client_id_win)))
def testEvaluatesNegativeInMatchAllModeIfOnlyOneRuleMatches(self): # Instantiate a rule set that matches if all of its two # operating system rules match rs = foreman_rules.ForemanClientRuleSet( match_mode=foreman_rules.ForemanClientRuleSet.MatchMode.MATCH_ALL, rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=False)), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule( os_windows=False, os_linux=True, os_darwin=True)) ]) client_id_dar = self.SetupClient(0, system="Darwin") # One of the set's rules has os_darwin=False, so the whole set doesn't # match with the match all match mode self.assertFalse( rs.Evaluate(data_store.REL_DB.ReadClientFullInfo(client_id_dar)))
def GenerateSample(number=0): # Assert that the argument uses at most the three least significant bits num_combinations = 2**3 if number < 0 or number >= num_combinations: raise ValueError( "Only %d distinct instances of %s exist, " "numbered from 0 to %d." % (num_combinations, foreman_rules.ForemanOsClientRule.__name__, num_combinations - 1)) # Assign the bits to new rule's boolean fields accordingly return foreman_rules.ForemanOsClientRule( os_windows=number & 1, os_linux=number & 2, os_darwin=number & 4)
def testOperatingSystemSelection(self): """Tests that we can distinguish based on operating system.""" self.SetupTestClientObject(1, system="Windows XP") self.SetupTestClientObject(2, system="Linux") self.SetupTestClientObject(3, system="Windows 7") with utils.Stubber(implementation.GRRHunt, "StartClients", self.StartClients): # Now setup the filters now = rdfvalue.RDFDatetime.Now() expiration_time = now + rdfvalue.Duration("1h") # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule", hunt_name=standard.GenericHunt.__name__, hunt_id="H:111111") # Matches Windows boxes rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule(os_windows=True)) ]) data_store.REL_DB.WriteForemanRule(rule) self.clients_started = [] foreman_obj = foreman.GetForeman() foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") # Make sure that only the windows machines ran self.assertEqual(len(self.clients_started), 2) self.assertEqual(self.clients_started[0][1], u"C.1000000000000001") self.assertEqual(self.clients_started[1][1], u"C.1000000000000003") self.clients_started = [] # Run again - This should not fire since it did already foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") self.assertEqual(len(self.clients_started), 0)
def testCopyHuntRespectsUserChanges(self): self.CreateSampleHunt("model hunt", 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 and then click through. self.WaitUntil(self.IsTextPresent, "What to run?") # Change values in the flow configuration. self.Type( "css=grr-new-hunt-wizard-form label:contains('Path') " "~ * input:text", "/tmp/very-evil.txt") self.Select( "css=grr-new-hunt-wizard-form label:contains('Pathtype') " "~ * select", "OS") # Click on "Next" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsElementPresent, "css=grr-wizard-form:contains('Hunt parameters')") self.Type( "css=grr-new-hunt-wizard-form label:contains('Description') " "~ * input:text", "my personal copy") self.Type( "css=grr-new-hunt-wizard-form label:contains('Client rate') " "~ * input", "42") # Click on "Next" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "How to process results") # Change output plugin and add another one. self.Click("css=grr-new-hunt-wizard-form button[name=Add]") self.Select("css=grr-configure-output-plugins-page select:eq(0)", "DummyOutputPlugin") self.Type( "css=grr-configure-output-plugins-page " "label:contains('Filename Regex'):eq(0) ~ * input:text", "foobar!") # Click on "Next" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Where to run?") # Replace a rule with another one. self.Click("css=grr-configure-rules-page button[name=Remove]") self.Click("css=grr-configure-rules-page button[name=Add]") self.Click("css=grr-configure-rules-page label:contains('Os darwin') ~ * " "input[type=checkbox]") # Click on "Next" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Review") # Check that expected values are shown in the review. self.WaitUntil(self.IsTextPresent, "OS") self.WaitUntil(self.IsTextPresent, "/tmp/very-evil.txt") self.WaitUntil(self.IsTextPresent, transfer.GetFile.__name__) self.WaitUntil(self.IsTextPresent, "DummyOutputPlugin") self.WaitUntil(self.IsTextPresent, "foobar!") self.WaitUntil(self.IsTextPresent, "blah!") self.WaitUntil(self.IsTextPresent, "my personal copy") self.WaitUntil(self.IsTextPresent, "Os darwin") self.WaitUntil(self.IsTextPresent, "42") # Click on "Run" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Created Hunt") if data_store.RelationalDBReadEnabled(): hunts_list = sorted( data_store.REL_DB.ReadHuntObjects(offset=0, count=10), key=lambda x: x.create_time) self.assertLen(hunts_list, 2) last_hunt = hunts_list[-1] self.assertEqual(last_hunt.args.standard.flow_args.pathspec.path, "/tmp/very-evil.txt") self.assertEqual(last_hunt.args.standard.flow_args.pathspec.pathtype, "OS") self.assertEqual(last_hunt.args.standard.flow_name, transfer.GetFile.__name__) self.assertLen(last_hunt.output_plugins, 2) self.assertEqual(last_hunt.output_plugins[0].plugin_name, "DummyOutputPlugin") self.assertEqual(last_hunt.output_plugins[0].plugin_args.filename_regex, "foobar!") self.assertEqual(last_hunt.output_plugins[0].plugin_args.fetch_binaries, False) self.assertEqual(last_hunt.output_plugins[1].plugin_name, "DummyOutputPlugin") self.assertEqual(last_hunt.output_plugins[1].plugin_args.filename_regex, "blah!") self.assertEqual(last_hunt.output_plugins[1].plugin_args.fetch_binaries, True) self.assertAlmostEqual(last_hunt.client_rate, 42) self.assertEqual(last_hunt.description, "my personal copy") self.assertEqual( last_hunt.client_rule_set, foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( os=foreman_rules.ForemanOsClientRule(os_darwin=True)) ])) else: hunts_root = aff4.FACTORY.Open("aff4:/hunts", token=self.token) hunts_list = sorted(list(hunts_root.ListChildren()), key=lambda x: x.age) self.assertLen(hunts_list, 2) last_hunt = aff4.FACTORY.Open(hunts_list[-1], token=self.token) self.assertEqual(last_hunt.args.flow_args.pathspec.path, "/tmp/very-evil.txt") self.assertEqual(last_hunt.args.flow_args.pathspec.pathtype, "OS") self.assertEqual(last_hunt.args.flow_runner_args.flow_name, transfer.GetFile.__name__) self.assertLen(last_hunt.runner_args.output_plugins, 2) self.assertEqual(last_hunt.runner_args.output_plugins[0].plugin_name, "DummyOutputPlugin") self.assertEqual( last_hunt.runner_args.output_plugins[0].plugin_args.filename_regex, "foobar!") self.assertEqual( last_hunt.runner_args.output_plugins[0].plugin_args.fetch_binaries, False) self.assertEqual(last_hunt.runner_args.output_plugins[1].plugin_name, "DummyOutputPlugin") self.assertEqual( last_hunt.runner_args.output_plugins[1].plugin_args.filename_regex, "blah!") self.assertEqual( last_hunt.runner_args.output_plugins[1].plugin_args.fetch_binaries, True) runner_args = last_hunt.runner_args self.assertAlmostEqual(runner_args.client_rate, 42) self.assertEqual(runner_args.description, "my personal copy") self.assertEqual( runner_args.client_rule_set, foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( os=foreman_rules.ForemanOsClientRule(os_darwin=True)) ]))