Ejemplo n.º 1
0
def FinalizeConfigInit(config,
                       admin_password: Optional[Text] = None,
                       redownload_templates: bool = False,
                       repack_templates: bool = True,
                       prompt: bool = True):
    """Performs the final steps of config initialization."""
    config.Set("Server.initialized", True)
    print("\nWriting configuration to %s." % config["Config.writeback"])
    config.Write()
    print("Initializing the datastore.")
    # Reload the config and initialize the GRR database.
    server_startup.Init()

    print("\nStep 3: Adding GRR Admin User")
    try:
        CreateUser("admin", password=admin_password, is_admin=True)
    except UserAlreadyExistsError:
        if prompt:
            # pytype: disable=wrong-arg-count
            if ((input("User 'admin' already exists, do you want to "
                       "reset the password? [yN]: ").upper() or "N") == "Y"):
                UpdateUser("admin", password=admin_password, is_admin=True)
            # pytype: enable=wrong-arg-count
        else:
            UpdateUser("admin", password=admin_password, is_admin=True)

    print("\nStep 4: Repackaging clients with new configuration.")
    if prompt:
        redownload_templates = RetryBoolQuestion(
            "Server debs include client templates. Re-download templates?",
            False)
        repack_templates = RetryBoolQuestion("Repack client templates?", True)
    if redownload_templates:
        InstallTemplatePackage()
    # Build debug binaries, then build release binaries.
    if repack_templates:
        repacking.TemplateRepacker().RepackAllTemplates(upload=True)
    print("\nGRR Initialization complete! You can edit the new configuration "
          "in %s.\n" % config["Config.writeback"])
    if prompt and os.geteuid() == 0:
        restart = RetryBoolQuestion(
            "Restart service for the new configuration "
            "to take effect?", True)
        if restart:
            for service in ("grr-server", "fleetspeak-server"):
                try:
                    print(f"Restarting service: {service}.")
                    subprocess.check_call(["service", service, "restart"])
                except subprocess.CalledProcessError as e:
                    print(f"Failed to restart: {service}.")
                    print(e, file=sys.stderr)
    else:
        print("Please restart the service for the new configuration to take "
              "effect.\n")
Ejemplo n.º 2
0
    def testRepackAll(self):
        """Test repacking all binaries."""
        self.executables_dir = package.ResourcePath("grr-response-core",
                                                    "executables")
        with utils.TempDirectory() as tmp_dir:
            new_dir = os.path.join(tmp_dir, "grr", "executables")
            os.makedirs(new_dir)

            # Copy unzipsfx so it can be used in repacking/
            shutil.copy(
                os.path.join(self.executables_dir,
                             "windows/templates/unzipsfx/unzipsfx-i386.exe"),
                new_dir)
            shutil.copy(
                os.path.join(self.executables_dir,
                             "windows/templates/unzipsfx/unzipsfx-amd64.exe"),
                new_dir)

            with test_lib.ConfigOverrider({
                    "ClientBuilder.executables_dir":
                    new_dir,
                    "ClientBuilder.unzipsfx_stub_dir":
                    new_dir
            }):
                repacking.TemplateRepacker().RepackAllTemplates()

            self.assertEqual(
                len(glob.glob(os.path.join(new_dir, "installers/*.deb"))), 2)
            self.assertEqual(
                len(glob.glob(os.path.join(new_dir, "installers/*.rpm"))), 2)
            self.assertEqual(
                len(glob.glob(os.path.join(new_dir, "installers/*.exe"))), 4)
            self.assertEqual(
                len(glob.glob(os.path.join(new_dir, "installers/*.pkg"))), 1)

            # Validate the config appended to the OS X package.
            zf = zipfile.ZipFile(glob.glob(
                os.path.join(new_dir, "installers/*.pkg")).pop(),
                                 mode="r")
            fd = zf.open("config.yaml")

            # We can't load the included build.yaml because the package hasn't been
            # installed.
            loaded = yaml.Parse(fd.read().decode("utf-8"))
            loaded.pop("Config.includes")

            packaged_config = config.CONFIG.MakeNewConfig()
            data = yaml.Dump(loaded)
            packaged_config.Initialize(parser=config_lib.YamlParser, data=data)
            packaged_config.Validate(
                sections=build.ClientRepacker.CONFIG_SECTIONS)
            repacker = build.ClientRepacker()
            repacker.ValidateEndConfig(packaged_config)
