Esempio n. 1
0
    def Handle(self, args, token=None):
        audit_description = ",".join([
            token.username + u"." + utils.SmartUnicode(name)
            for name in args.labels
        ])
        audit_events = []

        try:
            index = client_index.CreateClientIndex(token=token)
            client_objs = aff4.FACTORY.MultiOpen(
                [cid.ToClientURN() for cid in args.client_ids],
                aff4_type=aff4_grr.VFSGRRClient,
                mode="rw",
                token=token)
            for client_obj in client_objs:
                index.RemoveClientLabels(client_obj)
                self.RemoveClientLabels(client_obj, args.labels)
                index.AddClient(client_obj)
                client_obj.Close()

                audit_events.append(
                    events.AuditEvent(
                        user=token.username,
                        action="CLIENT_REMOVE_LABEL",
                        flow_name="handler.ApiRemoveClientsLabelsHandler",
                        client=client_obj.urn,
                        description=audit_description))
        finally:
            events.Events.PublishMultipleEvents(
                {audit.AUDIT_EVENT: audit_events}, token=token)
Esempio n. 2
0
def AddUser(username, password=None, labels=None, token=None):
  """Implementation of the add_user command."""
  token = data_store.GetDefaultToken(token)
  user_urn = "aff4:/users/%s" % username
  try:
    if aff4.FACTORY.Open(user_urn, users.GRRUser, token=token):
      raise UserError("Cannot add user %s: User already exists." % username)
  except aff4.InstantiationError:
    pass

  fd = aff4.FACTORY.Create(user_urn, users.GRRUser, mode="rw", token=token)
  # Note this accepts blank passwords as valid.
  if password is None:
    password = getpass.getpass(prompt="Please enter password for user '%s': " %
                               username)
  fd.SetPassword(password)

  if labels:
    fd.AddLabels(*set(labels), owner="GRR")

  fd.Close()

  EPrint("Added user %s." % username)

  events.Events.PublishEvent(
      "Audit",
      events.AuditEvent(
          user=token.username, action="USER_ADD", urn=user_urn),
      token=token)
Esempio n. 3
0
    def _CreateAuditEvent(self, event_action):
        flow_name = self.hunt_obj.args.flow_runner_args.flow_name

        event = events.AuditEvent(user=self.hunt_obj.token.username,
                                  action=event_action,
                                  urn=self.hunt_obj.urn,
                                  flow_name=flow_name,
                                  description=self.runner_args.description)
        events.Events.PublishEvent("Audit", event, token=self.hunt_obj.token)
Esempio n. 4
0
    def SimulateUserActivity(username, client_id, timestamp, num=10):
        for flow_name in flows[:num]:
            event = events.AuditEvent(user=username,
                                      action="RUN_FLOW",
                                      flow_name=flow_name,
                                      client=client_id,
                                      age=timestamp)

            events.Events.PublishEvent("Audit", event, token=token)
Esempio n. 5
0
    def BuildApprovalUrn(self, approval_id):
        """Builds approval object urn."""
        event = events.AuditEvent(user=self.token.username,
                                  action="CLIENT_APPROVAL_BREAK_GLASS_REQUEST",
                                  client=self.client_id,
                                  description=self.args.reason)
        events.Events.PublishEvent("Audit", event, token=self.token)

        return self.ApprovalUrnBuilder(self.client_id.Path(),
                                       self.token.username, approval_id)
Esempio n. 6
0
def AddFakeAuditLog(description=None,
                    client=None,
                    user=None,
                    token=None,
                    **kwargs):
  events.Events.PublishEventInline(
      "Audit",
      events.AuditEvent(
          description=description, client=client, user=user, **kwargs),
      token=token)
Esempio n. 7
0
    def BuildApprovalUrn(self, approval_id):
        """Builds approval object urn."""
        events.Events.PublishEvent("Audit",
                                   events.AuditEvent(
                                       user=self.token.username,
                                       action="CLIENT_APPROVAL_GRANT",
                                       client=self.subject_urn,
                                       description=self.args.reason),
                                   token=self.token)

        return self.ApprovalUrnBuilder(self.subject_urn.Path(),
                                       self.args.delegate, approval_id)
