예제 #1
0
파일: config_test.py 프로젝트: ytisf/grr
  def SetUpBinaries(self):
    with test_lib.FakeTime(42):
      code = "I am a binary file"
      upload_path = config_lib.CONFIG.Get("Config.aff4_root").Add(
          "executables/windows/test.exe")
      maintenance_utils.UploadSignedConfigBlob(
          code, aff4_path=upload_path, token=self.token)

    with test_lib.FakeTime(43):
      code = "I'm a python hack"
      upload_path = config_lib.CONFIG.Get("Config.python_hack_root").Add("test")
      maintenance_utils.UploadSignedConfigBlob(
          code, aff4_path=upload_path, token=self.token)

    with test_lib.FakeTime(44):
      component = test_lib.WriteComponent(
          name="grr-awesome-component",
          build_system=rdf_client.Uname(
              architecture="64bit",
              fqdn="test.host",
              kernel="3.42-generic",
              machine="x86_64",
              node="test.localhost",
              pep425tag="Linux_debian_64bit",
              release="Debian",
              system="Linux",
              version="4.42"),
          version="1.2.3.4",
          raw_data="I'm a component",
          modules=["grr_awesome"],
          token=self.token)
      return component.summary
예제 #2
0
    def RenderAjax(self, request, response):
        """Handle the upload via ajax."""
        try:
            self.uploaded_file = request.FILES.items()[0][1]
            self.dest_path, _ = self.GetFilePath(request)

            content = StringIO.StringIO()
            for chunk in self.uploaded_file.chunks():
                content.write(chunk)

            self.dest_path = maintenance_utils.UploadSignedConfigBlob(
                content.getvalue(),
                aff4_path=self.dest_path,
                token=request.token)

            return renderers.TemplateRenderer.Layout(self, request, response,
                                                     self.success_template)
        except (IOError) as e:
            self.error = "Could not write file to database %s" % e
        except (IndexError) as e:
            self.error = "No file provided."
        except message.DecodeError as e:
            self.error = (
                "Could not decode driver. This should be a signed protobuf"
                " generated with sign_blob")
        return renderers.TemplateRenderer.Layout(self, request, response,
                                                 self.error_template)
예제 #3
0
    def __init__(self, **kwargs):
        super(TestLaunchBinaries, self).__init__(**kwargs)
        self.context = ["Platform:%s" % self.platform.title()]
        self.binary = config_lib.CONFIG.Get(
            "Executables.aff4_path",
            context=self.context).Add("test/%s" % self.ds_names[self.platform])

        self.args = dict(binary=self.binary)

        try:
            aff4.FACTORY.Open(self.binary,
                              aff4_type="GRRSignedBlob",
                              token=self.token)
        except IOError:
            print "Uploading the test binary to the Executables area."
            source = os.path.join(config_lib.CONFIG["Test.data_dir"],
                                  self.filenames[self.platform])

            if not os.path.exists(source):
                self.fail("Path %s should exist." % source)

            maintenance_utils.UploadSignedConfigBlob(
                open(source, "rb").read(),
                aff4_path=self.binary,
                client_context=self.context,
                token=self.token,
                limit=self.limit)
예제 #4
0
  def testExecuteBinariesWithArgs(self):
    client_mock = action_mocks.ActionMock("ExecuteBinaryCommand")

    code = "I am a binary file"
    upload_path = config_lib.CONFIG["Executables.aff4_path"].Add("test.exe")

    maintenance_utils.UploadSignedConfigBlob(
        code, aff4_path=upload_path, token=self.token)

    # This flow has an acl, the user needs to be admin.
    user = aff4.FACTORY.Create("aff4:/users/%s" % self.token.username,
                               mode="rw", aff4_type="GRRUser", token=self.token)
    user.SetLabels("admin", owner="GRR")
    user.Close()

    with utils.Stubber(subprocess, "Popen", test_lib.Popen):
      for _ in test_lib.TestFlowHelper(
          "LaunchBinary", client_mock, client_id=self.client_id,
          binary=upload_path, command_line="--value 356", token=self.token):
        pass

      # Check that the executable file contains the code string.
      self.assertEqual(test_lib.Popen.binary, code)

      # At this point, the actual binary should have been cleaned up by the
      # client action so it should not exist.
      self.assertRaises(IOError, open, test_lib.Popen.running_args[0])

      # Check the binary was run with the correct command line.
      self.assertEqual(test_lib.Popen.running_args[1], "--value")
      self.assertEqual(test_lib.Popen.running_args[2], "356")

      # Check the command was in the tmp file.
      self.assertTrue(test_lib.Popen.running_args[0].startswith(
          config_lib.CONFIG["Client.tempdir"]))
