def testEmptySubjectShouldRaise(self): token = access_control.ACLToken(username="******") with self.assertRaises(ValueError): self.access_manager.CheckClientAccess(token, "") with self.assertRaises(ValueError): self.access_manager.CheckHuntAccess(token, "") with self.assertRaises(ValueError): self.access_manager.CheckCronJobAccess(token, "") with self.assertRaises(ValueError): self.access_manager.CheckDataStoreAccess(token, [""], requested_access="r")
def Run(self): with test_lib.FakeTime(42): self.CreateAdminUser("approver") clients = self.SetupClients(2) for client_id in clients: # Delete the certificate as it's being regenerated every time the # client is created. with aff4.FACTORY.Open(client_id, mode="rw", token=self.token) as grr_client: grr_client.DeleteAttribute(grr_client.Schema.CERT) with test_lib.FakeTime(44): approval_urn = security.ClientApprovalRequestor( reason="foo", subject_urn=clients[0], approver="approver", token=self.token).Request() approval1_id = approval_urn.Basename() with test_lib.FakeTime(45): approval_urn = security.ClientApprovalRequestor( reason="bar", subject_urn=clients[1], approver="approver", token=self.token).Request() approval2_id = approval_urn.Basename() with test_lib.FakeTime(84): approver_token = access_control.ACLToken(username="******") security.ClientApprovalGrantor(reason="bar", delegate=self.token.username, subject_urn=clients[1], token=approver_token).Grant() with test_lib.FakeTime(126): self.Check("GetClientApproval", args=user_plugin.ApiGetClientApprovalArgs( client_id=clients[0].Basename(), approval_id=approval1_id, username=self.token.username), replace={approval1_id: "approval:111111"}) self.Check("GetClientApproval", args=user_plugin.ApiGetClientApprovalArgs( client_id=clients[1].Basename(), approval_id=approval2_id, username=self.token.username), replace={approval2_id: "approval:222222"})
def main(unused_argv): """Main.""" banner = ("\nWelcome to the GRR console\n" "Type help<enter> to get help\n\n") config_lib.CONFIG.AddContext("Commandline Context") config_lib.CONFIG.AddContext( "Console Context", "Context applied when running the console binary.") startup.Init() # To make the console easier to use, we make a default token which will be # used in StartFlow operations. data_store.default_token = access_control.ACLToken( username=getpass.getuser(), reason=flags.FLAGS.reason) locals_vars = { "hilfe": Help, "help": Help, "__name__": "GRR Console", "l": Lister, "o": aff4.FACTORY.Open, # Bring some symbols from other modules into the console's # namespace. "StartFlowAndWait": flow_utils.StartFlowAndWait, "StartFlowAndWorker": debugging.StartFlowAndWorker, "RunEndToEndTests": end_to_end_tests.RunEndToEndTests, } locals_vars.update(globals()) # add global variables to console if flags.FLAGS.client is not None: locals_vars["client"], locals_vars["token"] = console_utils.OpenClient( client_id=flags.FLAGS.client) if flags.FLAGS.code_to_execute: logging.info("Running code from flag: %s", flags.FLAGS.code_to_execute) exec(flags.FLAGS.code_to_execute) # pylint: disable=exec-used elif flags.FLAGS.command_file: logging.info("Running code from file: %s", flags.FLAGS.command_file) execfile(flags.FLAGS.command_file) if (flags.FLAGS.exit_on_complete and (flags.FLAGS.code_to_execute or flags.FLAGS.command_file)): return else: # We want the normal shell. locals_vars.update(globals()) # add global variables to console ipshell.IPShell(argv=[], user_ns=locals_vars, banner=banner)
def InitDatastore(self): self.token = access_control.ACLToken(username="******", reason="Running tests") # Use separate tables for benchmarks / tests so they can be run in parallel. with test_lib.ConfigOverrider( {"Mysql.database_name": "grr_test_%s" % self.__class__.__name__}): try: data_store.DB = mysql_advanced_data_store.MySQLAdvancedDataStore( ) data_store.DB.flusher_thread.Stop() data_store.DB.security_manager = test_lib.MockSecurityManager() data_store.DB.RecreateTables() except Exception as e: logging.debug("Error while connecting to MySQL db: %s.", e) raise unittest.SkipTest( "Skipping since Mysql db is not reachable.")
def SaveServerMapping(self, mapping, create_pathing=False): """Stores the server mapping in the data store.""" if create_pathing: # We are going to use our own pathing. mapping.pathing = self.pathing else: # We are going to use the mapping pathing configuration. # Check if its different than the one we use now and then ask the # datastore to use it. new_pathing = list(mapping.pathing) if self._DifferentPathing(new_pathing): self.pathing = new_pathing self.db.RecreatePathing(new_pathing) # SetUID is required to write to aff4:/servers_map token = access_control.ACLToken(username="******").SetUID() self.db.MultiSet(MAP_SUBJECT, {MAP_VALUE_PREDICATE: mapping}, token=token)
def RevokeClientApproval(self, client_id, token, remove_from_cache=True): approval_urn = aff4.ROOT_URN.Add("ACL").Add(client_id).Add( token.username).Add(utils.EncodeReasonString(token.reason)) super_token = access_control.ACLToken(username="******") super_token.supervisor = True approval_request = aff4.FACTORY.Open(approval_urn, mode="rw", token=super_token) approval_request.DeleteAttribute(approval_request.Schema.APPROVER) approval_request.Close() if remove_from_cache: data_store.DB.security_manager.acl_cache.ExpireObject( utils.SmartUnicode(approval_urn))
def _MakeFixtures(self): # Install the mock security manager so we can trap errors in interactive # mode. data_store.DB.security_manager = test_lib.MockSecurityManager() token = access_control.ACLToken(username="******", reason="Make fixtures.") token = token.SetUID() for i in range(10): client_id = rdf_client.ClientURN("C.%016X" % i) with aff4.FACTORY.Create(client_id, aff4_grr.VFSGRRClient, mode="rw", token=token) as client_obj: index = client_index.CreateClientIndex(token=token) index.AddClient(client_obj)
def LoadServerMapping(self): """Retrieve server mapping from database.""" # TODO(user): this SetUID can likely be replaced with a read ACL. token = access_control.ACLToken(username="******").SetUID() mapping_str, _ = self.db.Resolve(MAP_SUBJECT, MAP_VALUE_PREDICATE, token=token) if not mapping_str: return None mapping = rdf_data_server.DataServerMapping.FromSerializedString( mapping_str) # Restore pathing information. if self._DifferentPathing(list(mapping.pathing)): self.pathing = list(mapping.pathing) self.db.RecreatePathing(self.pathing) return mapping
def main(unused_argv): """Main.""" config_lib.CONFIG.AddContext("Commandline Context", "Context applied for all command line tools") config_lib.CONFIG.AddContext("ExportTool Context", "Context applied to the export tool.") server_startup.Init() data_store.default_token = access_control.ACLToken( username=flags.FLAGS.username or getpass.getuser(), reason=flags.FLAGS.reason) # If subcommand was specified by the user in the command line, # corresponding subparser should have initialized "func" argument # with a corresponding export plugin's Run() function. flags.FLAGS.func(flags.FLAGS)
def __init__(self, methodName=None): # pylint: disable=g-bad-name """Hack around unittest's stupid constructor. We sometimes need to instantiate the test suite without running any tests - e.g. to start initialization or setUp() functions. The unittest constructor requires to provide a valid method name. Args: methodName: The test method to run. """ super(GRRBaseTest, self).__init__(methodName=methodName or "__init__") self.base_path = config.CONFIG["Test.data_dir"] test_user = "******" users.GRRUser.SYSTEM_USERS.add(test_user) self.token = access_control.ACLToken(username=test_user, reason="Running tests")
def testRendersSettingsForUserCorrespondingToToken(self): with aff4.FACTORY.Create( aff4.ROOT_URN.Add("users").Add("foo"), aff4_type=aff4_users.GRRUser, mode="w", token=self.token) as user_fd: user_fd.Set(user_fd.Schema.GUI_SETTINGS, aff4_users.GUISettings(mode="ADVANCED", canary_mode=True, docs_location="REMOTE")) result = self.handler.Handle(None, token=access_control.ACLToken(username="******")) self.assertEqual(result.settings.mode, "ADVANCED") self.assertEqual(result.settings.canary_mode, True) self.assertEqual(result.settings.docs_location, "REMOTE")
def TestFlows(client_id, platform, testname=None, local_worker=False): """Test a bunch of flows.""" if platform not in ["windows", "linux", "darwin"]: raise RuntimeError("Requested operating system not supported.") # This token is not really used since there is no approval for the # tested client - these tests are designed for raw access - but we send it # anyways to have an access reason. token = access_control.ACLToken(username="******", reason="client testing") client_id = rdfvalue.RDFURN(client_id) RunTests(client_id, platform=platform, testname=testname, token=token, local_worker=local_worker)
def UpdateLoop(self): token = access_control.ACLToken(username="******", reason="Updating An Index") while True: with self.cv: while not self.to_process: self.cv.wait() next_update = self.to_process.popleft() now = time.time() next_urn = next_update[0] next_time = next_update[1] while now < next_time: time.sleep(next_time - now) now = time.time() aff4.FACTORY.Open(next_urn, token=token).UpdateIndex()
def GenerateNotifications(cls): """Generate some fake notifications.""" token = access_control.ACLToken(username="******", reason="test fixture") cls.session_id = flow.GRRFlow.StartFlow( client_id="aff4:/C.0000000000000001", flow_name="Interrogate", token=token) with aff4.FACTORY.Open(cls.session_id, mode="rw", token=token) as flow_obj: flow_obj.Notify("ViewObject", "aff4:/C.0000000000000001/fs/os/proc/10/exe", "File fetch completed.") # Generate an error for this flow. with flow_obj.GetRunner() as runner: runner.Error("not a real backtrace")
def RequestAndGrantClientApproval(client_id, token=None, approver="approver", reason="testing"): token = token or GetToken() ApprovalRequest(client_id, token=token, approver=approver, reason=reason) user = aff4.FACTORY.Create("aff4:/users/%s" % approver, users.GRRUser, token=token.SetUID()) user.Flush() approver_token = access_control.ACLToken(username=approver) flow.GRRFlow.StartFlow(client_id=client_id, flow_name="GrantClientApprovalFlow", reason=reason, delegate=token.username, subject_urn=rdf_client.ClientURN(client_id), token=approver_token)
def GrantHuntApproval(self, hunt_urn, token=None): """Grants an approval for a given hunt.""" token = token or self.token # Create the approval and approve it. security.HuntApprovalRequestor(subject_urn=hunt_urn, reason=token.reason, approver="approver", token=token).Request() self.CreateAdminUser("approver") approver_token = access_control.ACLToken(username="******") security.HuntApprovalGrantor(subject_urn=hunt_urn, reason=token.reason, delegate=token.username, token=approver_token).Grant()
def StartFlowAndWorker(client_id, flow_name, **kwargs): """Launches the flow and worker and waits for it to finish. Args: client_id: The client common name we issue the request. flow_name: The name of the flow to launch. **kwargs: passthrough to flow. Returns: A flow session id. Note: you need raw access to run this flow as it requires running a worker. """ # Empty token, only works with raw access. queue = rdfvalue.RDFURN("DEBUG-%s-" % getpass.getuser()) if "token" in kwargs: token = kwargs.pop("token") else: token = access_control.ACLToken(username="******") session_id = flow.GRRFlow.StartFlow(client_id=client_id, flow_name=flow_name, queue=queue, token=token, **kwargs) worker_thrd = worker.GRRWorker(queues=[queue], token=token, threadpool_size=1) while True: try: worker_thrd.RunOnce() except KeyboardInterrupt: print "exiting" worker_thrd.thread_pool.Join() break time.sleep(2) with aff4.FACTORY.Open(session_id, token=token) as flow_obj: if not flow_obj.GetRunner().IsRunning(): break # Terminate the worker threads worker_thrd.thread_pool.Join() return session_id
def GrantCronJobApproval(self, cron_job_urn, token=None): """Grants an approval for a given cron job.""" token = token or self.token # Create cron job approval and approve it. security.CronJobApprovalRequestor( subject_urn=rdfvalue.RDFURN(cron_job_urn), reason=self.token.reason, approver="approver", token=token).Request() self.CreateAdminUser("approver") approver_token = access_control.ACLToken(username="******") security.CronJobApprovalGrantor(subject_urn=cron_job_urn, reason=token.reason, delegate=token.username, token=approver_token).Grant()
def Run(self): with test_lib.FakeTime(42): self.CreateAdminUser("approver") clients = self.SetupClients(2) for client_id in clients: # Delete the certificate as it's being regenerated every time the # client is created. with aff4.FACTORY.Open(client_id, mode="rw", token=self.token) as grr_client: grr_client.DeleteAttribute(grr_client.Schema.CERT) with test_lib.FakeTime(44): flow.GRRFlow.StartFlow(client_id=clients[0], flow_name="RequestClientApprovalFlow", reason="foo", subject_urn=clients[0], approver="approver", token=self.token) with test_lib.FakeTime(45): flow.GRRFlow.StartFlow(client_id=clients[1], flow_name="RequestClientApprovalFlow", reason="bar", subject_urn=clients[1], approver="approver", token=self.token) with test_lib.FakeTime(84): approver_token = access_control.ACLToken(username="******") flow.GRRFlow.StartFlow(client_id=clients[1], flow_name="GrantClientApprovalFlow", reason="bar", delegate=self.token.username, subject_urn=clients[1], token=approver_token) with test_lib.FakeTime(126): self.Check( "GET", "/api/users/me/approvals/client/%s/foo" % clients[0].Basename()) self.Check( "GET", "/api/users/me/approvals/client/%s/bar" % clients[1].Basename())
def testFlowAccess(self): """Tests access to flows.""" token = access_control.ACLToken(username="******", reason="For testing") client_id = "C." + "a" * 16 self.assertRaises( access_control.UnauthorizedAccess, flow.GRRFlow.StartFlow, client_id=client_id, flow_name=test_lib.SendingFlow.__name__, message_count=1, token=token) approval_urn = self.RequestAndGrantClientApproval(client_id, token) sid = flow.GRRFlow.StartFlow( client_id=client_id, flow_name=test_lib.SendingFlow.__name__, message_count=1, token=token) # Check we can open the flow object. flow_obj = aff4.FACTORY.Open(sid, mode="r", token=token) # Check that we can not write to it. flow_obj.mode = "rw" state = flow_obj.Get(flow_obj.Schema.FLOW_STATE_DICT) flow_obj.Set(state) # This is not allowed - Users can not write to flows. self.assertRaises(access_control.UnauthorizedAccess, flow_obj.Close) self.RevokeClientApproval(approval_urn, token) self.assertRaises( access_control.UnauthorizedAccess, aff4.FACTORY.Open, sid, mode="r", token=token) self.RequestAndGrantClientApproval(client_id, token) aff4.FACTORY.Open(sid, mode="r", token=token)
def BuildToken(request, execution_time): """Build an ACLToken from the request.""" if request.method == "GET": reason = request.GET.get("reason", "") elif request.method == "POST": reason = request.POST.get("reason", "") token = access_control.ACLToken(username=request.user, reason=reason, process="GRRAdminUI", expiry=rdfvalue.RDFDatetime().Now() + execution_time) for field in ["REMOTE_ADDR", "HTTP_X_FORWARDED_FOR"]: remote_addr = request.META.get(field, "") if remote_addr: token.source_ips.append(remote_addr) return token
def CreateHuntApproval(self, hunt_urn, token, admin=False): approval_urn = aff4.ROOT_URN.Add("ACL").Add(hunt_urn.Path()).Add( token.username).Add(utils.EncodeReasonString(token.reason)) super_token = access_control.ACLToken(username="******") super_token.supervisor = True approval_request = aff4.FACTORY.Create(approval_urn, "HuntApproval", mode="rw", token=super_token) approval_request.AddAttribute( approval_request.Schema.APPROVER("Approver1")) approval_request.AddAttribute( approval_request.Schema.APPROVER("Approver2")) approval_request.Close() if admin: self.CreateAdminUser("Approver1")
def testClientApproval(self): """Tests that we can create an approval object to access clients.""" client_id = "C.%016X" % 0 urn = rdf_client.ClientURN(client_id).Add("/fs") token = access_control.ACLToken(username="******", reason="For testing") self.assertRaises(access_control.UnauthorizedAccess, aff4.FACTORY.Open, urn, None, "rw", token=token) self.GrantClientApproval(client_id, token) fd = aff4.FACTORY.Open(urn, None, "rw", token=token) fd.Close() self.RevokeClientApproval(client_id, token) self.assertRaises(access_control.UnauthorizedAccess, aff4.FACTORY.Open, urn, None, "rw", token=token)
def testClientNoLabels(self): nolabel_urn = self.client_nolabel.Add("/fs") token = access_control.ACLToken(username="******", reason="For testing") self.assertRaises( access_control.UnauthorizedAccess, aff4.FACTORY.Open, nolabel_urn, aff4_type=None, mode="rw", token=token) # approvers.yaml rules don't get checked because this client has no # labels. Regular approvals still required. self.RequestAndGrantClientApproval(self.client_nolabel, token) # Check we now have access with aff4.FACTORY.Open(nolabel_urn, aff4_type=None, mode="rw", token=token): pass
def CreateFileVersions(self, client_id, file_path): """Add a new version for a file.""" with test_lib.FakeTime(self.time_1): token = access_control.ACLToken(username="******") fd = aff4.FACTORY.Create(client_id.Add(file_path), "AFF4MemoryStream", mode="w", token=token) fd.Write("Hello World") fd.Close() with test_lib.FakeTime(self.time_2): fd = aff4.FACTORY.Create(client_id.Add(file_path), "AFF4MemoryStream", mode="w", token=token) fd.Write("Goodbye World") fd.Close()
def testSupervisorCanDoAnything(self): token = access_control.ACLToken(username="******", supervisor=True) self.assertTrue( self.access_manager.CheckClientAccess(token, "aff4:/C.0000000000000001")) self.assertTrue( self.access_manager.CheckHuntAccess(token, "aff4:/hunts/H:12344")) self.assertTrue( self.access_manager.CheckCronJobAccess(token, "aff4:/cron/blah")) self.assertTrue( self.access_manager.CheckIfCanStartFlow( token, "SomeFlow", with_client_id=True)) self.assertTrue( self.access_manager.CheckIfCanStartFlow( token, "SomeFlow", with_client_id=False)) self.assertTrue( self.access_manager.CheckDataStoreAccess( token, ["aff4:/foo/bar"], requested_access="w"))
def UpdateLoop(self): token = access_control.ACLToken(username="******", reason="Updating An Index") while not self.exit_now: with self.cv: while not self.to_process: self.cv.wait() next_update = self.to_process.popleft() if next_update is None: return now = time.time() next_urn = next_update[0] next_time = next_update[1] while now < next_time: time.sleep(next_time - now) now = time.time() self.ProcessCollection(next_urn, token)
def testExpiredTokens(self): """Tests that expired tokens are rejected.""" urn = rdf_client.ClientURN("C.%016X" % 0).Add("/fs/os/c") self.assertRaises(access_control.UnauthorizedAccess, aff4.FACTORY.Open, urn) with test_lib.FakeTime(100): # Token expires in 5 seconds. super_token = access_control.ACLToken(username="******", expiry=105) super_token.supervisor = True # This should work since token is a super token. aff4.FACTORY.Open(urn, mode="rw", token=super_token) # Change the time to 200 with test_lib.FakeTime(200): # Should be expired now. with self.assertRaises(access_control.ExpiryError): aff4.FACTORY.Open(urn, token=super_token, mode="rw")
def testCreatorPropagation(self): # Instantiate the flow using one username. session_id = flow.GRRFlow.StartFlow( client_id=self.client_id, flow_name="ParentFlow", sync=False, token=access_control.ACLToken(username="******", reason="testing")) # Run the flow using another user ("test"). for _ in test_lib.TestFlowHelper(session_id, ClientMock(), client_id=self.client_id, token=self.token): pass self.assertEqual(ParentFlow.success, True) subflows = list(aff4.FACTORY.Open( session_id, token=self.token).ListChildren()) self.assertEqual(len(subflows), 1) child_flow = aff4.FACTORY.Open(subflows[0], token=self.token) self.assertEqual(child_flow.GetRunner().context.creator, "original_user")
def testUserAccess(self): """Tests access to user objects.""" token = access_control.ACLToken(username="******", reason="For testing") urn = aff4.ROOT_URN.Add("users") # We cannot open any user account. self.assertRaises(access_control.UnauthorizedAccess, aff4.FACTORY.Open, urn.Add("some_user"), None, "rw", False, token) # But we can open our own. aff4.FACTORY.Open(urn.Add("test"), mode="rw", token=token) # And we can also access our labels. label_urn = urn.Add("test").Add("labels") labels = aff4.FACTORY.Open(label_urn, mode="rw", token=token) # But we cannot write to them. l = labels.Schema.LABELS() l.AddLabel(aff4_rdfvalues.AFF4ObjectLabel(name="admin", owner="GRR")) labels.Set(labels.Schema.LABELS, l) self.assertRaises(access_control.UnauthorizedAccess, labels.Close)