def _AddWorker(self):
        worker_name = self.name + "-%d" % random.UInt32()
        worker = _WorkerThread(self._queue, self, worker_name)
        worker.start()

        self._workers[worker.name] = worker
        self._workers_ro_copy = self._workers.copy()
Beispiel #2
0
  def __init__(self,
               initializer=None,
               base="aff4:/flows",
               queue=DEFAULT_FLOW_QUEUE,
               flow_name=None):
    """Constructor.

    Args:
      initializer: A string or another RDFURN.
      base: The base namespace this session id lives in.
      queue: The queue to use.
      flow_name: The name of this flow or its random id.

    Raises:
      InitializeError: The given URN cannot be converted to a SessionID.
    """
    if initializer is None:
      # This SessionID is being constructed from scratch.
      if flow_name is None:
        flow_name = random.UInt32()

      if isinstance(flow_name, int):
        initializer = RDFURN(base).Add("%s:%X" % (queue.Basename(), flow_name))
      else:
        initializer = RDFURN(base).Add("%s:%s" % (queue.Basename(), flow_name))
    else:
      if isinstance(initializer, RDFURN):
        try:
          self.ValidateID(initializer.Basename())
        except ValueError as e:
          raise InitializeError("Invalid URN for SessionID: %s, %s" %
                                (initializer, e))

    super(SessionID, self).__init__(initializer=initializer)
Beispiel #3
0
 def __init__(self, initializer=None, age=None, **kwargs):
     super(AuditEvent, self).__init__(initializer=initializer,
                                      age=age,
                                      **kwargs)
     if not self.id:
         self.id = random.UInt32()
     if not self.timestamp:
         self.timestamp = rdfvalue.RDFDatetime.Now()
Beispiel #4
0
    def Request(self):
        """Create the Approval object and notify the Approval Granter."""

        approval_id = "approval:%X" % random.UInt32()
        approval_urn = self.BuildApprovalUrn(approval_id)

        email_msg_id = email.utils.make_msgid()

        with aff4.FACTORY.Create(approval_urn,
                                 self.approval_type,
                                 mode="w",
                                 token=self.token) as approval_request:
            approval_request.Set(
                approval_request.Schema.SUBJECT(self.subject_urn))
            approval_request.Set(
                approval_request.Schema.REQUESTOR(self.token.username))
            approval_request.Set(approval_request.Schema.REASON(self.reason))
            approval_request.Set(
                approval_request.Schema.EMAIL_MSG_ID(email_msg_id))

            cc_addresses = (self.email_cc_address,
                            config.CONFIG.Get("Email.approval_cc_address"))
            email_cc = ",".join(filter(None, cc_addresses))

            # When we reply with the approval we want to cc all the people to whom the
            # original approval was sent, to avoid people approving stuff that was
            # already approved.
            if email_cc:
                reply_cc = ",".join((self.approver, email_cc))
            else:
                reply_cc = self.approver

            approval_request.Set(approval_request.Schema.EMAIL_CC(reply_cc))

            approval_request.Set(
                approval_request.Schema.NOTIFIED_USERS(self.approver))

            # We add ourselves as an approver as well (The requirement is that we have
            # 2 approvers, so the requester is automatically an approver).
            approval_request.AddAttribute(
                approval_request.Schema.APPROVER(self.token.username))

        approval_link_urns = self.BuildApprovalSymlinksUrns(approval_id)
        for link_urn in approval_link_urns:
            with aff4.FACTORY.Create(link_urn,
                                     aff4.AFF4Symlink,
                                     mode="w",
                                     token=self.token) as link:
                link.Set(link.Schema.SYMLINK_TARGET(approval_urn))

        return approval_urn
Beispiel #5
0
    def HandleWellKnownFlows(self, messages):
        """Hands off messages to well known flows."""
        msgs_by_wkf = {}
        result = []
        for msg in messages:
            # Regular message - queue it.
            if msg.response_id != 0:
                result.append(msg)
                continue

            # Well known flows:
            flow_name = msg.session_id.FlowName()

            if flow_name in self.well_known_flows:
                # This message should be processed directly on the front end.
                msgs_by_wkf.setdefault(flow_name, []).append(msg)

                # TODO(user): Deprecate in favor of 'well_known_flow_requests'
                # metric.
                stats_collector_instance.Get().IncrementCounter(
                    "grr_well_known_flow_requests")

                stats_collector_instance.Get().IncrementCounter(
                    "well_known_flow_requests", fields=[str(msg.session_id)])
            else:
                # Message should be queued to be processed in the backend.

                # Well known flows have a response_id==0, but if we queue up the state
                # as that it will overwrite some other message that is queued. So we
                # change it to a random number here.
                msg.response_id = random.UInt32()

                # Queue the message in the data store.
                result.append(msg)

        for flow_name, msg_list in iteritems(msgs_by_wkf):
            wkf = self.well_known_flows[flow_name]
            wkf.ProcessMessages(msg_list)

        return result