예제 #5
0
  def testExecuteLargeBinaries(self):
    client_mock = action_mocks.ActionMock("ExecuteBinaryCommand")

    code = "I am a large binary file" * 100
    upload_path = config_lib.CONFIG["Executables.aff4_path"].Add("test.exe")

    maintenance_utils.UploadSignedConfigBlob(
        code, aff4_path=upload_path, limit=100, token=self.token)

    # Ensure the aff4 collection has many items.
    fd = aff4.FACTORY.Open(upload_path, token=self.token)

    # There should be 24 parts to this binary.
    self.assertEqual(len(fd.collection), 24)

    # Total size is 2400.
    self.assertEqual(len(fd), 2400)

    class Popen(object):
      """A mock object for subprocess.Popen."""

      def __init__(self, run, stdout, stderr, stdin):
        Popen.running_args = run
        Popen.stdout = stdout
        Popen.stderr = stderr
        Popen.stdin = stdin
        Popen.returncode = 0

        # Store the content of the executable file.
        Popen.binary = open(run[0]).read()

      def communicate(self):  # pylint: disable=g-bad-name
        return "stdout here", "stderr here"

    # This flow has an acl, the user needs to be admin.
    user = aff4.FACTORY.Create("aff4:/users/%s" % self.token.username,
                               mode="rw", aff4_type="GRRUser", token=self.token)
    user.SetLabels("admin", owner="GRR")
    user.Close()

    with utils.Stubber(subprocess, "Popen", Popen):
      for _ in test_lib.TestFlowHelper(
          "LaunchBinary", client_mock, client_id=self.client_id,
          binary=upload_path, command_line="--value 356", token=self.token):
        pass

      # Check that the executable file contains the code string.
      self.assertEqual(Popen.binary, code)

      # At this point, the actual binary should have been cleaned up by the
      # client action so it should not exist.
      self.assertRaises(IOError, open, Popen.running_args[0])

      # Check the binary was run with the correct command line.
      self.assertEqual(Popen.running_args[1], "--value")
      self.assertEqual(Popen.running_args[2], "356")

      # Check the command was in the tmp file.
      self.assertTrue(Popen.running_args[0].startswith(
          config_lib.CONFIG["Client.tempdir"]))
예제 #6
0
    def SetUpBinaries(self):
        with test_lib.FakeTime(42):
            code = "I am a binary file"
            upload_path = config.CONFIG.Get("Config.aff4_root").Add(
                "executables/windows/test.exe")
            maintenance_utils.UploadSignedConfigBlob(code,
                                                     aff4_path=upload_path,
                                                     token=self.token)

        with test_lib.FakeTime(43):
            code = "I'm a python hack"
            upload_path = config.CONFIG.Get("Config.python_hack_root").Add(
                "test")
            maintenance_utils.UploadSignedConfigBlob(code,
                                                     aff4_path=upload_path,
                                                     token=self.token)
