Skip to main content

ploit_malper/
config.rs

1use std::env;
2use std::fs;
3use std::path::PathBuf;
4
5use serde::{Deserialize, Serialize};
6
7use crate::error::Result;
8
9fn home_dir() -> PathBuf {
10    if let Some(home) = env::var_os("HOME") {
11        PathBuf::from(home)
12    } else if let Some(profile) = env::var_os("USERPROFILE") {
13        PathBuf::from(profile)
14    } else {
15        env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
16    }
17}
18
19pub fn config_dir() -> PathBuf {
20    home_dir().join(".config").join("ploit_malper")
21}
22
23pub fn config_file() -> PathBuf {
24    config_dir().join("config.json")
25}
26
27pub fn nvd_cache_file() -> PathBuf {
28    config_dir().join("nvd_cache.json")
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(default)]
33pub struct MSFRPCConfig {
34    pub host: String,
35    pub port: u16,
36    pub username: String,
37    pub password: String,
38    pub ssl: bool,
39    pub workspace: String,
40}
41
42impl Default for MSFRPCConfig {
43    fn default() -> Self {
44        Self {
45            host: "127.0.0.1".to_string(),
46            port: 55553,
47            username: "msf".to_string(),
48            password: String::new(),
49            ssl: true,
50            workspace: "default".to_string(),
51        }
52    }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, Default)]
56#[serde(default)]
57pub struct NVDConfig {
58    pub api_key: String,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(default)]
63pub struct AppConfig {
64    pub msfrpc: MSFRPCConfig,
65    pub nvd: NVDConfig,
66    pub report_dir: String,
67    pub last_scan_file: Option<String>,
68}
69
70impl Default for AppConfig {
71    fn default() -> Self {
72        Self {
73            msfrpc: MSFRPCConfig::default(),
74            nvd: NVDConfig::default(),
75            report_dir: home_dir()
76                .join("ploit_malper_reports")
77                .to_string_lossy()
78                .to_string(),
79            last_scan_file: None,
80        }
81    }
82}
83
84#[derive(Debug, Clone)]
85pub struct ConfigManager {
86    pub config: AppConfig,
87    loaded: bool,
88}
89
90impl ConfigManager {
91    pub fn new() -> Self {
92        Self {
93            config: AppConfig::default(),
94            loaded: false,
95        }
96    }
97
98    pub fn load(&mut self) -> bool {
99        let path = config_file();
100        if !path.exists() {
101            return false;
102        }
103
104        match fs::read_to_string(&path) {
105            Ok(raw) => match serde_json::from_str::<AppConfig>(&raw) {
106                Ok(config) => {
107                    self.config = config;
108                    self.loaded = true;
109                    true
110                }
111                Err(_) => false,
112            },
113            Err(_) => false,
114        }
115    }
116
117    pub fn save(&mut self) -> Result<()> {
118        let dir = config_dir();
119        fs::create_dir_all(&dir)?;
120        let path = config_file();
121        let data = serde_json::to_string_pretty(&self.config)?;
122        fs::write(path, data)?;
123        self.loaded = true;
124        Ok(())
125    }
126
127    pub fn reset(&mut self) -> Result<()> {
128        let config_path = config_file();
129        if config_path.exists() {
130            fs::remove_file(config_path)?;
131        }
132
133        let cache_path = nvd_cache_file();
134        if cache_path.exists() {
135            fs::remove_file(cache_path)?;
136        }
137
138        self.config = AppConfig::default();
139        self.loaded = false;
140        Ok(())
141    }
142
143    pub fn is_configured(&self) -> bool {
144        self.loaded && !self.config.msfrpc.password.is_empty()
145    }
146
147    pub fn is_nvd_configured(&self) -> bool {
148        !self.config.nvd.api_key.is_empty()
149    }
150
151    pub fn get_msfrpc_config(&self) -> &MSFRPCConfig {
152        &self.config.msfrpc
153    }
154
155    pub fn get_nvd_config(&self) -> &NVDConfig {
156        &self.config.nvd
157    }
158}
159
160impl Default for ConfigManager {
161    fn default() -> Self {
162        Self::new()
163    }
164}