def Parse(self, stat, knowledge_base): _ = stat, knowledge_base test_dict = { "environ_temp": rdfvalue.RDFString("tempvalue"), "environ_path": rdfvalue.RDFString("pathvalue") } yield rdf_protodict.Dict(test_dict)
def Run(self): hunt_urn = rdfvalue.RDFURN("aff4:/hunts/H:123456") results = implementation.GRRHunt.ResultCollectionForHID(hunt_urn) with data_store.DB.GetMutationPool() as pool: result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("blah1"), age=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1)) results.Add(result, timestamp=result.age + rdfvalue.Duration("1s"), mutation_pool=pool) result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("blah2-foo"), age=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(42)) results.Add(result, timestamp=result.age + rdfvalue.Duration("1s"), mutation_pool=pool) self.Check("ListHuntResults", args=hunt_plugin.ApiListHuntResultsArgs(hunt_id="H:123456")) self.Check("ListHuntResults", args=hunt_plugin.ApiListHuntResultsArgs(hunt_id="H:123456", count=1)) self.Check("ListHuntResults", args=hunt_plugin.ApiListHuntResultsArgs(hunt_id="H:123456", offset=1, count=1)) self.Check("ListHuntResults", args=hunt_plugin.ApiListHuntResultsArgs(hunt_id="H:123456", filter="foo"))
def testCorrectlyExportsFourValuesOfTwoDifferentTypes(self): with self.pool: self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo"), source=self.client_id), mutation_pool=self.pool) self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFInteger(42), source=self.client_id), mutation_pool=self.pool) self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("bar"), source=self.client_id), mutation_pool=self.pool) self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFInteger(43), source=self.client_id), mutation_pool=self.pool) chunks = self.ProcessPlugin() self.assertListEqual(chunks, [ "Start: aff4:/foo/bar", "Values of type: RDFInteger", "First pass: 42 (source=%s)" % self.client_id, "First pass: 43 (source=%s)" % self.client_id, "Second pass: 42 (source=%s)" % self.client_id, "Second pass: 43 (source=%s)" % self.client_id, "Values of type: RDFString", "First pass: foo (source=%s)" % self.client_id, "First pass: bar (source=%s)" % self.client_id, "Second pass: foo (source=%s)" % self.client_id, "Second pass: bar (source=%s)" % self.client_id, "Finish: aff4:/foo/bar" ]) # pyformat: disable
def testFlowStoresResultsPerType(self): flow_urn = flow_test_lib.TestFlowHelper( FlowWithMultipleResultTypes.__name__, action_mocks.ActionMock(), token=self.token, client_id=self.client_id) c = flow.GRRFlow.TypedResultCollectionForFID(flow_urn) self.assertEqual( set(c.ListStoredTypes()), set([ rdfvalue.RDFInteger.__name__, rdfvalue.RDFString.__name__, rdfvalue.RDFURN.__name__ ])) self.assertEqual(c.LengthByType(rdfvalue.RDFInteger.__name__), 1) self.assertEqual(c.LengthByType(rdfvalue.RDFString.__name__), 2) self.assertEqual(c.LengthByType(rdfvalue.RDFURN.__name__), 3) self.assertListEqual( [v.payload for _, v in c.ScanByType(rdfvalue.RDFInteger.__name__)], [rdfvalue.RDFInteger(42)]) self.assertListEqual( [v.payload for _, v in c.ScanByType(rdfvalue.RDFString.__name__)], [rdfvalue.RDFString("foo bar"), rdfvalue.RDFString("foo1 bar1")]) self.assertListEqual( [v.payload for _, v in c.ScanByType(rdfvalue.RDFURN.__name__)], [ rdfvalue.RDFURN("foo/bar"), rdfvalue.RDFURN("foo1/bar1"), rdfvalue.RDFURN("foo2/bar2") ])
def End(self, responses): self.SendReply(rdfvalue.RDFInteger(42)) self.SendReply(rdfvalue.RDFString("foo bar")) self.SendReply(rdfvalue.RDFString("foo1 bar1")) self.SendReply(rdfvalue.RDFURN("aff4:/foo/bar")) self.SendReply(rdfvalue.RDFURN("aff4:/foo1/bar1")) self.SendReply(rdfvalue.RDFURN("aff4:/foo2/bar2"))
def testResultsViewGetsAutoRefreshed(self): client_id = self.SetupClient(0) h = self.CreateSampleHunt() with data_store.DB.GetMutationPool() as pool: h.ResultCollection().Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo-result"), source=client_id), mutation_pool=pool) self.Open("/") # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.core.resultsCollectionDirective.setAutoRefreshInterval(1000);" ) self.Click("css=a[grrtarget=hunts]") self.Click("css=td:contains('GenericHunt')") self.Click("css=li[heading=Results]") self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('foo-result')") self.WaitUntilNot( self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')") with data_store.DB.GetMutationPool() as pool: h.ResultCollection().Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("bar-result"), source=client_id), mutation_pool=pool) self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')")
def testFlowResultsTabGetsUpdatedWhenNewResultsAreAdded(self): f = flow.GRRFlow.StartFlow( client_id=self.client_id, flow_name=gui_test_lib.RecursiveTestFlow.__name__, token=self.token) with data_store.DB.GetMutationPool() as pool: flow.GRRFlow.ResultCollectionForFID(f).Add( rdfvalue.RDFString("foo-result"), mutation_pool=pool) self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.core.resultsCollectionDirective.setAutoRefreshInterval(1000);" ) # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset. self.Click("css=a[grrtarget='client.flows']") self.Click("css=tr:contains('%s')" % f.Basename()) self.Click("css=li[heading=Results]:not([disabled]") self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('foo-result')") self.WaitUntilNot( self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')") with data_store.DB.GetMutationPool() as pool: flow.GRRFlow.ResultCollectionForFID(f).Add( rdfvalue.RDFString("bar-result"), mutation_pool=pool) self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')")
def Parse(self, stat, knowledge_base): """Convert the timezone to Olson format.""" _ = knowledge_base value = stat.registry_data.GetValue() result = ZONE_LIST.get(value.strip()) if not result: yield rdfvalue.RDFString("Unknown (%s)" % value.strip()) yield rdfvalue.RDFString(result)
def testArray(self): sample = rdf_protodict.RDFValueArray() # Add a string. sample.Append("hello") self.assertEqual(len(sample), 1) self.assertEqual(sample[0], "hello") # Add another RDFValue sample.Append(rdfvalue.RDFString("hello")) self.assertIsInstance(sample[1], rdfvalue.RDFString) # Test iterator. sample_list = list(sample) self.assertIsInstance(sample_list, list) self.assertIsInstance(sample_list[0], str) self.assertIsInstance(sample_list[1], rdfvalue.RDFString) # Test initialization from a list of variable types. test_list = [ 1, 2, # Integers. None, # None. rdfvalue.RDFDatetime.Now(), # An RDFValue instance. [1, 2], # A nested list. u"升级程序", # Unicode. ] sample = rdf_protodict.RDFValueArray(test_list) for x, y in zip(sample, test_list): self.assertEqual(x.__class__, y.__class__) self.assertEqual(x, y)
def testRepr(self): """Test RDFValue.__repr__.""" self.assertEqual(repr(rdfvalue.RDFBool(True)), "<RDFBool('1')>") self.assertEqual( repr(rdfvalue.RDFString(long_string)), "<RDFString('\\xe8\\xbf\\x8e\\xe6\\xac\\xa2\\xe8\\xbf\\x8e\\nLorem " "ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus ex " "sed dictum volutp...')>")
def Parse(self, stat, knowledge_base): value = stat.registry_data.GetValue() if not value: # Provide a default, if the registry value is not available. value = "%SystemDrive%\\Documents and Settings" interpolated_value = artifact_utils.ExpandWindowsEnvironmentVariables( value, knowledge_base) yield rdfvalue.RDFString(interpolated_value)
def Parse(self, stat, knowledge_base): """Expand any variables in the value.""" value = stat.registry_data.GetValue() if not value: raise parser.ParseError("Invalid value for key %s" % stat.pathspec.path) value = artifact_utils.ExpandWindowsEnvironmentVariables( value, knowledge_base) if value: yield rdfvalue.RDFString(value)
def testValuesOfMultipleTypesCanBeIteratedTogether(self): with self.pool: original_values = set() for i in range(100): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) original_values.add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i))) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) original_values.add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i))) self.assertEqual(sorted([v.payload for v in original_values]), sorted([v.payload for v in self.collection]))
def Parse(self, stat, unused_knowledge_base): """Parse the key currentcontrolset output.""" value = stat.registry_data.GetValue() if not str(value).isdigit() or int(value) > 999 or int(value) < 0: raise parser.ParseError( "Invalid value for CurrentControlSet key %s" % value) yield rdfvalue.RDFString( "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet%03d" % int(value))
def ReceiveHello(self, responses): if responses.First() != "Hello": raise RuntimeError("Did not receive hello.") DelayedCallStateFlow.flow_ran = 1 # Call the child flow. self.CallState([rdfvalue.RDFString("Hello")], next_state="DelayedHello", start_time=rdfvalue.RDFDatetime.Now() + 100)
def testAddGet(self): collection = sequential_collection.GeneralIndexedCollection( rdfvalue.RDFURN("aff4:/sequential_collection/testAddGetIndexed")) with data_store.DB.GetMutationPool() as pool: collection.Add(rdfvalue.RDFInteger(42), mutation_pool=pool) collection.Add(rdfvalue.RDFString("the meaning of life"), mutation_pool=pool) self.assertEqual(collection[0].__class__, rdfvalue.RDFInteger) self.assertEqual(collection[0], 42) self.assertEqual(collection[1].__class__, rdfvalue.RDFString) self.assertEqual(collection[1], "the meaning of life")
def testLengthOfCollectionIsCorrectWhenMultipleTypesAreUsed(self): with self.pool: for i in range(100): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) self.assertEqual(200, len(self.collection))
def testDynamicAnyValueTypeWithPrimitiveValues(self): test_pb = DynamicAnyValueTypeTest(type="RDFString") # We can not assign arbitrary values to the dynamic field. self.assertRaises(ValueError, setattr, test_pb, "dynamic", 42) # Can assign a nested field. test_pb.dynamic = rdfvalue.RDFString("Hello") self.assertTrue(isinstance(test_pb.dynamic, rdfvalue.RDFString)) # Test serialization/deserialization. serialized = test_pb.SerializeToString() unserialized = DynamicAnyValueTypeTest.FromSerializedString(serialized) self.assertEqual(unserialized, test_pb) self.assertEqual(unserialized.dynamic, "Hello")
def Parse(self, stat, _): """Parses a SystemDrive environment variable.""" if isinstance(stat, rdf_client.StatEntry): value = stat.registry_data.GetValue() elif isinstance(stat, rdfvalue.RDFString): value = stat if not value: raise parser.ParseError("Invalid value for key %s" % stat.pathspec.path) systemdrive = value[0:2] if re.match(r"^[A-Za-z]:$", systemdrive): yield rdfvalue.RDFString(systemdrive) else: raise parser.ParseError( "Bad drive letter for key %s" % stat.pathspec.path)
def testUsesDefaultClientURNIfGrrMessageHasNoSource(self): with self.pool: self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo"), source=None), mutation_pool=self.pool) chunks = self.ProcessPlugin( source_urn=rdf_client.ClientURN("C.1111222233334444")) self.assertListEqual(chunks, [ "Start: aff4:/foo/bar", "Values of type: RDFString", "First pass: foo (source=aff4:/C.1111222233334444)", "Second pass: foo (source=aff4:/C.1111222233334444)", "Finish: aff4:/foo/bar" ]) # pyformat: disable
def testClientSummaryModalIsShownWhenClientInfoButtonClicked(self): client_id = self.SetupClient(0) h = self.CreateSampleHunt() with data_store.DB.GetMutationPool() as pool: h.ResultCollection().Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo-result"), source=client_id), mutation_pool=pool) self.Open("/#/hunts/%s/results" % h.urn.Basename()) self.Click("css=td:contains('%s') button:has(.glyphicon-info-sign)" % client_id.Basename()) self.WaitUntil( self.IsElementPresent, "css=.modal-dialog:contains('Client %s')" % client_id.Basename())
def testLengthIsReportedCorrectlyForEveryType(self): with self.pool: for i in range(99): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) for i in range(101): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) self.assertEqual( 99, self.collection.LengthByType(rdfvalue.RDFInteger.__name__)) self.assertEqual( 101, self.collection.LengthByType(rdfvalue.RDFString.__name__))
def testValuesOfMultipleTypesCanBeIteratedPerType(self): with self.pool: for i in range(100): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) for index, (_, v) in enumerate( self.collection.ScanByType(rdfvalue.RDFInteger.__name__)): self.assertEqual(index, v.payload) for index, (_, v) in enumerate( self.collection.ScanByType(rdfvalue.RDFString.__name__)): self.assertEqual(str(index), v.payload)
def testExtractsTypesFromGrrMessage(self): with self.pool: self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(0)), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo")), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFURN("aff4:/foo/bar")), mutation_pool=self.pool) self.assertEqual( set([ rdfvalue.RDFInteger.__name__, rdfvalue.RDFString.__name__, rdfvalue.RDFURN.__name__ ]), set(self.collection.ListStoredTypes()))
def _FillInStubResults(self): results = implementation.GRRHunt.ResultCollectionForHID( self.hunt.urn, token=self.token) result = results[0] with data_store.DB.GetMutationPool() as pool: for i in range(self.handler.MAX_RECORDS_TO_CHECK): wrong_result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo/bar"), age=(result.age - (self.handler.MAX_RECORDS_TO_CHECK - i + 1) * rdfvalue.Duration("1s")), source=self.client_id) results.Add(wrong_result, timestamp=wrong_result.age, mutation_pool=pool) return result
def testDeletingCollectionDeletesAllSubcollections(self): if not isinstance(data_store.DB, fake_data_store.FakeDataStore): self.skipTest("Only supported on FakeDataStore.") with self.pool: self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(0)), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo")), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFURN("aff4:/foo/bar")), mutation_pool=self.pool) self.collection.Delete() for urn in data_store.DB.subjects.keys(): self.assertFalse( utils.SmartStr(self.collection.collection_id) in urn)
def ParseFiles(self, responses): """Take each file we retrieved and get the history from it.""" if responses: for response in responses: fd = aff4.FACTORY.Open(response.stat_entry.AFF4Path( self.client_id), token=self.token) hist = firefox3_history.Firefox3History(fd) count = 0 for epoch64, dtype, url, dat1, in hist.Parse(): count += 1 str_entry = "%s %s %s %s" % ( datetime.datetime.utcfromtimestamp( epoch64 / 1e6), url, dat1, dtype) self.SendReply( rdfvalue.RDFString(utils.SmartStr(str_entry))) self.Log( "Wrote %d Firefox History entries for user %s from %s", count, self.args.username, response.stat_entry.pathspec.Basename()) self.state.hist_count += count
def testSimpleTypeAssignment(self): sample = rdf_client.StatEntry() sample.AddDescriptor( rdf_structs.ProtoRDFValue(name="test", field_number=45, default=rdfvalue.RDFInteger(0), rdf_type=rdfvalue.RDFInteger)) self.assertIsInstance(sample.test, rdfvalue.RDFInteger) # Can we assign an RDFValue instance? sample.test = rdfvalue.RDFInteger(5) self.assertEqual(sample.test, 5) # Check that bare values can be coerced. sample.test = 6 self.assertIsInstance(sample.test, rdfvalue.RDFInteger) self.assertEqual(sample.test, 6) # Assign an enum. sample.registry_type = sample.RegistryType.REG_DWORD self.assertEqual(sample.registry_type, sample.RegistryType.REG_DWORD) sample.registry_type = rdf_client.StatEntry.RegistryType.REG_SZ self.assertEqual(sample.registry_type, sample.RegistryType.REG_SZ) # We can also assign the string value. sample.registry_type = "REG_QWORD" self.assertEqual(sample.registry_type, sample.RegistryType.REG_QWORD) # Check that coercing works. sample.test = "10" self.assertEqual(sample.test, 10) # Assign an RDFValue which can not be coerced. self.assertRaises(type_info.TypeValueError, setattr, sample, "test", rdfvalue.RDFString("hello"))
def InitFromKeyValue(self, key, value): self.key = key # Convert primitive types to rdf values so they can be serialized. if isinstance(value, float) and not value.is_integer(): # TODO(user): Do not convert float values here and mark them invalid # later. ATM, we do not have means to properly represent floats. Change # this part once we have a RDFFloat implementation. pass elif rdfvalue.RDFInteger.IsNumeric(value): value = rdfvalue.RDFInteger(value) elif isinstance(value, basestring): value = rdfvalue.RDFString(value) elif isinstance(value, bool): value = rdfvalue.RDFBool(value) if isinstance(value, rdfvalue.RDFValue): self.type = value.__class__.__name__ self.value = value else: self.invalid = True return self
def ParseFiles(self, responses): """Take each file we retrieved and get the history from it.""" # Note that some of these Find requests will fail because some paths don't # exist, e.g. Chromium on most machines, so we don't check for success. if responses: for response in responses: fd = aff4.FACTORY.Open(response.stat_entry.AFF4Path( self.client_id), token=self.token) hist = chrome_history.ChromeParser(fd) count = 0 for epoch64, dtype, url, dat1, dat2, dat3 in hist.Parse(): count += 1 str_entry = "%s %s %s %s %s %s" % ( datetime.datetime.utcfromtimestamp( epoch64 / 1e6), url, dat1, dat2, dat3, dtype) self.SendReply( rdfvalue.RDFString(utils.SmartStr(str_entry))) self.Log("Wrote %d Chrome History entries for user %s from %s", count, self.args.username, response.stat_entry.pathspec.Basename()) self.state.hist_count += count