Exemple #1
0
    def _ValidateFleetspeakServiceConfig(self, config_path):
        """Validates a Fleetspeak service config.

    Checks that the given file is a valid TextFormat representation of
    a Fleetspeak service config proto.

    Args:
      config_path: Path to the config file.

    Raises:
      BuildError: If the config is not valid.
    """
        with open(config_path, "rb") as f:
            parsed_config = text_format.Parse(
                f.read(),
                fs_system_pb2.ClientServiceConfig(),
                descriptor_pool=fs_config_pb2.DESCRIPTOR.pool)
            if parsed_config.factory != "Daemon":
                raise build.BuildError(
                    "Fleetspeak config does not have the expected factory type."
                )
            daemon_cfg = fs_config_pb2.Config()
            parsed_config.config.Unpack(daemon_cfg)
            if not daemon_cfg.argv:
                raise build.BuildError(
                    "Fleetspeak daemon service config does not specify command line "
                    "args.")
Exemple #2
0
    def MakeDeployableBinary(self, template_path, output_path):
        """This will add the config to the client template and create a .rpm."""

        rpmbuild_binary = "/usr/bin/rpmbuild"
        if not os.path.exists(rpmbuild_binary):
            logging.error("rpmbuild not found, unable to repack client.")
            return None

        with utils.TempDirectory() as tmp_dir:
            template_dir = os.path.join(tmp_dir, "dist")
            utils.EnsureDirExists(template_dir)

            zf = zipfile.ZipFile(template_path)
            for name in zf.namelist():
                dirname = os.path.dirname(name)
                utils.EnsureDirExists(os.path.join(template_dir, dirname))
                with io.open(os.path.join(template_dir, name), "wb") as fd:
                    fd.write(zf.read(name))

            self._ProcessUniversalTemplate(template_dir)

            # Set up a RPM building environment.

            rpm_root_dir = os.path.join(tmp_dir, "rpmbuild")

            rpm_build_dir = os.path.join(rpm_root_dir, "BUILD")
            utils.EnsureDirExists(rpm_build_dir)

            rpm_buildroot_dir = os.path.join(rpm_root_dir, "BUILDROOT")
            utils.EnsureDirExists(rpm_buildroot_dir)

            rpm_rpms_dir = os.path.join(rpm_root_dir, "RPMS")
            utils.EnsureDirExists(rpm_rpms_dir)

            rpm_specs_dir = os.path.join(rpm_root_dir, "SPECS")
            utils.EnsureDirExists(rpm_specs_dir)

            template_binary_dir = os.path.join(tmp_dir,
                                               "dist/rpmbuild/grr-client")

            target_binary_dir = "%s%s" % (rpm_build_dir,
                                          config.CONFIG.Get(
                                              "ClientBuilder.target_dir",
                                              context=self.context))

            utils.EnsureDirExists(os.path.dirname(target_binary_dir))
            try:
                shutil.rmtree(target_binary_dir)
            except OSError:
                pass
            # TODO(user):pytype: incorrect move() definition in typeshed.
            # pytype: disable=wrong-arg-types
            shutil.move(template_binary_dir, target_binary_dir)
            # pytype: enable=wrong-arg-types

            client_name = config.CONFIG.Get("Client.name",
                                            context=self.context)
            client_binary_name = config.CONFIG.Get("Client.binary_name",
                                                   context=self.context)
            if client_binary_name != "grr-client":
                # TODO(user):pytype: incorrect move() definition in typeshed.
                # pytype: disable=wrong-arg-types
                shutil.move(
                    os.path.join(target_binary_dir, "grr-client"),
                    os.path.join(target_binary_dir, client_binary_name))
                # pytype: enable=wrong-arg-types

            if config.CONFIG.Get("Client.fleetspeak_enabled",
                                 context=self.context):
                self._GenerateFleetspeakConfig(template_dir, rpm_build_dir)
                if not config.CONFIG.Get("Client.fleetspeak_service_name",
                                         context=self.context):
                    # The Fleetspeak service name is required when generating the RPM
                    # spec file.
                    raise build.BuildError(
                        "Client.fleetspeak_service_name is not set.")
                if config.CONFIG.Get("ClientBuilder.fleetspeak_bundled",
                                     context=self.context):
                    self._GenerateBundledFleetspeakFiles(
                        os.path.join(template_dir, "bundled-fleetspeak"),
                        rpm_build_dir)
                    shutil.copy(
                        config.CONFIG.Get(
                            "ClientBuilder.fleetspeak_client_config",
                            context=self.context),
                        os.path.join(rpm_build_dir,
                                     "etc/fleetspeak-client/client.config"))
            else:
                self._GenerateInitConfigs(template_dir, rpm_build_dir)

            # Generate spec
            spec_filename = os.path.join(rpm_specs_dir,
                                         "%s.spec" % client_name)
            build_helpers.GenerateFile(os.path.join(
                tmp_dir, "dist/rpmbuild/grr.spec.in"),
                                       spec_filename,
                                       context=self.context)

            # Generate prelinking blacklist file
            prelink_target_filename = os.path.join(rpm_build_dir,
                                                   "etc/prelink.conf.d",
                                                   "%s.conf" % client_name)

            utils.EnsureDirExists(os.path.dirname(prelink_target_filename))
            build_helpers.GenerateFile(os.path.join(
                tmp_dir, "dist/rpmbuild/prelink_blacklist.conf.in"),
                                       prelink_target_filename,
                                       context=self.context)

            # Create a client config.
            client_context = ["Client Context"] + self.context
            client_config_content = build_helpers.GetClientConfig(
                client_context)

            with io.open(os.path.join(
                    target_binary_dir,
                    config.CONFIG.Get("ClientBuilder.config_filename",
                                      context=self.context)),
                         "w",
                         encoding="utf-8") as fd:
                fd.write(client_config_content)

            # Set the daemon to executable.
            os.chmod(os.path.join(target_binary_dir, client_binary_name),
                     0o755)

            client_arch = config.CONFIG.Get("Template.arch",
                                            context=self.context)
            if client_arch == "amd64":
                client_arch = "x86_64"

            # Create wrapper script
            if os.path.exists(os.path.join(target_binary_dir,
                                           "wrapper.sh.in")):
                build_helpers.GenerateFile(
                    os.path.join(target_binary_dir, "wrapper.sh.in"),
                    os.path.join(target_binary_dir, "wrapper.sh"),
                    context=self.context)
                os.chmod(os.path.join(target_binary_dir, "wrapper.sh"), 0o755)

            command = [
                rpmbuild_binary, "--define", "_topdir " + rpm_root_dir,
                "--target", client_arch, "--buildroot", rpm_buildroot_dir,
                "-bb", spec_filename
            ]
            try:
                subprocess.check_output(command, stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError as e:
                logging.error("Error calling %s.", command)
                logging.error(e.output)
                raise

            client_version = config.CONFIG.Get("Template.version_string",
                                               context=self.context)
            rpm_filename = os.path.join(
                rpm_rpms_dir, client_arch,
                "%s-%s-1.%s.rpm" % (client_name, client_version, client_arch))

            utils.EnsureDirExists(os.path.dirname(output_path))
            shutil.move(rpm_filename, output_path)

            logging.info("Created package %s", output_path)
            self._Sign(output_path)
            return output_path
Exemple #3
0
    def _GenerateDPKGFiles(self, template_path):
        """Generates the files needed by dpkg-buildpackage."""

        fleetspeak_enabled = config.CONFIG.Get("Client.fleetspeak_enabled",
                                               context=self.context)
        fleetspeak_bundled = config.CONFIG.Get(
            "ClientBuilder.fleetspeak_bundled", context=self.context)

        if fleetspeak_bundled and not fleetspeak_enabled:
            raise build.BuildError("ClientBuilder.fleetspeak_bundled requires "
                                   "Client.fleetspeak_enabled to be set.")

        # Rename the generated binaries to the correct name.
        template_binary_dir = os.path.join(template_path,
                                           "dist/debian/grr-client")
        package_name = config.CONFIG.Get("ClientBuilder.package_name",
                                         context=self.context)
        target_binary_dir = os.path.join(
            template_path,
            "dist/debian/%s%s" % (package_name,
                                  config.CONFIG.Get("ClientBuilder.target_dir",
                                                    context=self.context)))
        if package_name == "grr-client":
            # Need to rename the template path or the move will fail.
            shutil.move(template_binary_dir,
                        "%s-template" % template_binary_dir)
            template_binary_dir = "%s-template" % template_binary_dir

        utils.EnsureDirExists(os.path.dirname(target_binary_dir))
        shutil.move(template_binary_dir, target_binary_dir)

        shutil.move(
            os.path.join(target_binary_dir, "grr-client"),
            os.path.join(
                target_binary_dir,
                config.CONFIG.Get("Client.binary_name", context=self.context)))

        deb_in_dir = os.path.join(template_path, "dist/debian/debian.in/")

        if not os.path.isdir(deb_in_dir):
            # This is an universal (fleetspeak + legacy) template.
            # In prior versions, debian.in used to contain different files for a
            # fleetspeak-enabled and legacy template respectively.
            if fleetspeak_enabled:
                deb_in_dir = os.path.join(template_path,
                                          "dist/debian/fleetspeak-debian.in/")
            else:
                deb_in_dir = os.path.join(template_path,
                                          "dist/debian/legacy-debian.in/")

        build_helpers.GenerateDirectory(deb_in_dir,
                                        os.path.join(template_path,
                                                     "dist/debian"),
                                        [("grr-client", package_name)],
                                        context=self.context)

        # Generate directories for the /usr/sbin link.
        utils.EnsureDirExists(
            os.path.join(template_path,
                         "dist/debian/%s/usr/sbin" % package_name))

        if os.path.exists(os.path.join(target_binary_dir, "wrapper.sh.in")):
            build_helpers.GenerateFile(os.path.join(target_binary_dir,
                                                    "wrapper.sh.in"),
                                       os.path.join(target_binary_dir,
                                                    "wrapper.sh"),
                                       context=self.context)
            os.chmod(os.path.join(target_binary_dir, "wrapper.sh"), 0o755)

        if fleetspeak_enabled:
            if fleetspeak_bundled:
                self._GenerateFleetspeakConfig(
                    template_path, "/etc/fleetspeak-client/textservices")
                self._GenerateBundledFleetspeakFiles(
                    os.path.join(template_path, "dist/bundled-fleetspeak"),
                    os.path.join(template_path, "dist/debian", package_name))

                shutil.copy(
                    config.CONFIG.Get("ClientBuilder.fleetspeak_client_config",
                                      context=self.context),
                    os.path.join(template_path, "dist", "debian", package_name,
                                 "etc/fleetspeak-client/client.config"))

            else:
                fleetspeak_service_dir = config.CONFIG.Get(
                    "ClientBuilder.fleetspeak_service_dir",
                    context=self.context)
                self._GenerateFleetspeakConfig(template_path,
                                               fleetspeak_service_dir)
        else:
            # Generate the nanny template.
            # This exists from client version 3.1.2.5 onwards.
            build_helpers.GenerateFile(os.path.join(target_binary_dir,
                                                    "nanny.sh.in"),
                                       os.path.join(target_binary_dir,
                                                    "nanny.sh"),
                                       context=self.context)

            # Generate the upstart template.
            build_helpers.GenerateFile(
                os.path.join(template_path,
                             "dist/debian/upstart.in/grr-client.conf"),
                os.path.join(template_path,
                             "dist/debian/%s.upstart" % package_name),
                context=self.context)

            # Generate the initd template. The init will not run if it detects upstart
            # is present.
            build_helpers.GenerateFile(
                os.path.join(template_path, "dist/debian/initd.in/grr-client"),
                os.path.join(template_path,
                             "dist/debian/%s.init" % package_name),
                context=self.context)

            # Generate the systemd unit file.
            build_helpers.GenerateFile(
                os.path.join(template_path,
                             "dist/debian/systemd.in/grr-client.service"),
                os.path.join(template_path,
                             "dist/debian/%s.service" % package_name),
                context=self.context)

        # Clean up the template dirs.
        # Some of the dirs might be missing in older template versions, so removing
        # conditionally.
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/debian.in"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/fleetspeak-debian.in"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/legacy-debian.in"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/upstart.in"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/initd.in"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/debian/systemd.in"))
        self._RmTreeIfExists(os.path.join(template_path, "dist/fleetspeak"))
        self._RmTreeIfExists(
            os.path.join(template_path, "dist/bundled-fleetspeak"))