예제 #7
0
    def testExecuteLargeBinaries(self):
        client_mock = action_mocks.ActionMock(standard.ExecuteBinaryCommand)

        code = "I am a large binary file" * 100
        upload_path = config.CONFIG["Executables.aff4_path"].Add("test.exe")

        maintenance_utils.UploadSignedConfigBlob(code,
                                                 aff4_path=upload_path,
                                                 limit=100,
                                                 token=self.token)

        # Ensure the aff4 collection has many items.
        fd = aff4.FACTORY.Open(upload_path, token=self.token)

        # Total size is 2400.
        self.assertEqual(len(fd), 2400)

        # There should be 24 parts to this binary.
        self.assertEqual(len(fd.collection), 24)

        # This flow has an acl, the user needs to be admin.
        user = aff4.FACTORY.Create("aff4:/users/%s" % self.token.username,
                                   mode="rw",
                                   aff4_type=users.GRRUser,
                                   token=self.token)
        user.SetLabels("admin", owner="GRR")
        user.Close()

        with utils.Stubber(subprocess, "Popen", test_lib.Popen):
            for _ in test_lib.TestFlowHelper("LaunchBinary",
                                             client_mock,
                                             client_id=self.client_id,
                                             binary=upload_path,
                                             command_line="--value 356",
                                             token=self.token):
                pass

            # Check that the executable file contains the code string.
            self.assertEqual(test_lib.Popen.binary, code)

            # At this point, the actual binary should have been cleaned up by the
            # client action so it should not exist.
            self.assertRaises(IOError, open, test_lib.Popen.running_args[0])

            # Check the binary was run with the correct command line.
            self.assertEqual(test_lib.Popen.running_args[1], "--value")
            self.assertEqual(test_lib.Popen.running_args[2], "356")

            # Check the command was in the tmp file.
            self.assertTrue(test_lib.Popen.running_args[0].startswith(
                config.CONFIG["Client.tempdir_roots"][0]))
예제 #8
0
  def testExecutePythonHackWithArgs(self):
    client_mock = action_mocks.ActionMock("ExecutePython")
    sys.test_code_ran_here = 1234
    code = """
import sys
sys.test_code_ran_here = py_args['value']
"""
    maintenance_utils.UploadSignedConfigBlob(
        code, aff4_path="aff4:/config/python_hacks/test", token=self.token)

    for _ in test_lib.TestFlowHelper(
        "ExecutePythonHack", client_mock, client_id=self.client_id,
        hack_name="test", py_args=dict(value=5678), token=self.token):
      pass

    self.assertEqual(sys.test_code_ran_here, 5678)
예제 #9
0
  def testExecutePythonHack(self):
    client_mock = action_mocks.ActionMock("ExecutePython")
    # This is the code we test. If this runs on the client mock we can check for
    # this attribute.
    sys.test_code_ran_here = False

    code = """
import sys
sys.test_code_ran_here = True
"""
    maintenance_utils.UploadSignedConfigBlob(
        code, aff4_path="aff4:/config/python_hacks/test", token=self.token)

    for _ in test_lib.TestFlowHelper(
        "ExecutePythonHack", client_mock, client_id=self.client_id,
        hack_name="test", token=self.token):
      pass

    self.assertTrue(sys.test_code_ran_here)
예제 #10
0
        except maintenance_utils.UserError as e:
            print e

    elif flags.FLAGS.subparser_name == "upload_python":
        content = open(flags.FLAGS.file, "rb").read(1024 * 1024 * 30)
        aff4_path = flags.FLAGS.dest_path
        if not aff4_path:
            python_hack_root_urn = config_lib.CONFIG.Get(
                "Config.python_hack_root")
            aff4_path = python_hack_root_urn.Add(
                os.path.basename(flags.FLAGS.file))
        context = [
            "Platform:%s" % flags.FLAGS.platform.title(), "Client Context"
        ]
        maintenance_utils.UploadSignedConfigBlob(content,
                                                 aff4_path=aff4_path,
                                                 client_context=context,
                                                 token=token)

    elif flags.FLAGS.subparser_name == "upload_exe":
        content = open(flags.FLAGS.file, "rb").read(1024 * 1024 * 30)
        context = [
            "Platform:%s" % flags.FLAGS.platform.title(), "Client Context"
        ]

        if flags.FLAGS.dest_path:
            dest_path = rdfvalue.RDFURN(flags.FLAGS.dest_path)
        else:
            dest_path = config_lib.CONFIG.Get(
                "Executables.aff4_path",
                context=context).Add(os.path.basename(flags.FLAGS.file))
