def Start(self, add_foreman_rules=True): """This uploads the rules to the foreman and, thus, starts the hunt.""" # We are already running. if self.flow_obj.Get(self.flow_obj.Schema.STATE) == "STARTED": return # Check the permissions for the hunt here. Note that self.args.token is the # original creators's token, while the aff4 object was created with the # caller's token. This check therefore ensures that the caller to this # method has permissions to start the hunt (not necessarily the original # creator of the hunt). data_store.DB.security_manager.CheckHuntAccess(self.flow_obj.token, self.session_id) # Determine when this hunt will expire. self.context.expires = self.args.expiry_time.Expiry() # When the next client can be scheduled. Implements gradual client # recruitment rate according to the client_rate. self.context.next_client_due = rdfvalue.RDFDatetime().Now() self._CreateAuditEvent("HUNT_STARTED") # Start the hunt. self.flow_obj.Set(self.flow_obj.Schema.STATE("STARTED")) self.flow_obj.Flush() if not add_foreman_rules: return # Add a new rule to the foreman foreman_rule = rdfvalue.ForemanRule( created=rdfvalue.RDFDatetime().Now(), expires=self.context.expires, description="Hunt %s %s" % (self.session_id, self.args.hunt_name), regex_rules=self.args.regex_rules, integer_rules=self.args.integer_rules) foreman_rule.actions.Append(hunt_id=self.session_id, hunt_name=self.args.hunt_name, client_limit=self.args.client_limit) # Make sure the rule makes sense. foreman_rule.Validate() with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token, aff4_type="GRRForeman", ignore_cache=True) as foreman: foreman_rules = foreman.Get(foreman.Schema.RULES, default=foreman.Schema.RULES()) foreman_rules.Append(foreman_rule) foreman.Set(foreman_rules)
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 = [ rdfvalue.ForemanRule(created=now, expires=expires, description="Test rule1"), rdfvalue.ForemanRule(created=now, expires=expires, description="Test rule2") ] self.AddForemanRules(rules) hunt = hunts.GRRHunt.StartHunt( hunt_name="SampleHunt", regex_rules=[ rdfvalue.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="HUNT") ], integer_rules=[ rdfvalue.ForemanAttributeInteger( attribute_name="Clock", operator=rdfvalue.ForemanAttributeInteger.Operator. GREATER_THAN, value=1336650631137737) ], client_rate=0, token=self.token) with hunt: runner = hunt.GetRunner() runner.Start() # Add some more rules. rules = [ rdfvalue.ForemanRule(created=now, expires=expires, description="Test rule3"), rdfvalue.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())