def testEvaluatesRaisesWithUnsetField(self): r = foreman_rules.ForemanIntegerClientRule( operator=foreman_rules.ForemanIntegerClientRule.Operator.EQUAL, value=123) client_id = self.SetupClient(0) with self.assertRaises(ValueError): r.Evaluate(aff4.FACTORY.Open(client_id, token=self.token))
def testRuleAdding(self): foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) # Make sure there are no rules yet in the foreman. self.assertEqual(len(rules), 0) client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.REGEX, regex=foreman_rules.ForemanRegexClientRule( field="CLIENT_NAME", attribute_regex="HUNT")), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="CLIENT_CLOCK", operator=foreman_rules.ForemanIntegerClientRule.Operator. GREATER_THAN, value=1336650631137737)) ]) hunt = implementation.GRRHunt.StartHunt( hunt_name=standard.SampleHunt.__name__, client_rule_set=client_rule_set, client_rate=0, token=self.token) # Push the rules to the foreman. with hunt: hunt.GetRunner().Start() foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) # Make sure they were written correctly. self.assertEqual(len(rules), 1) rule = rules[0] self.assertEqual(rule.client_rule_set, client_rule_set) self.assertEqual(len(rule.actions), 1) self.assertEqual(rule.actions[0].hunt_name, "SampleHunt") # Running a second time should not change the rules any more. with hunt: hunt.GetRunner().Start() foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) # Still just one rule. self.assertEqual(len(rules), 1)
def testEvaluatesRaisesWithUnsetField(self): r = foreman_rules.ForemanIntegerClientRule( operator=foreman_rules.ForemanIntegerClientRule.Operator.EQUAL, value=123) client = self.SetupTestClientObject(0) info = data_store.REL_DB.ReadClientFullInfo(client.client_id) with self.assertRaises(ValueError): r.Evaluate(info)
def testEvaluatesSizeLessThanEqualValueToFalse(self): now = rdfvalue.RDFDatetime().Now() client = self.SetupTestClientObject(0, last_boot_time=now) info = data_store.REL_DB.ReadClientFullInfo(client.client_id) r = foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator.LESS_THAN, value=now.AsSecondsSinceEpoch()) # The values are the same, less than should not trigger. self.assertFalse(r.Evaluate(info))
def testEvaluatesSizeLessThanEqualValueToFalse(self): now = rdfvalue.RDFDatetime().Now() client_id = self.SetupClient(0, last_boot_time=now) client = aff4.FACTORY.Open(client_id, mode="rw", token=self.token) r = foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator.LESS_THAN, value=now.AsSecondsSinceEpoch()) # The values are the same, less than should not trigger. self.assertFalse(r.Evaluate(client))
def testEvaluatesSizeGreaterThanSmallerValueToTrue(self): now = rdfvalue.RDFDatetime().Now() client = self.SetupTestClientObject(0, last_boot_time=now) info = data_store.REL_DB.ReadClientFullInfo(client.client_id) before_boot = now - 1 r = foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator.GREATER_THAN, value=before_boot.AsSecondsSinceEpoch()) self.assertTrue(r.Evaluate(info))
def testEvaluatesSizeGreaterThanSmallerValueToTrue(self): now = rdfvalue.RDFDatetime().Now() client_id = self.SetupClient(0, last_boot_time=now) client = aff4.FACTORY.Open(client_id, mode="rw", token=self.token) before_boot = now - 1 r = foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator.GREATER_THAN, value=before_boot.AsSecondsSinceEpoch()) self.assertTrue(r.Evaluate(client))
def testEvaluation(self): now = rdfvalue.RDFDatetime().Now() client = self.SetupTestClientObject(0, last_boot_time=now) info = data_store.REL_DB.ReadClientFullInfo(client.client_id) int_f = foreman_rules.ForemanIntegerClientRule.ForemanIntegerField for f in int_f.enum_dict: if f == "UNSET": continue r = foreman_rules.ForemanIntegerClientRule( field=f, operator=foreman_rules.ForemanIntegerClientRule.Operator.LESS_THAN, value=now.AsSecondsSinceEpoch()) r.Evaluate(info)
def _GetTestRule(self, hunt_id="H:123456", expires=None): now = rdfvalue.RDFDatetime.Now() expiration_time = expires or now + rdfvalue.Duration("2w") rule = foreman_rules.ForemanCondition(creation_time=now, expiration_time=expiration_time, description="Test rule", hunt_id=hunt_id) rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator. LESS_THAN, value=now)) ]) return rule
def testIntegerComparisons(self): """Tests that we can use integer matching rules on the foreman.""" base_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336480583.077736) boot_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336300000.000000) self.SetupClient(0x11, system="Windows XP", install_time=base_time) self.SetupClient(0x12, system="Windows 7", install_time=base_time) # This one was installed one week earlier. one_week_ago = base_time - rdfvalue.Duration("1w") self.SetupClient(0x13, system="Windows 7", install_time=one_week_ago) self.SetupClient(0x14, system="Windows 7", last_boot_time=boot_time) with utils.Stubber(flow.GRRFlow, "StartFlow", 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(old)") # Matches the old client one_hour_ago = base_time - rdfvalue.Duration("1h") rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.LESS_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) old_flow = "Test flow for old clients" # Will run Test Flow rule.actions.Append(flow_name=old_flow, argv=rdf_protodict.Dict(dict(foo="bar"))) # Clear the rule set and add the new rule to it. rule_set = foreman_obj.Schema.RULES() rule_set.Append(rule) # Make a new rule rule = foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule(new)") # Matches the newer clients rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.GREATER_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) new_flow = "Test flow for newer clients" # Will run Test Flow rule.actions.Append(flow_name=new_flow, argv=rdf_protodict.Dict(dict(foo="bar"))) rule_set.Append(rule) # Make a new rule rule = foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule(eq)") # Note that this also tests the handling of nonexistent attributes. rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator="EQUAL", value=boot_time.AsSecondsSinceEpoch())) ]) eq_flow = "Test flow for LAST_BOOT_TIME" rule.actions.Append(flow_name=eq_flow, argv=rdf_protodict.Dict(dict(foo="bar"))) 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("C.1000000000000011") foreman_obj.AssignTasksToClient("C.1000000000000012") foreman_obj.AssignTasksToClient("C.1000000000000013") foreman_obj.AssignTasksToClient("C.1000000000000014") # Make sure that the clients ran the correct flows. self.assertEqual(len(self.clients_launched), 4) self.assertEqual(self.clients_launched[0][0], rdf_client.ClientURN("C.1000000000000011")) self.assertEqual(self.clients_launched[0][1], new_flow) self.assertEqual(self.clients_launched[1][0], rdf_client.ClientURN("C.1000000000000012")) self.assertEqual(self.clients_launched[1][1], new_flow) self.assertEqual(self.clients_launched[2][0], rdf_client.ClientURN("C.1000000000000013")) self.assertEqual(self.clients_launched[2][1], old_flow) self.assertEqual(self.clients_launched[3][0], rdf_client.ClientURN("C.1000000000000014")) self.assertEqual(self.clients_launched[3][1], eq_flow)
def testIntegerComparisons(self): """Tests that we can use integer matching rules on the foreman.""" base_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336480583.077736) boot_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336300000.000000) self.SetupTestClientObject(0x11, system="Windows XP", install_time=base_time) self.SetupTestClientObject(0x12, system="Windows 7", install_time=base_time) # This one was installed one week earlier. one_week_ago = base_time - rdfvalue.Duration("1w") self.SetupTestClientObject(0x13, system="Windows 7", install_time=one_week_ago) self.SetupTestClientObject(0x14, system="Windows 7", last_boot_time=boot_time) with utils.Stubber(implementation.GRRHunt, "StartClients", self.StartClients): 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(old)", hunt_name=standard.GenericHunt.__name__, hunt_id="H:111111") # Matches the old client one_hour_ago = base_time - rdfvalue.Duration("1h") rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.LESS_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule(new)", hunt_name=standard.GenericHunt.__name__, hunt_id="H:222222") # Matches the newer clients rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.GREATER_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule(eq)", hunt_name=standard.GenericHunt.__name__, hunt_id="H:333333") # Note that this also tests the handling of nonexistent attributes. rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator="EQUAL", value=boot_time.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) foreman_obj = foreman.GetForeman() self.clients_started = [] foreman_obj.AssignTasksToClient("C.1000000000000011") foreman_obj.AssignTasksToClient("C.1000000000000012") foreman_obj.AssignTasksToClient("C.1000000000000013") foreman_obj.AssignTasksToClient("C.1000000000000014") # Make sure that the clients ran the correct flows. self.assertEqual(len(self.clients_started), 4) self.assertEqual(self.clients_started[0][1], "C.1000000000000011") self.assertEqual("H:222222", self.clients_started[0][0].Basename()) self.assertEqual(self.clients_started[1][1], "C.1000000000000012") self.assertEqual("H:222222", self.clients_started[1][0].Basename()) self.assertEqual(self.clients_started[2][1], "C.1000000000000013") self.assertEqual("H:111111", self.clients_started[2][0].Basename()) self.assertEqual(self.clients_started[3][1], "C.1000000000000014") self.assertEqual("H:333333", self.clients_started[3][0].Basename())
def GenerateSample(self, number=0): # Sample rule matches clients with the attribute size equal to number return foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator.EQUAL, value=number)
def testStopping(self): """Tests if we can stop a hunt.""" foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) # Make sure there are no rules yet. self.assertEqual(len(rules), 0) now = rdfvalue.RDFDatetime.Now() expires = rdfvalue.Duration("1h").Expiry() # Add some rules. rules = [ foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule1"), foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule2") ] self.AddForemanRules(rules) client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.REGEX, regex=foreman_rules.ForemanRegexClientRule( field="CLIENT_NAME", attribute_regex="HUNT")), foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="CLIENT_CLOCK", operator=foreman_rules.ForemanIntegerClientRule.Operator. GREATER_THAN, value=1336650631137737)) ]) hunt = implementation.GRRHunt.StartHunt( hunt_name=standard.SampleHunt.__name__, client_rule_set=client_rule_set, client_rate=0, token=self.token) with hunt: runner = hunt.GetRunner() runner.Start() # Add some more rules. rules = [ foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule3"), foreman_rules.ForemanRule(created=now, expires=expires, description="Test rule4") ] self.AddForemanRules(rules) foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) self.assertEqual(len(rules), 5) # It should be running. self.assertTrue(runner.IsHuntStarted()) # Now we stop the hunt. hunt.Stop() foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) rules = foreman.Get(foreman.Schema.RULES) # The rule for this hunt should be deleted but the rest should be there. self.assertEqual(len(rules), 4) # And the hunt should report no outstanding requests any more. with hunt: self.assertFalse(hunt.GetRunner().IsHuntStarted())