예제 #11
0
    def RepackTemplate(self,
                       template_path,
                       output_dir,
                       upload=False,
                       token=None,
                       sign=False,
                       context=None,
                       signed_template=False):
        """Repack binaries based on the configuration.

    We repack all templates in the templates directory. We expect to find only
    functioning templates, all other files should be removed. Each template
    contains a build.yaml that specifies how it was built and how it should be
    repacked.

    Args:
      template_path: template path string
      output_dir: Output files will be put in this directory.
      upload: If specified we also upload the repacked binary into the
      token: Token to use when uploading to the datastore.
      sign: If true, we want to digitally sign the installer.
      context: Array of context strings
      signed_template: If true, the libraries in the template are already
      signed. This is only used for windows when repacking the template multiple
      times.

    Returns:
      A list of output installers generated.
    """
        orig_config = config.CONFIG
        repack_config = RepackConfig()
        print "Repacking template: %s" % template_path
        config.CONFIG = repack_config.GetConfigFromTemplate(template_path)

        result_path = None
        try:
            repack_context = config.CONFIG["Template.build_context"]
            if context:
                repack_context.extend(context)

            output_path = os.path.join(
                output_dir,
                config.CONFIG.Get("ClientRepacker.output_filename",
                                  context=repack_context))

            print "Using context: %s and labels: %s" % (
                repack_context,
                config.CONFIG.Get("Client.labels", context=repack_context))
            try:
                signer = None
                if sign:
                    signer = self.GetSigner(repack_context)
                builder_obj = self.GetRepacker(context=repack_context,
                                               signer=signer)
                builder_obj.signed_template = signed_template
                result_path = builder_obj.MakeDeployableBinary(
                    template_path, output_path)
            except Exception as e:  # pylint: disable=broad-except
                print "Repacking template %s failed: %s" % (template_path, e)

            if result_path:
                print "Repacked into %s" % result_path
                if upload:
                    # We delay import here so we don't have to import the entire server
                    # codebase and do full server init if we're just building and
                    # repacking clients. This codepath is used by config_updater
                    # initialize
                    # pylint: disable=g-import-not-at-top
                    from grr.lib import maintenance_utils
                    # pylint: enable=g-import-not-at-top
                    dest = config.CONFIG.Get("Executables.installer",
                                             context=repack_context)
                    maintenance_utils.UploadSignedConfigBlob(
                        open(result_path, "rb").read(100 * 1024 * 1024),
                        dest,
                        client_context=repack_context,
                        token=token)
            else:
                print "Failed to repack %s." % template_path
        finally:
            config.CONFIG = orig_config

        return result_path
예제 #12
0
    password = getpass.getpass(prompt="Please enter password for user '%s': " %
                               flags.FLAGS.username)
    labels = []
    if not flags.FLAGS.noadmin:
      labels.append("admin")
    UpdateUser(flags.FLAGS.username, password, labels)

  elif flags.FLAGS.subparser_name == "upload_python":
    content = open(flags.FLAGS.file).read(1024*1024*30)
    aff4_path = flags.FLAGS.dest_path
    if not aff4_path:
      python_hack_root_urn = config_lib.CONFIG.Get("Config.python_hack_root")
      aff4_path = python_hack_root_urn.Add(os.path.basename(flags.FLAGS.file))
    context = ["Platform:%s" % flags.FLAGS.platform.title(),
               "Client"]
    maintenance_utils.UploadSignedConfigBlob(content, aff4_path=aff4_path,
                                             client_context=context)

  elif flags.FLAGS.subparser_name == "upload_exe":
    content = open(flags.FLAGS.file).read(1024*1024*30)
    context = ["Platform:%s" % flags.FLAGS.platform.title(),
               "Client"]

    if flags.FLAGS.dest_path:
      dest_path = rdfvalue.RDFURN(flags.FLAGS.dest_path)
    else:
      dest_path = config_lib.CONFIG.Get(
          "Executables.aff4_path", context=context).Add(
              os.path.basename(flags.FLAGS.file))

    # Now upload to the destination.
    uploaded = maintenance_utils.UploadSignedConfigBlob(