Esempio n. 8
0
    def BuildApprovalUrn(self):
        """Builds approval object URN."""
        # In this case subject_urn is hunt's URN.
        events.Events.PublishEvent("Audit",
                                   events.AuditEvent(
                                       user=self.token.username,
                                       action="CRON_APPROVAL_GRANT",
                                       urn=self.args.subject_urn,
                                       description=self.args.reason),
                                   token=self.token)

        return self.ApprovalUrnBuilder(self.args.subject_urn.Path(),
                                       self.args.delegate, self.args.reason)
Esempio n. 9
0
    def BuildApprovalUrn(self, approval_id):
        """Builds approval object URN."""
        # In this case subject_urn is a cron job's URN.
        events.Events.PublishEvent("Audit",
                                   events.AuditEvent(
                                       user=self.token.username,
                                       action="CRON_APPROVAL_REQUEST",
                                       urn=self.subject_urn,
                                       description=self.reason),
                                   token=self.token)

        return self.ApprovalUrnBuilder(self.subject_urn.Path(),
                                       self.token.username, approval_id)
Esempio n. 10
0
def DeleteUser(username, token=None):
  """Deletes an existing user."""
  token = data_store.GetDefaultToken(token)
  user_urn = "aff4:/users/%s" % username
  try:
    aff4.FACTORY.Open(user_urn, users.GRRUser, token=token)
  except aff4.InstantiationError:
    EPrint("User %s not found." % username)
    return

  aff4.FACTORY.Delete(user_urn, token=token)
  EPrint("User %s has been deleted." % username)

  events.Events.PublishEvent(
      "Audit",
      events.AuditEvent(
          user=token.username, action="USER_DELETE", urn=user_urn),
      token=token)
Esempio n. 11
0
  def Start(self):
    """Find a hunt, perform a permissions check and modify it."""
    with aff4.FACTORY.Open(
        self.args.hunt_urn,
        aff4_type=implementation.GRRHunt,
        mode="rw",
        token=self.token) as hunt:

      runner = hunt.GetRunner()
      data_store.DB.security_manager.CheckHuntAccess(self.token.RealUID(),
                                                     hunt.urn)

      # Make sure the hunt is not running:
      if runner.IsHuntStarted():
        raise RuntimeError("Unable to modify a running hunt.")

      # Record changes in the audit event
      changes = []
      if runner.context.expires != self.args.expiry_time:
        changes.append("Expires: Old=%s, New=%s" % (runner.context.expires,
                                                    self.args.expiry_time))

      if runner.runner_args.client_limit != self.args.client_limit:
        changes.append(
            "Client Limit: Old=%s, New=%s" %
            (runner.runner_args.client_limit, self.args.client_limit))

      description = ", ".join(changes)
      event = events.AuditEvent(
          user=self.token.username,
          action="HUNT_MODIFIED",
          urn=self.args.hunt_urn,
          description=description)
      events.Events.PublishEvent("Audit", event, token=self.token)

      # Just go ahead and change the hunt now.
      runner.context.expires = self.args.expiry_time
      runner.runner_args.client_limit = self.args.client_limit
Esempio n. 12
0
def UpdateUser(username,
               password,
               add_labels=None,
               delete_labels=None,
               token=None):
  """Implementation of the update_user command."""
  token = data_store.GetDefaultToken(token)

  user_urn = "aff4:/users/%s" % username
  try:
    fd = aff4.FACTORY.Open(user_urn, users.GRRUser, mode="rw", token=token)
  except aff4.InstantiationError:
    raise UserError("User %s does not exist." % username)

  # Note this accepts blank passwords as valid.
  if password:
    if not isinstance(password, basestring):
      password = getpass.getpass(
          prompt="Please enter password for user '%s': " % username)
    fd.SetPassword(password)

  # Use sets to dedup input.
  current_labels = set()

  # Build a list of existing labels.
  for label in fd.GetLabels():
    current_labels.add(label.name)

  # Build a list of labels to be added.
  expanded_add_labels = set()
  if add_labels:
    for label in add_labels:
      # Split up any space or comma separated labels in the list.
      labels = label.split(",")
      expanded_add_labels.update(labels)

  # Build a list of labels to be removed.
  expanded_delete_labels = set()
  if delete_labels:
    for label in delete_labels:
      # Split up any space or comma separated labels in the list.
      labels = label.split(",")
      expanded_delete_labels.update(labels)

  # Set subtraction to remove labels being added and deleted at the same time.
  clean_add_labels = expanded_add_labels - expanded_delete_labels
  clean_del_labels = expanded_delete_labels - expanded_add_labels

  # Create final list using difference to only add new labels.
  final_add_labels = clean_add_labels - current_labels

  # Create final list using intersection to only remove existing labels.
  final_del_labels = clean_del_labels & current_labels

  if final_add_labels:
    fd.AddLabels(*final_add_labels, owner="GRR")

  if final_del_labels:
    fd.RemoveLabels(*final_del_labels, owner="GRR")

  fd.Close()

  EPrint("Updated user %s" % username)

  ShowUser(username, token=token)

  events.Events.PublishEvent(
      "Audit",
      events.AuditEvent(
          user=token.username, action="USER_UPDATE", urn=user_urn),
      token=token)
