use std::{
env,
error::Error,
fs::{self, OpenOptions},
io::{Read, Write},
path::Path,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct KdfObject {
pub algorithm: String,
pub parameters: Option<KdfParams>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct KdfParams {
pub iterations: u8,
pub threads: u8,
pub memory: u32,
}
impl Default for KdfParams {
fn default() -> Self {
KdfParams {
iterations: 2,
threads: 1,
memory: 19 * 1024,
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct AlgorithmConfig {
pub encryption: String,
pub hash: String,
pub kdf: KdfObject,
pub compression: bool,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Config {
pub db_path: String,
pub algorithms: AlgorithmConfig,
pub lock_timeout: u32,
pub debug_mode: bool,
}
pub fn default_config() -> Config {
let mut default_path = home::home_dir().unwrap_or_else(env::temp_dir);
default_path.push(".deadbolt");
default_path.push("database.dblt");
Config {
db_path: default_path.to_string_lossy().to_string(),
algorithms: AlgorithmConfig {
encryption: "aes-gcm".to_string(),
hash: "sha-256".to_string(),
kdf: KdfObject {
algorithm: "argon2d".to_string(),
parameters: Some(KdfParams::default()),
},
compression: true,
},
lock_timeout: 1800,
debug_mode: false,
}
}
pub fn get_config(path: &str) -> Result<Config, Box<dyn Error>> {
let mut file = OpenOptions::new().read(true).open(path)?;
let mut buf: String = Default::default();
file.read_to_string(&mut buf)?;
let value: Config = serde_yaml::from_str(&buf)?;
Ok(value)
}
pub fn set_config(path: &str, config: &Config) -> Result<(), Box<dyn Error>> {
let yaml = serde_yaml::to_string(&config)?;
let parent = Path::new(path).parent();
if let Some(parent_dir) = parent {
fs::create_dir_all(parent_dir)?;
}
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)?;
file.write_all(yaml.as_bytes())?;
Ok(())
}