def Start(self): """Retrieve all the clients for the AbstractClientStatsCollectors.""" try: self.stats = {} self.BeginProcessing() if data_store.RelationalDBReadEnabled(): clients = self._IterateClients() else: clients = self._IterateLegacyClients() processed_count = 0 for c in clients: if data_store.RelationalDBReadEnabled(): self.ProcessClientFullInfo(c) else: self.ProcessLegacyClient(c) processed_count += 1 # This flow is not dead: we don't want to run out of lease time. self.HeartBeat() self.FinishProcessing() for fd in self.stats.values(): fd.Close() logging.info("%s: processed %d clients.", self.__class__.__name__, processed_count) except Exception as e: # pylint: disable=broad-except logging.exception("Error while calculating stats: %s", e) raise
def setUp(self): super(GRRSeleniumTest, self).setUp() # Used by InstallACLChecks/UninstallACLChecks self.config_override = None self.token.username = "******" webauth.WEBAUTH_MANAGER.SetUserName(self.token.username) # Make the user use the advanced gui so we can test it. with aff4.FACTORY.Create( aff4.ROOT_URN.Add("users/%s" % self.token.username), aff4_type=users.GRRUser, mode="w", token=self.token) as user_fd: user_fd.Set(user_fd.Schema.GUI_SETTINGS(mode="ADVANCED")) if data_store.RelationalDBReadEnabled(): data_store.REL_DB.WriteGRRUser( self.token.username, ui_mode=users.GUISettings.UIMode.ADVANCED) self._artifact_patcher = artifact_test_lib.PatchDefaultArtifactRegistry() self._artifact_patcher.start() self.InstallACLChecks()
def setUp(self): super(ApprovalByLabelE2ETest, self).setUp() self.SetUpLegacy() if data_store.RelationalDBReadEnabled(): self.SetUpRelationalDB() cls = (api_call_router_with_approval_checks.ApiCallRouterWithApprovalChecks) cls.ClearCache() self.approver = test_lib.ConfigOverrider({ "API.DefaultRouter": cls.__name__, "ACL.approvers_config_file": os.path.join(self.base_path, "approvers.yaml") }) self.approver.Start() # Get a fresh approval manager object and reload with test approvers. self.approval_manager_stubber = utils.Stubber( client_approval_auth, "CLIENT_APPROVAL_AUTH_MGR", client_approval_auth.ClientApprovalAuthorizationManager()) self.approval_manager_stubber.Start() # Force creation of new APIAuthorizationManager, so that configuration # changes are picked up. api_auth_manager.APIACLInit.InitApiAuthManager()
def Handle(self, args, token=None): end = args.count or sys.maxsize keywords = shlex.split(args.query) api_clients = [] if data_store.RelationalDBReadEnabled(): index = client_index.ClientIndex() clients = sorted( index.LookupClients(keywords))[args.offset:args.offset + end] client_infos = data_store.REL_DB.MultiReadClientFullInfo(clients) for client_info in client_infos.itervalues(): api_clients.append(ApiClient().InitFromClientInfo(client_info)) else: index = client_index.CreateClientIndex(token=token) result_urns = sorted( index.LookupClients(keywords))[args.offset:args.offset + end] result_set = aff4.FACTORY.MultiOpen(result_urns, token=token) for child in sorted(result_set): api_clients.append(ApiClient().InitFromAff4Object(child)) UpdateClientsFromFleetspeak(api_clients) return ApiSearchClientsResult(items=api_clients)
def _SetupTestClient(self): if data_store.RelationalDBReadEnabled(): with test_lib.FakeTime(42): client_obj = self.SetupTestClientObject( 0, memory_size=4294967296, add_cert=False) client_id = client_obj.client_id with test_lib.FakeTime(45): self.SetupTestClientObject( 0, fqdn="some-other-hostname.org", memory_size=4294967296, add_cert=False) else: # We need AFF4 data. with test_lib.FakeTime(42): client_urn = self.SetupClient(0, memory_size=4294967296, add_cert=False) client_id = client_urn.Basename() with test_lib.FakeTime(45): with aff4.FACTORY.Open( client_urn, mode="rw", token=self.token) as grr_client: grr_client.Set(grr_client.Schema.HOSTNAME("some-other-hostname.org")) grr_client.Set(grr_client.Schema.FQDN("some-other-hostname.org")) kb = grr_client.Get(grr_client.Schema.KNOWLEDGE_BASE) kb.fqdn = "some-other-hostname.org" grr_client.Set(grr_client.Schema.KNOWLEDGE_BASE(kb)) return client_id
def _ProcessMessageHandlerRequests(self): """Processes message handler requests.""" if not data_store.RelationalDBReadEnabled(category="message_handlers"): return 0 if time.time() - self.last_mh_lease_attempt < self.MH_LEASE_INTERVAL: return 0 requests = data_store.REL_DB.LeaseMessageHandlerRequests( lease_time=self.well_known_flow_lease_time, limit=1000) if not requests: return 0 logging.debug("Leased message handler request ids: %s", ",".join( str(r.request_id) for r in requests)) grouped_requests = utils.GroupBy(requests, lambda r: r.handler_name) for handler_name, requests_for_handler in grouped_requests.items(): handler_cls = handler_registry.handler_name_map.get(handler_name) if not handler_cls: logging.error("Unknown message handler: %s", handler_name) continue try: logging.debug("Running %d messages for handler %s", len(requests_for_handler), handler_name) handler_cls(token=self.token).ProcessMessages(requests_for_handler) except Exception: # pylint: disable=broad-except logging.exception("Exception while processing message handler %s", handler_name) logging.debug("Deleting message handler request ids: %s", ",".join( str(r.request_id) for r in requests)) data_store.REL_DB.DeleteMessageHandlerRequests(requests) return len(requests)
def testHandlerRespectsTimestamp(self): # TODO(hanuszczak): Enable this test in relational database mode once # timestamp-specific file listing is supported by the data store. if data_store.RelationalDBReadEnabled(): raise unittest.SkipTest( "relational backend does not support timestamp-" "specific file listing") # file_path is "fs/os/etc", a directory. self.CreateFileVersions(self.client_id, self.file_path + "/file") args = vfs_plugin.ApiListFilesArgs(client_id=self.client_id, file_path=self.file_path, timestamp=self.time_2) result = self.handler.Handle(args, token=self.token) self.assertEqual(len(result.items), 1) self.assertEqual(result.items[0].last_collected_size, 13) args = vfs_plugin.ApiListFilesArgs(client_id=self.client_id, file_path=self.file_path, timestamp=self.time_1) result = self.handler.Handle(args, token=self.token) self.assertEqual(len(result.items), 1) self.assertEqual(result.items[0].last_collected_size, 11) args = vfs_plugin.ApiListFilesArgs(client_id=self.client_id, file_path=self.file_path, timestamp=self.time_0) result = self.handler.Handle(args, token=self.token) self.assertEqual(len(result.items), 0)
def Run(self): with test_lib.FakeTime(42): hunt_urn = self.StartHunt(description="the hunt") if data_store.RelationalDBReadEnabled(): clients = self.SetupTestClientObjects(5) client_ids = sorted(clients) else: client_ids = [urn.Basename() for urn in self.SetupClients(5)] self.AssignTasksToClients(client_ids=client_ids) # Only running the hunt on a single client, as SampleMock # implementation is non-deterministic in terms of resources # usage that gets reported back to the hunt. client_urns = [rdf_client.ClientURN(client_ids[-1])] self.RunHunt(client_ids=client_urns, failrate=0) # Create replace dictionary. replace = {hunt_urn.Basename(): "H:123456"} self.Check("ListHuntClients", args=hunt_plugin.ApiListHuntClientsArgs( hunt_id=hunt_urn.Basename(), client_status="STARTED"), replace=replace) self.Check("ListHuntClients", args=hunt_plugin.ApiListHuntClientsArgs( hunt_id=hunt_urn.Basename(), client_status="OUTSTANDING"), replace=replace) self.Check("ListHuntClients", args=hunt_plugin.ApiListHuntClientsArgs( hunt_id=hunt_urn.Basename(), client_status="COMPLETED"), replace=replace)
def Handle(self, args, token=None): end_time = args.end or rdfvalue.RDFDatetime.Now() start_time = args.start or end_time - rdfvalue.Duration("3m") diffs_only = args.mode == args.Mode.DIFF items = [] if data_store.RelationalDBReadEnabled(): history = data_store.REL_DB.ReadClientSnapshotHistory( str(args.client_id), timerange=(start_time, end_time)) for client in history[::-1]: items.append(ApiClient().InitFromClientObject(client)) else: all_clients = aff4.FACTORY.OpenDiscreteVersions( args.client_id.ToClientURN(), mode="r", age=(start_time.AsMicrosecondsSinceEpoch(), end_time.AsMicrosecondsSinceEpoch()), diffs_only=diffs_only, token=token) for fd in all_clients: items.append(ApiClient().InitFromAff4Object( fd, include_metadata=False)) return ApiGetClientVersionsResult(items=items)
def Handle(self, args, token=None): if data_store.RelationalDBReadEnabled(): md = data_store.REL_DB.ReadClientMetadata(str(args.client_id)) if md.fleetspeak_enabled: ip_str, ipaddr_obj = _GetAddrFromFleetspeak(args.client_id) else: try: ipaddr_obj = md.ip.AsIPAddr() ip_str = str(ipaddr_obj) except ValueError: ipaddr_obj = None ip_str = "" else: client = aff4.FACTORY.Open(args.client_id.ToClientURN(), aff4_type=aff4_grr.VFSGRRClient, token=token) if client.Get(client.Schema.FLEETSPEAK_ENABLED): ip_str, ipaddr_obj = _GetAddrFromFleetspeak(args.client_id) else: ip_str = client.Get(client.Schema.CLIENT_IP) if ip_str: ipaddr_obj = ipaddr.IPAddress(ip_str) else: ipaddr_obj = None status, info = ip_resolver.IP_RESOLVER.RetrieveIPInfo(ipaddr_obj) return ApiGetLastClientIPAddressResult(ip=ip_str, info=info, status=status)
def Run(self): if data_store.RelationalDBReadEnabled(): clients = self.SetupTestClientObjects(10) client_ids = sorted(clients) else: client_ids = [urn.Basename() for urn in self.SetupClients(10)] client_mock = hunt_test_lib.SampleHuntMock() with test_lib.FakeTime(42): with self.CreateHunt(description="the hunt") as hunt_obj: hunt_obj.Run() time_offset = 0 for client_id in client_ids: with test_lib.FakeTime(45 + time_offset): self.AssignTasksToClients([client_id]) hunt_test_lib.TestHuntHelper(client_mock, [rdf_client.ClientURN(client_id)], False, self.token) time_offset += 10 replace = {hunt_obj.urn.Basename(): "H:123456"} self.Check("GetHuntClientCompletionStats", args=hunt_plugin.ApiGetHuntClientCompletionStatsArgs( hunt_id=hunt_obj.urn.Basename()), replace=replace) self.Check("GetHuntClientCompletionStats", args=hunt_plugin.ApiGetHuntClientCompletionStatsArgs( hunt_id=hunt_obj.urn.Basename(), size=4), replace=replace) self.Check("GetHuntClientCompletionStats", args=hunt_plugin.ApiGetHuntClientCompletionStatsArgs( hunt_id=hunt_obj.urn.Basename(), size=1000), replace=replace)
def Handle(self, args, token=None): if not args.timestamp: age = rdfvalue.RDFDatetime.Now() else: age = rdfvalue.RDFDatetime(args.timestamp) api_client = None if data_store.RelationalDBReadEnabled(): info = data_store.REL_DB.ReadClientFullInfo(str(args.client_id)) if info is None: raise api_call_handler_base.ResourceNotFoundError() if args.timestamp: # Assume that a snapshot for this particular timestamp exists. snapshots = data_store.REL_DB.ReadClientSnapshotHistory( str(args.client_id), timerange=(args.timestamp, args.timestamp)) if snapshots: info.last_snapshot = snapshots[0] info.last_startup_info = snapshots[0].startup_info api_client = ApiClient().InitFromClientInfo(info) else: client = aff4.FACTORY.Open(args.client_id.ToClientURN(), aff4_type=aff4_grr.VFSGRRClient, age=age, token=token) api_client = ApiClient().InitFromAff4Object(client) UpdateClientsFromFleetspeak([api_client]) return api_client
def _ProcessMessageHandlerRequests(self): """Processes message handler requests.""" if not data_store.RelationalDBReadEnabled(category="message_handlers"): return 0 requests = data_store.REL_DB.LeaseMessageHandlerRequests( lease_time=self.well_known_flow_lease_time, limit=1000) if not requests: return 0 grouped_requests = utils.GroupBy(requests, lambda r: r.handler_name) for handler_name, requests in grouped_requests.items(): handler_cls = handler_registry.handler_name_map.get(handler_name) if not handler_cls: logging.error("Unknown message handler: %s", handler_name) continue try: handler_cls(token=self.token).ProcessMessages(requests) except Exception: # pylint: disable=broad-except logging.exception( "Exception while processing message handler %s", handler_name) data_store.REL_DB.DeleteMessageHandlerRequests(requests) return len(requests)
def End(self): """Finalize client registration.""" # Update summary and publish to the Discovery queue. if data_store.RelationalDBWriteEnabled(): try: data_store.REL_DB.WriteClientSnapshot(self.state.client) except db.UnknownClientError: pass client = self._OpenClient() if data_store.RelationalDBReadEnabled(): summary = self.state.client.GetSummary() summary.client_id = self.client_id summary.timestamp = rdfvalue.RDFDatetime.Now() else: summary = client.GetSummary() self.Publish("Discovery", summary) self.SendReply(summary) # Update the client index client_index.CreateClientIndex(token=self.token).AddClient(client) if data_store.RelationalDBWriteEnabled(): try: index = client_index.ClientIndex() index.AddClient(self.state.client) labels = self.state.client.startup_info.client_info.labels if labels: data_store.REL_DB.AddClientLabels(self.state.client.client_id, "GRR", labels) except db.UnknownClientError: # TODO(amoser): Remove after data migration. pass
def Flush(self): """Writes the changes in this object to the datastore.""" if data_store.RelationalDBReadEnabled(category="message_handlers"): message_handler_requests = [] leftover_responses = [] for r, timestamp in self.response_queue: if r.request_id == 0 and r.session_id in session_id_map: message_handler_requests.append( rdf_objects.MessageHandlerRequest( client_id=r.source and r.source.Basename(), handler_name=session_id_map[r.session_id], request_id=r.response_id, request=r.payload)) else: leftover_responses.append((r, timestamp)) if message_handler_requests: data_store.REL_DB.WriteMessageHandlerRequests( message_handler_requests) self.response_queue = leftover_responses self.data_store.StoreRequestsAndResponses( new_requests=self.request_queue, new_responses=self.response_queue, requests_to_delete=self.requests_to_delete) # We need to make sure that notifications are written after the requests so # we flush after writing all requests and only notify afterwards. mutation_pool = self.data_store.GetMutationPool() with mutation_pool: for client_id, messages in self.client_messages_to_delete.iteritems( ): self.Delete(client_id.Queue(), messages, mutation_pool=mutation_pool) if self.new_client_messages: for timestamp, messages in utils.GroupBy( self.new_client_messages, lambda x: x[1]).iteritems(): self.Schedule([x[0] for x in messages], timestamp=timestamp, mutation_pool=mutation_pool) if self.notifications: for notification in self.notifications.itervalues(): self.NotifyQueue(notification, mutation_pool=mutation_pool) mutation_pool.Flush() self.request_queue = [] self.response_queue = [] self.requests_to_delete = [] self.client_messages_to_delete = {} self.notifications = {} self.new_client_messages = []
def CreateUser(username): """Creates a user.""" if data_store.RelationalDBReadEnabled(): data_store.REL_DB.WriteGRRUser(username) user = aff4.FACTORY.Create("aff4:/users/%s" % username, users.GRRUser) user.Flush() return user
def ProcessMessage(self, message=None, event=None): """Handle a startup event.""" _ = event # We accept unauthenticated messages so there are no errors but we don't # store the results. if (message.auth_state != rdf_flows.GrrMessage.AuthorizationState.AUTHENTICATED): return client_id = message.source new_si = message.payload drift = rdfvalue.Duration("5m") if data_store.RelationalDBReadEnabled(): current_si = data_store.REL_DB.ReadClientStartupInfo( client_id.Basename()) # We write the updated record if the client_info has any changes # or the boot time is more than 5 minutes different. if (not current_si or current_si.client_info != new_si.client_info or not current_si.boot_time or abs(current_si.boot_time - new_si.boot_time) > drift): data_store.REL_DB.WriteClientStartupInfo( client_id.Basename(), new_si) else: changes = False with aff4.FACTORY.Create(client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token) as client: old_info = client.Get(client.Schema.CLIENT_INFO) old_boot = client.Get(client.Schema.LAST_BOOT_TIME, 0) info = new_si.client_info # Only write to the datastore if we have new information. if info != old_info: client.Set(client.Schema.CLIENT_INFO(info)) changes = True client.AddLabels(info.labels, owner="GRR") # Allow for some drift in the boot times (5 minutes). if not old_boot or abs(old_boot - new_si.boot_time) > drift: client.Set(client.Schema.LAST_BOOT_TIME(new_si.boot_time)) changes = True if data_store.RelationalDBWriteEnabled() and changes: try: data_store.REL_DB.WriteClientStartupInfo( client_id.Basename(), new_si) except db.UnknownClientError: pass events.Events.PublishEventInline("ClientStartup", message, token=self.token)
def CreateAdminUser(self, username): """Creates a user and makes it an admin.""" if data_store.RelationalDBReadEnabled(): data_store.REL_DB.WriteGRRUser( username, user_type=rdf_objects.GRRUser.UserType.USER_TYPE_ADMIN) with self.CreateUser(username) as user: user.SetLabel("admin", owner="GRR")
def FindForemanRules(hunt, token): if data_store.RelationalDBReadEnabled(category="foreman"): rules = data_store.REL_DB.ReadAllForemanRules() return [rule for rule in rules if rule.hunt_id == hunt.urn.Basename()] else: fman = aff4.FACTORY.Open( "aff4:/foreman", mode="r", aff4_type=aff4_grr.GRRForeman, token=token) rules = fman.Get(fman.Schema.RULES, []) return [rule for rule in rules if rule.hunt_id == hunt.urn]
def Handle(self, args, token=None): if data_store.RelationalDBReadEnabled(category="vfs"): return self._HandleRelational(args, token=token) path = args.file_path if not path: path = "/" # We allow querying root path ("/") to get a list of whitelisted # root entries. In all other cases we have to validate the path. if path != "/": ValidateVfsPath(args.file_path) if args.timestamp: age = args.timestamp else: age = aff4.NEWEST_TIME directory = aff4.FACTORY.Open(args.client_id.ToClientURN().Add(path), mode="r", token=token).Upgrade( aff4_standard.VFSDirectory) if args.directories_only: children = [ ch for ch in directory.OpenChildren(age=age) if "Container" in ch.behaviours ] else: children = [ch for ch in directory.OpenChildren(age=age)] # If we are reading the root file content, a whitelist applies. if path == "/": children = [ ch for ch in children if ch.urn.Basename() in ROOT_FILES_WHITELIST ] # Apply the filter. if args.filter: pattern = re.compile(args.filter, re.IGNORECASE) children = [ ch for ch in children if pattern.search(ch.urn.Basename()) ] # Apply sorting. # TODO(user): add sort attribute. children = sorted(children, key=lambda ch: ch.urn.Basename()) # Apply offset and count. if args.count: children = children[args.offset:args.offset + args.count] else: children = children[args.offset:] return ApiListFilesResult( items=[ApiFile().InitFromAff4Object(c) for c in children])
def GetUserNotifications(self, username): if data_store.RelationalDBReadEnabled(): return data_store.REL_DB.ReadUserNotifications(username) else: fd = aff4.FACTORY.Open( "aff4:/users/%s" % username, aff4_type=aff4_users.GRRUser, token=self.token) return fd.ShowNotifications(reset=False)
def Handle(self, args, token=None): ValidateVfsPath(args.file_path) if args.timestamp: age = args.timestamp else: age = aff4.ALL_TIMES file_obj = aff4.FACTORY.Open(args.client_id.ToClientURN().Add( args.file_path), mode="r", age=age, token=token) if data_store.RelationalDBReadEnabled(category="vfs"): # These are not really "files" so they cannot be stored in the database # but they still can be queried so we need to return something. Sometimes # they contain a trailing slash so we need to take care of that. # # TODO(hanuszczak): Require VFS paths to be normalized so that trailing # slash is either forbidden or mandatory. if args.file_path.endswith("/"): args.file_path = args.file_path[:-1] if args.file_path in ["fs", "registry", "temp", "fs/os", "fs/tsk"]: api_file = ApiFile() api_file.name = api_file.path = args.file_path api_file.is_directory = True return ApiGetFileDetailsResult(file=api_file) path_type, components = rdf_objects.ParseCategorizedPath( args.file_path) # TODO(hanuszczak): The tests passed even without support for timestamp # filtering. The test suite should be probably improved in that regard. path_id = rdf_objects.PathID(components) path_info = data_store.REL_DB.FindPathInfoByPathID( str(args.client_id), path_type, path_id, timestamp=args.timestamp) if path_info: stat_entry = path_info.stat_entry hash_entry = path_info.hash_entry else: stat_entry = rdf_client.StatEntry() hash_entry = rdf_crypto.Hash() else: stat_entry = None hash_entry = None return ApiGetFileDetailsResult( file=ApiFile().InitFromAff4Object(file_obj, stat_entry=stat_entry, hash_entry=hash_entry, with_details=True))
def GetClientOs(client_id, token=None): """Returns last known operating system name that the client used.""" if data_store.RelationalDBReadEnabled(): client_id = client_id.Basename() kb = data_store.REL_DB.ReadClientSnapshot(client_id).knowledge_base else: with aff4.FACTORY.Open(client_id, token=token) as client: kb = client.Get(client.Schema.KNOWLEDGE_BASE) return kb.os
def _GetAccessChecker(self): cls = ApiCallRouterWithApprovalChecks if cls.access_checker is None: if data_store.RelationalDBReadEnabled(): cls.access_checker = RelDBChecker() else: cls.access_checker = LegacyChecker() return cls.access_checker
def setUp(self): super(TestNewHuntWizard, self).setUp() if not data_store.RelationalDBReadEnabled(category="foreman"): # Create a Foreman with an empty rule set. with aff4.FACTORY.Create( "aff4:/foreman", aff4_grr.GRRForeman, mode="rw", token=self.token) as self.foreman: self.foreman.Set(self.foreman.Schema.RULES()) self.foreman.Close()
def AddJobStatus(self, job_id, status): if data_store.RelationalDBReadEnabled(): data_store.REL_DB.UpdateCronJob( job_id, last_run_time=rdfvalue.RDFDatetime.Now(), last_run_status=status) else: urn = cronjobs.CronManager.CRON_JOBS_PATH.Add(job_id) with aff4.FACTORY.OpenWithLock(urn, token=self.token) as job: job.Set(job.Schema.LAST_RUN_TIME(rdfvalue.RDFDatetime.Now())) job.Set(job.Schema.LAST_RUN_STATUS(status=status))
def testFingerprintPresence(self): client_id = self.SetupClient(0) path = os.path.join(self.base_path, "winexec_img.dd") pathspec = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS, path=path) pathspec.Append(path="/winpmem-amd64.sys", pathtype=rdf_paths.PathSpec.PathType.TSK) client_mock = action_mocks.ActionMock(file_fingerprint.FingerprintFile) with test_lib.Instrument(flow.GRRFlow, "SendReply") as send_reply: flow_test_lib.TestFlowHelper( flows_fingerprint.FingerprintFile.__name__, client_mock, token=self.token, client_id=client_id, pathspec=pathspec) self.assertEqual(len(send_reply.args), 1) for _, reply in send_reply.args: self.assertTrue( isinstance(reply, flows_fingerprint.FingerprintFileResult)) self.assertTrue( str(reply.file_urn).endswith( "test_data/winexec_img.dd/winpmem-amd64.sys")) self.assertEqual( str(reply.hash_entry.sha256), "40ac571d6d85d669a9a19d498d9f926525481430056ff65746f" "baf36bee8855f") self.assertEqual(str(reply.hash_entry.sha1), "6e17df1a1020a152f2bf4445d1004b192ae8e42d") self.assertEqual(str(reply.hash_entry.md5), "12be1109aa3d3b46c9398972af2008e1") if data_store.RelationalDBReadEnabled(category="vfs"): path_info = rdf_objects.PathInfo.FromPathSpec(pathspec) path_info = data_store.REL_DB.FindPathInfoByPathID( client_id.Basename(), path_info.path_type, path_info.GetPathID()) hash_obj = path_info.hash_entry else: urn = pathspec.AFF4Path(client_id) fd = aff4.FACTORY.Open(urn, token=self.token) self.assertEqual(fd.__class__, aff4_grr.VFSFile) hash_obj = fd.Get(fd.Schema.HASH) self.assertEqual(hash_obj.pecoff_sha1, "1f32fa4eedfba023653c094143d90999f6b9bc4f") self.assertEqual(hash_obj.signed_data[0].revision, 512)
def ProcessMessage(self, message=None): """Handle a startup event.""" client_id = message.source new_si = message.payload drift = rdfvalue.Duration("5m") if data_store.RelationalDBReadEnabled(): current_si = data_store.REL_DB.ReadClientStartupInfo( client_id.Basename()) # We write the updated record if the client_info has any changes # or the boot time is more than 5 minutes different. if (not current_si or current_si.client_info != new_si.client_info or not current_si.boot_time or abs(current_si.boot_time - new_si.boot_time) > drift): try: data_store.REL_DB.WriteClientStartupInfo( client_id.Basename(), new_si) except db.UnknownClientError: # On first contact with a new client, this write will fail. logging.info( "Can't write StartupInfo for unknown client %s", client_id) else: changes = False with aff4.FACTORY.Create(client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token) as client: old_info = client.Get(client.Schema.CLIENT_INFO) old_boot = client.Get(client.Schema.LAST_BOOT_TIME, 0) info = new_si.client_info # Only write to the datastore if we have new information. if info != old_info: client.Set(client.Schema.CLIENT_INFO(info)) changes = True client.AddLabels(info.labels, owner="GRR") # Allow for some drift in the boot times (5 minutes). if not old_boot or abs(old_boot - new_si.boot_time) > drift: client.Set(client.Schema.LAST_BOOT_TIME(new_si.boot_time)) changes = True if data_store.RelationalDBWriteEnabled() and changes: try: data_store.REL_DB.WriteClientStartupInfo( client_id.Basename(), new_si) except db.UnknownClientError: pass
def InitFromObj_(self, notification_type, reference, message=None): self.CreateUser(self.token.username) notification.Notify(self.token.username, notification_type, message or "", reference) ns = self.GetUserNotifications(self.token.username) if data_store.RelationalDBReadEnabled(): # Treat the notification as an object coming from REL_DB. return user_plugin.ApiNotification().InitFromUserNotification(ns[0]) else: # Treat the notification as an old-style notification object. return user_plugin.ApiNotification().InitFromNotification(ns[0])
def Run(self): if data_store.RelationalDBReadEnabled(category="foreman"): return try: # Make the foreman with aff4.FACTORY.Create("aff4:/foreman", GRRForeman, token=aff4.FACTORY.root_token): pass except access_control.UnauthorizedAccess: pass