malwaredb 0.3.2

Service for storing malicious, benign, or unknown files and related metadata and relationships.
// SPDX-License-Identifier: Apache-2.0

use super::Installer;

use std::path::PathBuf;
use std::process::ExitCode;

use anyhow::{ensure, Result};
use clap::Parser;

const LAUNCH_PATH: &str = "/Library/LaunchDaemons/malwaredb.plist";

/// Install Malware DB as a system service
#[derive(Parser, Debug, Clone, PartialEq)]
pub struct Install {
    /// Use custom configuration file path
    #[arg(value_hint = clap::ValueHint::FilePath)]
    pub config: Option<PathBuf>,
}

impl Install {
    pub(crate) fn gen_config(&self) -> Result<String> {
        let exec = std::env::current_exe().unwrap();
        let exec = exec.to_str().unwrap();

        let optional_config = if let Some(config) = &self.config {
            let config = config.to_str().unwrap();
            ensure!(
                config.starts_with('/'),
                "Must use an absolute path for the config file"
            );
            format!(
                "
        <string>load</string>
        <string>{config}</string>
        "
            )
        } else {
            String::new()
        };

        Ok(format!(
            "<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"
\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version='1.0'>
	<dict>
		<key>EnvironmentVariables</key>
		<dict>
			<key>SERVICE_RUN_MODE</key>
			<string>1</string>
		</dict>
		<key>Label</key>
		<string>MalwareDB</string>
		<key>ProgramArguments</key>
		<array>
			<string>{exec}</string>
			<string>run</string>{optional_config}
		</array>
		<key>KeepAlive</key>
		<true/>
		<key>RunAtLoad</key>
		<true/>
		<key>Disabled</key>
		<false/>
	</dict>
</plist>
",
        ))
    }
}

impl Installer for Install {
    fn do_install(&self) -> Result<ExitCode> {
        let config = self.gen_config()?;
        std::fs::write(LAUNCH_PATH, config)?;
        Ok(ExitCode::SUCCESS)
    }
}