Beispiel #6
0
    def SetPassword(self, password, salt=None):
        if salt is None:
            salt = "%08x" % random.UInt32()

        self._value = self._CalculateHash(password, salt)
        return self
Beispiel #7
0
 def testSpecific(self):
     self.assertEqual(random.UInt32(), 0xDEADBEEF)
     self.assertEqual(random.UInt32(), 0xBADDCAFE)
Beispiel #8
0
    def testMax(self, urandom):
        del urandom  # Unused.

        for _ in range(10000):
            self.assertEqual(random.UInt32(), 2**32 - 1)
Beispiel #9
0
    def ReceiveMessages(self, client_id: str,
                        messages: Iterable[rdf_flows.GrrMessage]):
        """Receives and processes the messages.

    For each message we update the request object, and place the
    response in that request's queue. If the request is complete, we
    send a message to the worker.

    Args:
      client_id: The client which sent the messages.
      messages: A list of GrrMessage RDFValues.
    """
        now = time.time()
        unprocessed_msgs = []
        worker_message_handler_requests = []
        frontend_message_handler_requests = []
        dropped_count = 0

        msgs_by_session_id = collection.Group(messages, lambda m: m.session_id)
        for session_id, msgs in msgs_by_session_id.items():

            for msg in msgs:
                if (msg.auth_state != msg.AuthorizationState.AUTHENTICATED
                        and msg.session_id != self.unauth_allowed_session_id):
                    dropped_count += 1
                    continue

                session_id_str = str(session_id)
                if session_id_str in message_handlers.session_id_map:
                    request = rdf_objects.MessageHandlerRequest(
                        client_id=msg.source.Basename(),
                        handler_name=message_handlers.
                        session_id_map[session_id],
                        request_id=msg.response_id or random.UInt32(),
                        request=msg.payload)
                    if request.handler_name in self._SHORTCUT_HANDLERS:
                        frontend_message_handler_requests.append(request)
                    else:
                        worker_message_handler_requests.append(request)
                elif session_id_str in self.legacy_well_known_session_ids:
                    logging.debug(
                        "Dropping message for legacy well known session id %s",
                        session_id)
                else:
                    unprocessed_msgs.append(msg)

        if dropped_count:
            logging.info("Dropped %d unauthenticated messages for %s",
                         dropped_count, client_id)

        if unprocessed_msgs:
            flow_responses = []
            for message in unprocessed_msgs:
                try:
                    flow_responses.append(
                        rdf_flow_objects.FlowResponseForLegacyResponse(
                            message))
                except ValueError as e:
                    logging.warning(
                        "Failed to parse legacy FlowResponse:\n%s\n%s", e,
                        message)

            data_store.REL_DB.WriteFlowResponses(flow_responses)

            for msg in unprocessed_msgs:
                if msg.type == rdf_flows.GrrMessage.Type.STATUS:
                    stat = rdf_flows.GrrStatus(msg.payload)
                    if stat.status == rdf_flows.GrrStatus.ReturnedStatus.CLIENT_KILLED:
                        # A client crashed while performing an action, fire an event.
                        crash_details = rdf_client.ClientCrash(
                            client_id=client_id,
                            session_id=msg.session_id,
                            backtrace=stat.backtrace,
                            crash_message=stat.error_message,
                            nanny_status=stat.nanny_status,
                            timestamp=rdfvalue.RDFDatetime.Now())
                        events.Events.PublishEvent("ClientCrash",
                                                   crash_details,
                                                   token=self.token)

        if worker_message_handler_requests:
            data_store.REL_DB.WriteMessageHandlerRequests(
                worker_message_handler_requests)

        if frontend_message_handler_requests:
            worker_lib.ProcessMessageHandlerRequests(
                frontend_message_handler_requests)

        logging.debug("Received %s messages from %s in %s sec", len(messages),
                      client_id,
                      time.time() - now)
Beispiel #10
0
 def GenerateRunId(self):
     self.run_id = "%08X" % random.UInt32()
     return self.run_id