예제 #1
0
def main(argv):
    del argv  # Unused.

    if flags.FLAGS.mysql_username is None:
        raise ValueError("--mysql_username has to be specified.")

    # Generate server and client configs.
    server_conf_path, client_conf_path = self_contained_components.InitConfigs(
        flags.FLAGS.mysql_database,
        mysql_username=flags.FLAGS.mysql_username,
        mysql_password=flags.FLAGS.mysql_password,
        logging_path=flags.FLAGS.logging_path,
        osquery_path=flags.FLAGS.osquery_path)

    # Start all remaining server components.
    # Start a background thread that kills the main process if one of the
    # server subprocesses dies.
    server_processes = self_contained_components.StartServerProcesses(
        server_conf_path)
    self_contained_components.DieIfSubProcessDies(server_processes)

    api_port = api_helpers.GetAdminUIPortFromConfig(server_conf_path)
    grrapi = api_helpers.WaitForAPIEndpoint(api_port)

    # Start the client.
    preliminary_client_p = self_contained_components.StartClientProcess(
        client_conf_path)

    # Wait for the client to enroll and get its id.
    client_id = api_helpers.WaitForClientToEnroll(grrapi)
    print("Found client id: %s" % client_id)

    # Python doesn't guarantee the process name of processes started by the Python
    # interpreter. They may vary from platform to platform. In order to ensure
    # that Client.binary_name config setting matches the actual process name,
    # let's get the name via psutil, kill the client and set the
    # Config.binary_name explicitly.
    client_binary_name = str(psutil.Process(preliminary_client_p.pid).name())
    api_helpers.KillClient(grrapi, client_id)
    preliminary_client_p.wait()

    print("Starting the client with Client.binary_name=%s" %
          client_binary_name)
    client_p = self_contained_components.StartClientProcess(
        client_conf_path, {"Client.binary_name": client_binary_name})
    # Start a background thread that kills the main process if
    # client subprocess dies.
    self_contained_components.DieIfSubProcessDies([client_p])

    # Run the test suite against the enrolled client.
    self_contained_components.RunEndToEndTests(
        client_id,
        server_conf_path,
        tests=flags.FLAGS.tests,
        manual_tests=flags.FLAGS.manual_tests)

    print("RunEndToEndTests execution succeeded.")
    sys.exit(0)
예제 #2
0
def main(argv):
  del argv  # Unused.

  if flags.FLAGS.mysql_username is None:
    raise ValueError("--mysql_username has to be specified.")

  # Generate server and client configs.
  grr_configs = self_contained_components.InitGRRConfigs(
      flags.FLAGS.mysql_database,
      mysql_username=flags.FLAGS.mysql_username,
      mysql_password=flags.FLAGS.mysql_password,
      logging_path=flags.FLAGS.logging_path)

  print("Building the template.")
  template_path = self_contained_components.RunBuildTemplate(
      grr_configs.server_config, component_options={"Logging.verbose": True})

  print("Repack %s." % template_path)
  installer_path = self_contained_components.RunRepackTemplate(
      grr_configs.server_config, template_path)

  version_overrides = {
      "Source.version_major": 9,
      "Source.version_minor": 9,
      "Source.version_revision": 9,
      "Source.version_release": 9,
      "Source.version_string": "9.9.9.9",
      "Source.version_numeric": 9999,
      "Template.version_major": 9,
      "Template.version_minor": 9,
      "Template.version_revision": 9,
      "Template.version_release": 9,
      "Template.version_string": "9.9.9.9",
      "Template.version_numeric": 9999,
  }

  print("Building next ver. template.")
  next_ver_template_path = self_contained_components.RunBuildTemplate(
      grr_configs.server_config,
      component_options=version_overrides,
      version_ini=_HIGHEST_VERSION_INI)

  print("Repack next ver. %s." % template_path)
  next_ver_installer_path = self_contained_components.RunRepackTemplate(
      grr_configs.server_config,
      next_ver_template_path,
      component_options=version_overrides)

  print("First installer ready: %s. Next ver. installer ready: %s." %
        (installer_path, next_ver_installer_path))

  print("Starting the server.")
  # Start all remaining server components.
  # Start a background thread that kills the main process if one of the
  # server subprocesses dies.
  server_processes = self_contained_components.StartServerProcesses(grr_configs)
  self_contained_components.DieIfSubProcessDies(server_processes)

  api_port = api_helpers.GetAdminUIPortFromConfig(grr_configs.server_config)
  grrapi = api_helpers.WaitForAPIEndpoint(api_port)

  print("Installing the client.")
  system = platform.system().lower()
  if system == "linux":
    distro_id = distro.id()
    if distro_id in ["ubuntu", "debian"]:
      subprocess.check_call(
          ["apt", "install", "--reinstall", "-y", installer_path])
    elif distro_id in ["centos", "rhel", "fedora"]:
      subprocess.check_call(["rpm", "-Uvh", installer_path])
    else:
      raise RuntimeError("Unsupported linux distro: %s" % distro_id)
  elif system == "windows":
    subprocess.check_call([installer_path])
  elif system == "darwin":
    subprocess.check_call(["installer", "-pkg", installer_path, "-target", "/"])
  else:
    raise RuntimeError("Unsupported platform for self-update tests: %s" %
                       system)

  # Wait for the client to enroll and get its id.
  client_id = api_helpers.WaitForClientToEnroll(grrapi)
  print("Found client id: %s" % client_id)

  print("Waiting for the client to report the initial version.")
  prev_version = api_helpers.WaitForClientVersionGreaterThan(
      grrapi.Client(client_id), 0)

  binary_id = self_contained_components.RunUploadExe(grr_configs.server_config,
                                                     next_ver_installer_path,
                                                     system)

  args = grrapi.types.CreateFlowArgs(flow_name="UpdateClient")
  args.binary_path = binary_id
  f = grrapi.Client(client_id).CreateFlow(name="UpdateClient", args=args)
  try:
    # Timeout has to be rather significant, since at the moment installers
    # are uploaded in chunks of 512Kb, each chunk requiring a round-trip
    # to/from the client.
    f.WaitUntilDone(timeout=180)
    print("Update flow finished successfully. This should never happen: "
          "the client should have been restarted.")
    sys.exit(-1)
  except errors.PollTimeoutError:
    print("Update flow timed out. This shouldn't happen: the flow should "
          "fail explicitly due to a client restart.")
    sys.exit(-1)
  except errors.FlowFailedError:
    print("Update flow failed (expected behavior, as the client got "
          "restarted).")

  print("Update flow details:")
  print(f.Get().data)

  print("Waiting for the client to report the updated version.")
  api_helpers.WaitForClientVersionGreaterThan(
      grrapi.Client(client_id), prev_version)

  print("Self-update test successful!")

  sys.exit(0)
