Пример #1
0
    def PushToStateQueue(self, message, **kw):
        """Push given message to the state queue."""
        # Assume the client is authorized
        message.auth_state = rdf_flows.GrrMessage.AuthorizationState.AUTHENTICATED

        # Update kw args
        for k, v in kw.items():
            setattr(message, k, v)

        # Handle well known flows
        if message.request_id == 0:
            self._PushHandlerMessage(message)
            return

        data_store.REL_DB.WriteFlowResponses(
            [rdf_flow_objects.FlowResponseForLegacyResponse(message)])
Пример #2
0
    def PushToStateQueue(self, manager, message, **kw):
        """Push given message to the state queue."""
        # Assume the client is authorized
        message.auth_state = rdf_flows.GrrMessage.AuthorizationState.AUTHENTICATED

        # Update kw args
        for k, v in iteritems(kw):
            setattr(message, k, v)

        # Handle well known flows
        if message.request_id == 0:
            self._PushHandlerMessage(message)
            return

        # Use REL_DB if it's enabled and if message in question has to be
        # delivered to a client. Messages for hunts have to be delivered
        # using the legacy queue manager until REL_DB hunts implementation
        # is complete.
        if data_store.RelationalDBEnabled() and str(
                message.session_id).startswith("aff4:/C."):
            data_store.REL_DB.WriteFlowResponses(
                [rdf_flow_objects.FlowResponseForLegacyResponse(message)])
        else:
            manager.QueueResponse(message)
Пример #3
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)
Пример #4
0
    def ReceiveMessagesRelationalFlows(self, client_id, messages):
        """Receives and processes messages for flows stored in the relational db.

    Args:
      client_id: The client which sent the messages.
      messages: A list of GrrMessage RDFValues.
    """
        now = time.time()
        unprocessed_msgs = []
        message_handler_requests = []
        dropped_count = 0
        for session_id, msgs in iteritems(
                collection.Group(messages, operator.attrgetter("session_id"))):

            # Remove and handle messages to WellKnownFlows
            leftover_msgs = self.HandleWellKnownFlows(msgs)

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

                if session_id in queue_manager.session_id_map:
                    message_handler_requests.append(
                        rdf_objects.MessageHandlerRequest(
                            client_id=msg.source.Basename(),
                            handler_name=queue_manager.
                            session_id_map[session_id],
                            request_id=msg.response_id,
                            request=msg.payload))
                elif session_id 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:
                flow_responses.append(
                    rdf_flow_objects.FlowResponseForLegacyResponse(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 message_handler_requests:
            data_store.REL_DB.WriteMessageHandlerRequests(
                message_handler_requests)

        logging.debug("Received %s messages from %s in %s sec", len(messages),
                      client_id,
                      time.time() - now)