Exemple #1
0
def InstallerNotifyServer():
    """An emergency function Invoked when the client installation failed."""
    # We make a temporary emergency config file to contain the new client id. Note
    # that the notification callback does not really mean anything to us, since
    # the client is not installed and we dont have basic interrogate information.
    config_lib.CONFIG.SetWriteBack("temp.yaml")

    try:
        log_data = open(config_lib.CONFIG["Installer.logfile"], "rb").read()
    except (IOError, OSError):
        log_data = ""

    # Start the client and send the server a message, then terminate. The
    # private key may be empty if we did not install properly yet. In this case,
    # the client will automatically generate a random client ID and private key
    # (and the message will be unauthenticated since we never enrolled.).
    comms.CommsInit().RunOnce()

    client = comms.GRRHTTPClient(
        ca_cert=config_lib.CONFIG["CA.certificate"],
        private_key=config_lib.CONFIG.Get("Client.private_key"))

    client.client_worker.SendReply(
        session_id=rdfvalue.FlowSessionID(flow_name="InstallationFailed"),
        message_type=rdf_flows.GrrMessage.Type.STATUS,
        request_id=0,
        response_id=0,
        rdf_value=rdf_flows.GrrStatus(
            status=rdf_flows.GrrStatus.ReturnedStatus.GENERIC_ERROR,
            error_message="Installation failed.",
            backtrace=log_data[-10000:]))

    client.RunOnce()
Exemple #2
0
 def _ForemanOp(self):
     """Sends Foreman checks periodically."""
     period = config.CONFIG["Client.foreman_check_frequency"]
     self._threads["Worker"].SendReply(
         rdf_protodict.DataBlob(),
         session_id=rdfvalue.FlowSessionID(flow_name="Foreman"),
         require_fastpoll=False)
     time.sleep(period)
Exemple #3
0
 def SendNannyMessage(self):
     msg = self.nanny_controller.GetNannyMessage()
     if msg:
         self.SendReply(
             rdfvalue.DataBlob(string=msg),
             session_id=rdfvalue.FlowSessionID(flow_name="NannyMessage"),
             priority=rdfvalue.GrrMessage.Priority.LOW_PRIORITY,
             require_fastpoll=False)
         self.nanny_controller.ClearNannyMessage()
Exemple #4
0
 def _ForemanCheckerThread(self):
   """Sends Foreman checks periodically."""
   period = config.CONFIG["Client.foreman_check_frequency"]
   while True:
     self._client_worker.SendReply(
         rdf_protodict.DataBlob(),
         session_id=rdfvalue.FlowSessionID(flow_name="Foreman"),
         priority=rdf_flows.GrrMessage.Priority.LOW_PRIORITY)
     time.sleep(period)
Exemple #5
0
 def SendClientAlert(self, msg):
     self.SendReply(
         rdfvalue.DataBlob(string=msg),
         session_id=rdfvalue.FlowSessionID(flow_name="ClientAlert"),
         priority=rdfvalue.GrrMessage.Priority.LOW_PRIORITY,
         require_fastpoll=False)
Exemple #6
0
    def Run(self):
        """A Generator which makes a single request to the GRR server.

    Callers should generate this when they wish to make a connection
    to the server. It is up to the caller to sleep between calls in
    order to enforce the required network and CPU utilization
    policies.

    Raises:
      RuntimeError: Too many connection errors have been encountered.
    Yields:
      A Status() object indicating how the last POST went.
    """
        while True:
            self.consecutive_connection_errors = 0
            while self.active_server_url is None:
                if self.EstablishConnection():
                    # Everything went as expected - we don't need to return to
                    # the main loop (which would mean sleeping for a poll_time).
                    break
                else:
                    # If we can't reconnect to the server for a long time, we restart
                    # to reset our state. In some very rare cases, the urrlib can get
                    # confused and we need to reset it before we can start talking to
                    # the server again.
                    self.consecutive_connection_errors += 1
                    limit = config_lib.CONFIG["Client.connection_error_limit"]
                    if self.consecutive_connection_errors > limit:
                        raise RuntimeError(
                            "Too many connection errors, exiting.")

                    # Constantly retrying will not work, we back off a bit.
                    time.sleep(60)
                yield Status()

            # Check if there is a message from the nanny to be sent.
            self.client_worker.SendNannyMessage()

            now = time.time()
            # Check with the foreman if we need to
            if (now > self.last_foreman_check +
                    config_lib.CONFIG["Client.foreman_check_frequency"]):
                # We must not queue messages from the comms thread with blocking=True
                # or we might deadlock. If the output queue is full, we can't accept
                # more work from the foreman anyways so it's ok to drop the message.
                try:
                    self.client_worker.SendReply(
                        rdfvalue.DataBlob(),
                        session_id=rdfvalue.FlowSessionID(flow_name="Foreman"),
                        priority=rdfvalue.GrrMessage.Priority.LOW_PRIORITY,
                        require_fastpoll=False,
                        blocking=False)
                    self.last_foreman_check = now
                except Queue.Full:
                    pass

            status = self.RunOnce()

            # We suicide if our memory is exceeded, and there is no more work to do
            # right now. Our death should not result in loss of messages since we are
            # not holding any requests in our input queues.
            if (self.client_worker.MemoryExceeded()
                    and not self.client_worker.IsActive()
                    and self.client_worker.InQueueSize() == 0
                    and self.client_worker.OutQueueSize() == 0):
                logging.warning("Memory exceeded - exiting.")
                self.client_worker.SendClientAlert(
                    "Memory limit exceeded, exiting.")
                # Make sure this will return True so we don't get more work.
                # pylint: disable=g-bad-name
                self.client_worker.MemoryExceeded = lambda: True
                # pylint: enable=g-bad-name
                # Now send back the client message.
                self.RunOnce()
                # And done for now.
                sys.exit(-1)

            self.Wait(status)

            yield status
Exemple #7
0
 def SendForemanRequest(self):
     self.client_worker.SendReply(
         rdfvalue.DataBlob(),
         session_id=rdfvalue.FlowSessionID(flow_name="Foreman"),
         priority=rdfvalue.GrrMessage.Priority.LOW_PRIORITY,
         require_fastpoll=False)