def main(argv):
    grr_configs = self_contained_components.InitGRRConfigs(
        flags.FLAGS.mysql_database,
        mysql_username=flags.FLAGS.mysql_username,
        mysql_password=flags.FLAGS.mysql_password,
        logging_path=flags.FLAGS.logging_path,
        with_fleetspeak=True)

    fleetspeak_configs = self_contained_components.InitFleetspeakConfigs(
        grr_configs,
        flags.FLAGS.fleetspeak_mysql_database,
        mysql_username=flags.FLAGS.mysql_username,
        mysql_password=flags.FLAGS.mysql_password)

    server_processes = self_contained_components.StartServerProcesses(
        grr_configs=grr_configs, fleetspeak_configs=fleetspeak_configs)

    api_port = api_helpers.GetAdminUIPortFromConfig(grr_configs.server_config)

    grr_api = api_helpers.WaitForAPIEndpoint(api_port)

    if list(grr_api.SearchClients()):
        raise Exception("This tests expects to be run on an empty database.")

    client_p = self_contained_components.StartClientProcess(
        grr_configs=grr_configs, fleetspeak_configs=fleetspeak_configs)

    client_id = api_helpers.WaitForClientToEnroll(grr_api)

    print("client_id is", client_id)

    client_proc_before = FindGrrClientProcess(grr_configs.client_config)

    print("GRR process has process ID {}.".format(client_proc_before.pid))

    print("Running Interrogate flow 1.")
    result = RunInterrogate(grr_api, client_id)
    print("Interrogate flow 1 finished with result {}.".format(result))

    print("Running RestartFleetspeakGrrService().")
    self_contained_components.RunApiShellRawAccess(
        grr_configs.server_config,
        "grrapi.root.Client(\"{}\").RestartFleetspeakGrrService()".format(
            client_id))
    print("Finished RestartFleetspeakGrrService().")

    # We have to wait for the restart to finish.
    # Killing the GRR service while a flow is running might make the flow hang.
    # The GRR client sends the reply of an action to fleetspeak, then deletes
    # the action from the transaction log. However, fleetspeak buffers the reply
    # in memory for up to one second. If the GRR client gets killed in this
    # time window, the reply is lost.
    time.sleep(10)

    client_proc_after = FindGrrClientProcess(grr_configs.client_config)
    print("GRR process has process ID {} after restart.".format(
        client_proc_before.pid))

    if client_proc_before.pid == client_proc_after.pid:
        raise Exception("Process ID of GRR process didn't change as expected. "
                        "Before: {}. After: {}.".format(
                            client_proc_before.pid, client_proc_after.pid))

    print("Running Interrogate flow 2.")
    result = RunInterrogate(grr_api, client_id)
    print("Interrogate flow 2 finished with result {}.".format(result))

    if client_p.poll() is not None:
        raise Exception(
            "Fleetspeak client process is expected to run, but it terminated.")

    # With force=False the fleetspeak client performs a graceful shutdown.
    print("Running KillFleetspeak(force=False).")
    self_contained_components.RunApiShellRawAccess(
        grr_configs.server_config,
        "grrapi.root.Client(\"{}\").KillFleetspeak(force=False)".format(
            client_id))
    print("Finished KillFleetspeak(force=False).")

    print("Waiting for fleetspeak client to terminate.")
    client_p.wait(5)
    print("Fleetspeak client terminated.")

    print("Restarting fleetspeak client.")
    client_p = self_contained_components.StartClientProcess(
        grr_configs=grr_configs, fleetspeak_configs=fleetspeak_configs)

    print("Running Interrogate flow 3.")
    result = RunInterrogate(grr_api, client_id)
    print("Interrogate flow 3 finished with result {}.".format(result))

    if client_p.poll() is not None:
        raise Exception(
            "Fleetspeak client process is expected to run, but it terminated.")

    # With force=True the fleetspeak clients just exits.
    print("Running KillFleetspeak(force=True).")
    self_contained_components.RunApiShellRawAccess(
        grr_configs.server_config,
        "grrapi.root.Client(\"{}\").KillFleetspeak(force=True)".format(
            client_id))
    print("Finished KillFleetspeak(force=True).")

    print("Waiting for fleetspeak client to terminate.")
    client_p.wait(5)
    print("Fleetspeak client terminated.")

    print("Restarting fleetspeak client.")
    client_p = self_contained_components.StartClientProcess(
        grr_configs=grr_configs, fleetspeak_configs=fleetspeak_configs)

    print("Running Interrogate flow 4.")
    result = RunInterrogate(grr_api, client_id)
    print("Interrogate flow 4 finished with result {}.".format(result))

    print("Finished.")

    sys.exit(0)