Ejemplo n.º 3
0
def FinalizeConfigInit(config,
                       token,
                       admin_password=None,
                       redownload_templates=False,
                       repack_templates=True,
                       prompt=True):
    """Performs the final steps of config initialization."""
    config.Set("Server.initialized", True)
    print("\nWriting configuration to %s." % config["Config.writeback"])
    config.Write()
    print("Initializing the datastore.")
    # Reload the config and initialize the GRR database.
    server_startup.Init()

    print("\nStep 3: Adding GRR Admin User")
    try:
        CreateUser("admin", password=admin_password, is_admin=True)
    except UserAlreadyExistsError:
        if prompt:
            # pytype: disable=wrong-arg-count
            if ((builtins.input("User 'admin' already exists, do you want to "
                                "reset the password? [yN]: ").upper()
                 or "N") == "Y"):
                UpdateUser("admin", password=admin_password, is_admin=True)
            # pytype: enable=wrong-arg-count
        else:
            UpdateUser("admin", password=admin_password, is_admin=True)

    print("\nStep 4: Repackaging clients with new configuration.")
    if prompt:
        redownload_templates = RetryBoolQuestion(
            "Server debs include client templates. Re-download templates?",
            False)
        repack_templates = RetryBoolQuestion("Repack client templates?", True)
    if redownload_templates:
        InstallTemplatePackage()
    # Build debug binaries, then build release binaries.
    if repack_templates:
        repacking.TemplateRepacker().RepackAllTemplates(upload=True,
                                                        token=token)
    print("\nGRR Initialization complete! You can edit the new configuration "
          "in %s.\n" % config["Config.writeback"])
    print("Please restart the service for the new configuration to take "
          "effect.\n")
Ejemplo n.º 4
0
def main(args):
    """Launch the appropriate builder."""

    grr_config.CONFIG.AddContext(contexts.CLIENT_BUILD_CONTEXT)

    if args.subparser_name == "generate_client_config":
        # We don't need a full init to just build a config.
        GetClientConfig(args.client_config_output)
        return

    # TODO(user): Find out if adding the client-builder context is still
    # necessary.
    context = FLAGS.context
    context.append(contexts.CLIENT_BUILD_CONTEXT)

    config_lib.SetPlatformArchContext()
    config_lib.ParseConfigCommandLine()

    # Use basic console output logging so we can see what is happening.
    logger = logging.getLogger()
    handler = logging.StreamHandler()
    handler.setLevel(logging.DEBUG if FLAGS.verbose else logging.INFO)
    logger.handlers = [handler]

    if args.subparser_name == "build":
        if grr_config.CONFIG["Client.fleetspeak_enabled"]:
            if grr_config.CONFIG.ContextApplied("Platform:Darwin"):
                if not grr_config.CONFIG.Get("ClientBuilder.install_dir"):
                    raise RuntimeError(
                        "ClientBuilder.install_dir must be set.")
                if not grr_config.CONFIG.Get(
                        "ClientBuilder.fleetspeak_plist_path"):
                    raise RuntimeError(
                        "ClientBuilder.fleetspeak_plist_path must be set.")
        TemplateBuilder().BuildTemplate(context=context, output=args.output)
    elif args.subparser_name == "repack":
        if args.debug_build:
            context.append("DebugClientBuild Context")
        result_path = repacking.TemplateRepacker().RepackTemplate(
            args.template,
            args.output_dir,
            context=context,
            sign=args.sign,
            signed_template=args.signed_template)

        if not result_path:
            raise ErrorDuringRepacking(" ".join(sys.argv[:]))
    elif args.subparser_name == "repack_multiple":

        # Resolve globs manually on Windows.
        templates = []
        for template in args.templates:
            if "*" in template:
                templates.extend(glob.glob(template))
            else:
                # This could go through glob but then we'd swallow errors for
                # non existing files.
                templates.append(template)

        repack_configs = []
        for repack_config in args.repack_configs:
            if "*" in repack_config:
                repack_configs.extend(glob.glob(repack_config))
            else:
                # This could go through glob but then we'd swallow errors for
                # non existing files.
                repack_configs.append(repack_config)

        MultiTemplateRepacker().RepackTemplates(
            repack_configs,
            templates,
            args.output_dir,
            config=FLAGS.config,
            sign=args.sign,
            signed_template=args.signed_template)
    elif args.subparser_name == "sign_template":
        repacking.TemplateRepacker().SignTemplate(args.template,
                                                  args.output_file,
                                                  context=context)
        if not os.path.exists(args.output_file):
            raise RuntimeError("Signing failed: output not written")