Esempio n. 13
0
    def Handle(self, args, token=None):
        hunt_urn = HUNTS_ROOT_PATH.Add(args.hunt_id)
        try:
            hunt = aff4.FACTORY.Open(hunt_urn,
                                     aff4_type=hunts.GRRHunt,
                                     mode="rw",
                                     token=token)
        except aff4.InstantiationError:
            raise HuntNotFoundError("Hunt with id %s could not be found" %
                                    args.hunt_id)

        current_state = hunt.Get(hunt.Schema.STATE)
        hunt_changes = []
        runner = hunt.GetRunner()

        if args.HasField("client_limit"):
            hunt_changes.append(
                "Client Limit: Old=%s, New=%s" %
                (runner.runner_args.client_limit, args.client_limit))
            runner.runner_args.client_limit = args.client_limit

        if args.HasField("client_rate"):
            hunt_changes.append(
                "Client Rate: Old=%s, New=%s" %
                (runner.runner_args.client_rate, args.client_limit))
            runner.runner_args.client_rate = args.client_rate

        if args.HasField("expires"):
            hunt_changes.append("Expires: Old=%s, New=%s" %
                                (runner.context.expires, args.expires))
            runner.context.expires = args.expires

        if hunt_changes and current_state != "PAUSED":
            raise HuntNotModifiableError(
                "Hunt's client limit/client rate/expiry time attributes "
                "can only be changed if hunt's current state is "
                "PAUSED")

        if args.HasField("state"):
            hunt_changes.append("State: Old=%s, New=%s" %
                                (current_state, args.state))

            if args.state == ApiHunt.State.STARTED:
                if current_state != "PAUSED":
                    raise HuntNotStartableError(
                        "Hunt can only be started from PAUSED state.")
                hunt.Run()

            elif args.state == ApiHunt.State.STOPPED:
                if current_state not in ["PAUSED", "STARTED"]:
                    raise HuntNotStoppableError(
                        "Hunt can only be stopped from STARTED or "
                        "PAUSED states.")
                hunt.Stop()

            else:
                raise InvalidHuntStateError(
                    "Hunt's state can only be updated to STARTED or STOPPED")

        # Publish an audit event.
        # TODO(user): this should be properly tested.
        event = events.AuditEvent(user=token.username,
                                  action="HUNT_MODIFIED",
                                  urn=hunt_urn,
                                  description=", ".join(hunt_changes))
        events.Events.PublishEvent("Audit", event, token=token)

        hunt.Close()

        hunt = aff4.FACTORY.Open(hunt_urn,
                                 aff4_type=hunts.GRRHunt,
                                 mode="rw",
                                 token=token)
        return ApiHunt().InitFromAff4Object(hunt, with_full_summary=True)
