def _CheckApprovalsForTokenWithReason(self, token, target): # Build the approval URN. approval_urn = aff4.ROOT_URN.Add("ACL").Add(target.Path()).Add( token.username).Add(utils.EncodeReasonString(token.reason)) try: cached_token = self.acl_cache.Get(approval_urn) stats.STATS.IncrementCounter("approval_searches", fields=["with_reason", "cache"]) token.is_emergency = cached_token.is_emergency return True except KeyError: stats.STATS.IncrementCounter("approval_searches", fields=["with_reason", "data_store"]) try: approval_request = aff4.FACTORY.Open( approval_urn, aff4_type=security.Approval.__name__, mode="r", token=token, age=aff4.ALL_TIMES) if approval_request.CheckAccess(token): # Cache this approval for fast path checking. self.acl_cache.Put(approval_urn, token) return True raise access_control.UnauthorizedAccess( "Approval %s was rejected." % approval_urn, subject=target) except IOError: # No Approval found, reject this request. raise access_control.UnauthorizedAccess( "No approval found for %s." % target, subject=target)
def ApprovalRevokeRaw(aff4_path, token): """Revokes an approval for a given token. This method requires raw datastore access to manipulate approvals directly. Args: aff4_path: The aff4_path or client id the approval should be created for. token: The token that should be revoked. """ try: urn = rdf_client.ClientURN(aff4_path) except type_info.TypeValueError: urn = rdfvalue.RDFURN(aff4_path) approval_urn = aff4.ROOT_URN.Add("ACL").Add(urn.Path()).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()
def ApprovalRevokeRaw(aff4_path, token, remove_from_cache=False): """Revokes an approval for a given token. This method requires raw datastore access to manipulate approvals directly. Args: aff4_path: The aff4_path or client id the approval should be created for. token: The token that should be revoked. remove_from_cache: If True, also remove the approval from the security_manager cache. """ try: urn = rdfvalue.ClientURN(aff4_path) except type_info.TypeValueError: urn = rdfvalue.RDFURN(aff4_path) approval_urn = aff4.ROOT_URN.Add("ACL").Add(urn.Path()).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 Handle(self, args, token=None): approval_urn = aff4.ROOT_URN.Add("ACL").Add(args.client_id.Basename()).Add( token.username).Add(utils.EncodeReasonString(args.reason)) approval_obj = aff4.FACTORY.Open( approval_urn, aff4_type=aff4_security.ClientApproval.__name__, age=aff4.ALL_TIMES, token=token) return ApiUserClientApproval().InitFromAff4Object(approval_obj)
def ApprovalRevokeRaw(client_id, token, remove_from_cache=False): """Revokes an approval for a given token. This method doesn't work through the Gatekeeper for obvious reasons. To use it, the console has to use raw datastore access. Args: client_id: The client id the approval should be revoked for. token: The token that should be revoked. remove_from_cache: If True, also remove the approval from the security_manager cache. """ client_id = rdfvalue.ClientURN(client_id) approval_urn = aff4.ROOT_URN.Add("ACL").Add(client_id.Path()).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 CheckACL(self, token, target): # The supervisor may bypass all ACL checks. if token.supervisor: logging.debug(u"ACL access granted to %s on %s. Supervisor: %s", utils.SmartUnicode(token.username), target, token.supervisor) return True # Target may be None for flows not specifying a client. # Only aff4.GRRUser.SYSTEM_USERS can run these flows. if not target: if token.username not in aff4.GRRUser.SYSTEM_USERS: raise access_control.UnauthorizedAccess( "ACL access denied for flow without client_urn for %s" % token.username) return True if not token.reason: raise access_control.UnauthorizedAccess( "Must specify a reason for access.", subject=target) # Build the approval URN. approval_urn = aff4.ROOT_URN.Add("ACL").Add(target.Path()).Add( token.username).Add(utils.EncodeReasonString(token.reason)) try: token.is_emergency = self.acl_cache.Get(approval_urn) logging.debug(u"ACL access granted to %s on %s. Supervisor: %s", utils.SmartUnicode(token.username), target, token.supervisor) return True except KeyError: try: # Retrieve the approval object with superuser privileges so we can check # it. approval_request = aff4.FACTORY.Open(approval_urn, aff4_type="Approval", mode="r", token=self.super_token, age=aff4.ALL_TIMES) if approval_request.CheckAccess(token): # Cache this approval for fast path checking. self.acl_cache.Put(approval_urn, token.is_emergency) logging.debug( u"ACL access granted to %s on %s. Supervisor: %s", utils.SmartUnicode(token.username), target, token.supervisor) return True raise access_control.UnauthorizedAccess( "Approval %s was rejected." % approval_urn, subject=target) except IOError: # No Approval found, reject this request. raise access_control.UnauthorizedAccess( "No approval found for %s." % target, subject=target)
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)) with aff4.FACTORY.Open(approval_urn, mode="rw", token=self.token.SetUID()) as approval_request: approval_request.DeleteAttribute(approval_request.Schema.APPROVER) if remove_from_cache: data_store.DB.security_manager.acl_cache.ExpireObject(approval_urn)
def testGetApprovalForObjectRaisesIfApprovalsAreOfWrongType(self): # Create AFF4Volume object where Approval is expected to be. approval_urn = aff4.ROOT_URN.Add("ACL").Add(self.client_id.Path()).Add( self.token.username).Add(utils.EncodeReasonString(self.token.reason)) with aff4.FACTORY.Create( approval_urn, aff4.AFF4Volume, token=self.token) as _: pass with self.assertRaisesRegexp(access_control.UnauthorizedAccess, "Couldn't open any of 1 approvals"): security.Approval.GetApprovalForObject(self.client_id, token=self.token)
def UserHasClientApproval(self, subject, token): """Checks if read access for this client is allowed using the given token. Args: subject: Subject below the client level which triggered the check. token: The token to check with. Returns: True if the access is allowed. Raises: UnauthorizedAccess: if the access is rejected. """ client_id, _ = rdfvalue.RDFURN(subject).Split(2) client_urn = rdfvalue.ClientURN(client_id) logging.debug("Checking client approval for %s, %s", client_urn, token) if not token.reason: raise access_control.UnauthorizedAccess( "Must specify a reason for access.", subject=client_urn) # Build the approval URN. approval_urn = aff4.ROOT_URN.Add("ACL").Add(client_urn.Path()).Add( token.username).Add(utils.EncodeReasonString(token.reason)) try: token.is_emergency = self.acl_cache.Get(approval_urn) return True except KeyError: try: # Retrieve the approval object with superuser privileges so we can check # it. approval_request = aff4.FACTORY.Open(approval_urn, aff4_type="Approval", mode="r", token=self.super_token, age=aff4.ALL_TIMES) if approval_request.CheckAccess(token): # Cache this approval for fast path checking. self.acl_cache.Put(approval_urn, token.is_emergency) return True raise access_control.UnauthorizedAccess( "Approval %s was rejected." % approval_urn, subject=client_urn) except IOError: # No Approval found, reject this request. raise access_control.UnauthorizedAccess( "No approval found for client %s." % client_urn, subject=client_urn)
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(approval_urn)
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)) with aff4.FACTORY.Create( approval_urn, security.HuntApproval.__name__, mode="rw", token=self.token.SetUID()) as approval_request: approval_request.AddAttribute( approval_request.Schema.APPROVER("Approver1")) approval_request.AddAttribute( approval_request.Schema.APPROVER("Approver2")) if admin: self.CreateAdminUser("Approver1")
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 setUp(self): super(ApiCreateUserClientApprovalHandlerTest, self).setUp() self.client_id = self.SetupClients(1)[0] self.handler = user_plugin.ApiCreateUserClientApprovalHandler() self.args = user_plugin.ApiCreateUserClientApprovalArgs( client_id=self.client_id) self.args.approval.reason = self.token.reason self.args.approval.notified_users = ["approver"] self.args.approval.email_cc_addresses = ["*****@*****.**"] self.approval_urn = aff4.ROOT_URN.Add("ACL").Add(self.client_id.Basename( )).Add(self.token.username).Add(utils.EncodeReasonString(self.token.reason)) self.CreateUser("test") self.CreateUser("approver")
def CheckCronJobAccess(self, token, cron_job_urn): """Checks access to a given cron job. Args: token: User credentials token. cron_job_urn: URN of cron job to check. Returns: True if access is allowed, raises otherwise. Raises: access_control.UnauthorizedAccess if access is rejected. """ logging.debug("Checking approval for cron job %s, %s", cron_job_urn, token) if not token.username: raise access_control.UnauthorizedAccess( "Must specify a username for access.", subject=cron_job_urn) if not token.reason: raise access_control.UnauthorizedAccess( "Must specify a reason for access.", subject=cron_job_urn) # Build the approval URN. approval_urn = aff4.ROOT_URN.Add("ACL").Add(cron_job_urn.Path()).Add( token.username).Add(utils.EncodeReasonString(token.reason)) try: approval_request = aff4.FACTORY.Open(approval_urn, aff4_type="Approval", mode="r", token=token, age=aff4.ALL_TIMES) except IOError: # No Approval found, reject this request. raise access_control.UnauthorizedAccess( "No approval found for cron job %s." % cron_job_urn, subject=cron_job_urn) if approval_request.CheckAccess(token): return True else: raise access_control.UnauthorizedAccess( "Approval %s was rejected." % approval_urn, subject=cron_job_urn)
def Handle(self, args, token=None): if not args.approval.reason: raise ValueError("Approval reason can't be empty.") flow.GRRFlow.StartFlow( client_id=args.client_id, flow_name=aff4_security.RequestClientApprovalFlow.__name__, reason=args.approval.reason, approver=",".join(args.approval.notified_users), email_cc_address=",".join(args.approval.email_cc_addresses), subject_urn=args.client_id, token=token) approval_urn = aff4.ROOT_URN.Add("ACL").Add(args.client_id.Basename()).Add( token.username).Add(utils.EncodeReasonString(args.approval.reason)) approval_obj = aff4.FACTORY.Open( approval_urn, aff4_type=aff4_security.ClientApproval.__name__, age=aff4.ALL_TIMES, token=token) return ApiUserClientApproval().InitFromAff4Object(approval_obj)
def ApprovalUrnBuilder(cls, subject, user, reason): """Encode an approval URN.""" return aff4.ROOT_URN.Add("ACL").Add(subject).Add(user).Add( utils.EncodeReasonString(reason))
def ApprovalSymlinkUrnBuilder(approval_type, unique_id, user, reason): """Build an approval symlink URN.""" return aff4.ROOT_URN.Add("users").Add(user).Add("approvals").Add( approval_type).Add(unique_id).Add(utils.EncodeReasonString(reason))