Ejemplo n.º 5
0
    def RepackTemplates(self,
                        repack_configs,
                        templates,
                        output_dir,
                        config=None,
                        sign=False,
                        signed_template=False):
        """Call repacker in a subprocess."""
        pool = multiprocessing.Pool(processes=10)
        results = []
        bulk_sign_installers = False
        for repack_config in repack_configs:
            for template in templates:
                repack_args = ["grr_client_build"]
                if config:
                    repack_args.extend(["--config", config])

                repack_args.extend([
                    "--secondary_configs", repack_config, "repack",
                    "--template", template, "--output_dir",
                    self.GetOutputDir(output_dir, repack_config)
                ])

                # We only sign exes and rpms at the moment. The others will raise if we
                # try to ask for signing.
                passwd = None

                if sign:
                    if template.endswith(".exe.zip") or template.endswith(
                            ".msi.zip"):
                        # This is for osslsigncode only.
                        if platform.system() != "Windows":
                            passwd = self.GetWindowsPassphrase()
                            repack_args.append("--sign")
                        else:
                            if template.endswith(".msi.zip"):
                                repack_args.append("--sign")
                            else:
                                bulk_sign_installers = True
                        if signed_template:
                            repack_args.append("--signed_template")
                    elif template.endswith(".rpm.zip"):
                        bulk_sign_installers = True

                print("Calling %s" % " ".join(repack_args))
                results.append(
                    pool.apply_async(SpawnProcess, (repack_args, ),
                                     dict(passwd=passwd)))

                # Also build debug if it's windows.
                if template.endswith(".exe.zip") or template.endswith(
                        ".msi.zip"):
                    debug_args = []
                    debug_args.extend(repack_args)
                    debug_args.append("--debug_build")
                    print("Calling %s" % " ".join(debug_args))
                    results.append(
                        pool.apply_async(SpawnProcess, (debug_args, ),
                                         dict(passwd=passwd)))

        try:
            pool.close()
            # Workaround to handle keyboard kills
            # http://stackoverflow.com/questions/1408356/keyboard-interrupts-with-pythons-multiprocessing-pool
            # get will raise if the child raises.
            for result_obj in results:
                result_obj.get(9999)
            pool.join()
        except KeyboardInterrupt:
            print("parent received control-c")
            pool.terminate()
        except ErrorDuringRepacking:
            pool.terminate()
            raise

        if bulk_sign_installers:
            to_sign = {}
            for root, _, files in os.walk(output_dir):
                for f in files:
                    if f.endswith(".exe"):
                        to_sign.setdefault("windows",
                                           []).append(os.path.join(root, f))
                    elif f.endswith(".rpm"):
                        to_sign.setdefault("rpm",
                                           []).append(os.path.join(root, f))
            if to_sign.get("windows"):
                signer = repacking.TemplateRepacker().GetSigner([
                    "ClientBuilder Context",
                    "Platform:%s" % platform.system(), "Target:Windows"
                ])
                signer.SignFiles(to_sign.get("windows"))
            if to_sign.get("rpm"):
                signer = repacking.TemplateRepacker().GetSigner([
                    "ClientBuilder Context",
                    "Platform:%s" % platform.system(), "Target:Linux",
                    "Target:LinuxRpm"
                ])
                signer.AddSignatureToRPMs(to_sign.get("rpm"))