Esempio n. 14
0
  def StartFlow(cls, args=None, runner_args=None,  # pylint: disable=g-bad-name
                parent_flow=None, sync=True, **kwargs):
    """The main factory function for Creating and executing a new flow.

    Args:

      args: An arg protocol buffer which is an instance of the required flow's
        args_type class attribute.

      runner_args: an instance of FlowRunnerArgs() protocol buffer which is used
        to initialize the runner for this flow.

      parent_flow: A parent flow or None if this is a top level flow.

      sync: If True, the Start method of this flow will be called
         inline. Otherwise we schedule the starting of this flow on another
         worker.

      **kwargs: If args or runner_args are not specified, we construct these
        protobufs from these keywords.

    Returns:
      the session id of the flow.

    Raises:
      RuntimeError: Unknown or invalid parameters were provided.
    """

    # Build the runner args from the keywords.
    if runner_args is None:
      runner_args = rdf_flows.FlowRunnerArgs()

    cls.FilterArgsFromSemanticProtobuf(runner_args, kwargs)

    # When asked to run a flow in the future this implied it will run
    # asynchronously.
    if runner_args.start_time:
      sync = False

    # Is the required flow a known flow?
    if runner_args.flow_name not in GRRFlow.classes:
      stats.STATS.IncrementCounter("grr_flow_invalid_flow_count")
      raise RuntimeError("Unable to locate flow %s" % runner_args.flow_name)

    # If no token is specified, use the default token.
    if not runner_args.HasField("token"):
      if data_store.default_token is None:
        raise access_control.UnauthorizedAccess("A token must be specified.")

      runner_args.token = data_store.default_token.Copy()

    # Make sure we are allowed to run this flow. If not, we raise here. We
    # respect SUID (supervisor) if it is already set. SUID cannot be set by the
    # user since it isn't part of the ACLToken proto.
    data_store.DB.security_manager.CheckIfCanStartFlow(
        runner_args.token,
        runner_args.flow_name,
        with_client_id=runner_args.client_id)

    flow_cls = GRRFlow.GetPlugin(runner_args.flow_name)
    # If client id was specified and flow doesn't have exemption from ACL
    # checking policy, then check that the user has access to the client
    # where the flow is going to run.
    if flow_cls.ACL_ENFORCED and runner_args.client_id:
      data_store.DB.security_manager.CheckClientAccess(runner_args.token,
                                                       runner_args.client_id)

    # For the flow itself we use a supervisor token.
    token = runner_args.token.SetUID()

    # Extend the expiry time of this token indefinitely. Python on Windows only
    # supports dates up to the year 3000, this number corresponds to July, 2997.
    token.expiry = 32427003069 * rdfvalue.RDFDatetime.converter

    # We create an anonymous AFF4 object first, The runner will then generate
    # the appropriate URN.
    flow_obj = aff4.FACTORY.Create(
        None, aff4.AFF4Object.classes.get(runner_args.flow_name), token=token)

    # Now parse the flow args into the new object from the keywords.
    if args is None:
      args = flow_obj.args_type()

    cls.FilterArgsFromSemanticProtobuf(args, kwargs)

    # Check that the flow args are valid.
    args.Validate()

    # Store the flow args.
    flow_obj.args = args
    flow_obj.runner_args = runner_args

    # At this point we should exhaust all the keyword args. If any are left
    # over, we do not know what to do with them so raise.
    if kwargs:
      raise type_info.UnknownArg("Unknown parameters to StartFlow: %s" % kwargs)

    # Create a flow runner to run this flow with.
    if parent_flow:
      parent_runner = parent_flow.runner
    else:
      parent_runner = None

    runner = flow_obj.CreateRunner(
        parent_runner=parent_runner, runner_args=runner_args)

    logging.info(u"Scheduling %s(%s) on %s", flow_obj.urn,
                 runner_args.flow_name, runner_args.client_id)

    if sync:
      # Just run the first state inline. NOTE: Running synchronously means
      # that this runs on the thread that starts the flow. The advantage is
      # that that Start method can raise any errors immediately.
      flow_obj.Start()
    else:
      # Running Asynchronously: Schedule the start method on another worker.
      runner.CallState(next_state="Start", start_time=runner_args.start_time)

    # The flow does not need to actually remain running.
    if not runner.OutstandingRequests():
      flow_obj.Terminate()

    flow_obj.Close()

    # Publish an audit event, only for top level flows.
    if parent_flow is None:
      events.Events.PublishEvent(
          "Audit",
          events.AuditEvent(
              user=token.username,
              action="RUN_FLOW",
              flow_name=runner_args.flow_name,
              urn=flow_obj.urn,
              client=runner_args.client_id),
          token=token)

    return flow_obj.urn
Esempio n. 15
0
def AddFakeAuditLog(description, client=None, token=None):
    events.Events.PublishEventInline("Audit",
                                     events.AuditEvent(description=description,
                                                       client=client),
                                     token=token)