Ejemplo n.º 6
0
def main(args):
    """Main."""
    grr_config.CONFIG.AddContext(contexts.COMMAND_LINE_CONTEXT)
    grr_config.CONFIG.AddContext(contexts.CONFIG_UPDATER_CONTEXT)

    if args.subparser_name == "initialize":
        config_lib.ParseConfigCommandLine()
        if args.noprompt:
            config_updater_util.InitializeNoPrompt(
                grr_config.CONFIG,
                external_hostname=args.external_hostname,
                admin_password=args.admin_password,
                mysql_hostname=args.mysql_hostname,
                mysql_port=args.mysql_port,
                mysql_username=args.mysql_username,
                mysql_password=args.mysql_password,
                mysql_db=args.mysql_db,
                mysql_client_key_path=args.mysql_client_key_path,
                mysql_client_cert_path=args.mysql_client_cert_path,
                mysql_ca_cert_path=args.mysql_ca_cert_path,
                redownload_templates=args.redownload_templates,
                repack_templates=not args.norepack_templates)
        else:
            config_updater_util.Initialize(
                grr_config.CONFIG,
                external_hostname=args.external_hostname,
                admin_password=args.admin_password,
                redownload_templates=args.redownload_templates,
                repack_templates=not args.norepack_templates)
        return

    server_startup.Init()

    try:
        print("Using configuration %s" % grr_config.CONFIG)
    except AttributeError:
        raise RuntimeError("No valid config specified.")

    if args.subparser_name == "generate_keys":
        try:
            config_updater_keys_util.GenerateKeys(
                grr_config.CONFIG, overwrite_keys=args.overwrite_keys)
        except RuntimeError as e:
            # GenerateKeys will raise if keys exist and overwrite_keys is not set.
            print("ERROR: %s" % e)
            sys.exit(1)
        grr_config.CONFIG.Write()

    elif args.subparser_name == "repack_clients":
        upload = not args.noupload
        repacking.TemplateRepacker().RepackAllTemplates(upload=upload)

    elif args.subparser_name == "show_user":
        if args.username:
            print(config_updater_util.GetUserSummary(args.username))
        else:
            print(config_updater_util.GetAllUserSummaries())

    elif args.subparser_name == "update_user":
        config_updater_util.UpdateUser(args.username,
                                       password=args.password,
                                       is_admin=args.admin)

    elif args.subparser_name == "delete_user":
        config_updater_util.DeleteUser(args.username)

    elif args.subparser_name == "add_user":
        config_updater_util.CreateUser(args.username,
                                       password=args.password,
                                       is_admin=args.admin)

    elif args.subparser_name == "upload_python":
        config_updater_util.UploadSignedBinary(
            args.file,
            rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK,
            args.platform,
            upload_subdirectory=args.upload_subdirectory)

    elif args.subparser_name == "upload_exe":
        config_updater_util.UploadSignedBinary(
            args.file,
            rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE,
            args.platform,
            upload_subdirectory=args.upload_subdirectory)

    elif args.subparser_name == "set_var":
        var = args.var
        val = args.val

        config = grr_config.CONFIG
        print("Setting %s to %s" % (var, val))
        if val.startswith("["):  # Allow setting of basic lists.
            val = val[1:-1].split(",")
        config.Set(var, val)
        config.Write()

    elif args.subparser_name == "switch_datastore":
        config_updater_util.SwitchToRelDB(grr_config.CONFIG)
        grr_config.CONFIG.Write()

    elif args.subparser_name == "upload_artifact":
        with io.open(args.file, "r") as filedesc:
            source = filedesc.read()
        try:
            artifact.UploadArtifactYamlFile(source,
                                            overwrite=args.overwrite_artifact)
        except rdf_artifacts.ArtifactDefinitionError as e:
            print("Error %s. You may need to set --overwrite_artifact." % e)

    elif args.subparser_name == "delete_artifacts":
        artifact_list = args.artifact
        if not artifact_list:
            raise ValueError("No artifact to delete given.")
        artifact_registry.DeleteArtifactsFromDatastore(artifact_list)
        print("Artifacts %s deleted." % artifact_list)

    elif args.subparser_name == "rotate_server_key":
        print("""
You are about to rotate the server key. Note that:

  - Clients might experience intermittent connection problems after
    the server keys rotated.

  - It's not possible to go back to an earlier key. Clients that see a
    new certificate will remember the cert's serial number and refuse
    to accept any certificate with a smaller serial number from that
    point on.
    """)

        if input("Continue? [yN]: ").upper() == "Y":
            if args.keylength:
                keylength = int(args.keylength)
            else:
                keylength = grr_config.CONFIG["Server.rsa_key_length"]

            maintenance_utils.RotateServerKey(cn=args.common_name,
                                              keylength=keylength)