2022-09-26 07:43:49 +00:00
|
|
|
use std::{
|
|
|
|
env, fs,
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
};
|
2022-09-24 16:23:53 +00:00
|
|
|
|
2023-08-17 20:09:44 +00:00
|
|
|
use anyhow::{Context, Result};
|
2022-09-26 07:43:49 +00:00
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2022-09-24 16:23:53 +00:00
|
|
|
|
2022-09-26 07:43:49 +00:00
|
|
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
2022-09-24 16:23:53 +00:00
|
|
|
pub struct Config {
|
|
|
|
/// Bind on address address. eg. `127.0.0.1:1080`
|
2022-09-26 07:43:49 +00:00
|
|
|
#[serde(default = "default_listen_addr")]
|
2022-09-24 16:23:53 +00:00
|
|
|
pub listen_addr: String,
|
|
|
|
/// Request timeout
|
2022-09-26 07:43:49 +00:00
|
|
|
#[serde(default = "default_timeout")]
|
2022-09-24 16:23:53 +00:00
|
|
|
pub request_timeout: u64,
|
|
|
|
/// Authentication
|
|
|
|
#[serde(default)]
|
|
|
|
pub auth: Option<PasswordAuth>,
|
|
|
|
/// Avoid useless roundtrips if we don't need the Authentication layer
|
|
|
|
#[serde(default)]
|
|
|
|
pub skip_auth: bool,
|
|
|
|
/// Enable dns-resolving
|
|
|
|
#[serde(default = "default_true")]
|
|
|
|
pub dns_resolve: bool,
|
|
|
|
/// Enable command execution
|
|
|
|
#[serde(default = "default_true")]
|
|
|
|
pub execute_command: bool,
|
|
|
|
/// Enable UDP support
|
|
|
|
#[serde(default = "default_true")]
|
|
|
|
pub allow_udp: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_true() -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-09-26 07:43:49 +00:00
|
|
|
fn default_timeout() -> u64 {
|
|
|
|
60
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_listen_addr() -> String {
|
|
|
|
"127.0.0.1:1080".into()
|
|
|
|
}
|
|
|
|
|
2022-09-24 16:23:53 +00:00
|
|
|
/// Password authentication data
|
2022-09-26 07:43:49 +00:00
|
|
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
2022-09-24 16:23:53 +00:00
|
|
|
pub struct PasswordAuth {
|
|
|
|
pub username: String,
|
|
|
|
pub password: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
fn default() -> Self {
|
|
|
|
Config {
|
2022-09-26 07:43:49 +00:00
|
|
|
listen_addr: default_listen_addr(),
|
|
|
|
request_timeout: default_timeout(),
|
2022-09-24 16:23:53 +00:00
|
|
|
auth: None,
|
|
|
|
skip_auth: false,
|
|
|
|
dns_resolve: true,
|
|
|
|
execute_command: true,
|
|
|
|
allow_udp: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Config {
|
|
|
|
const FILENAME: &'static str = "config.toml";
|
2023-08-17 20:09:44 +00:00
|
|
|
fn read<P: AsRef<Path>>(path: P) -> Result<Self> {
|
|
|
|
let data = fs::read_to_string(path).context("can't read config")?;
|
|
|
|
toml::from_str(&data).context("can't parse config")
|
2022-09-26 07:43:49 +00:00
|
|
|
}
|
2023-08-17 20:09:44 +00:00
|
|
|
fn write<P: AsRef<Path>>(&self, path: P) -> Result<()> {
|
|
|
|
let data = toml::to_string_pretty(&self).context("can't serialize config")?;
|
|
|
|
fs::write(path, data).context("can't write config")
|
2022-09-24 16:23:53 +00:00
|
|
|
}
|
2023-08-17 20:09:44 +00:00
|
|
|
fn file_location() -> Result<PathBuf> {
|
2022-09-26 07:43:49 +00:00
|
|
|
let res = env::current_exe()
|
2023-08-17 20:09:44 +00:00
|
|
|
.context("can't get current exe path")?
|
2022-09-26 07:43:49 +00:00
|
|
|
.with_file_name(Config::FILENAME);
|
2022-09-24 16:23:53 +00:00
|
|
|
Ok(res)
|
|
|
|
}
|
|
|
|
pub fn get() -> Self {
|
|
|
|
let path = Config::file_location();
|
2022-09-26 07:43:49 +00:00
|
|
|
if let Err(e) = path {
|
2023-08-17 20:09:44 +00:00
|
|
|
log::error!(r#"Error: "{e}", using default config"#);
|
2022-09-24 16:23:53 +00:00
|
|
|
return Config::default();
|
|
|
|
}
|
|
|
|
|
|
|
|
let path = path.unwrap();
|
2022-09-26 07:43:49 +00:00
|
|
|
let cfg = Config::read(path);
|
2022-09-24 16:23:53 +00:00
|
|
|
match cfg {
|
|
|
|
Err(e) => {
|
2023-08-17 20:09:44 +00:00
|
|
|
log::error!(r#"Error: "{e}", using default config"#);
|
2022-09-24 16:23:53 +00:00
|
|
|
Config::default()
|
|
|
|
}
|
|
|
|
Ok(cfg) => cfg,
|
|
|
|
}
|
|
|
|
}
|
2022-09-26 07:43:49 +00:00
|
|
|
pub fn save(&self) {
|
|
|
|
let path = Config::file_location();
|
|
|
|
if let Err(ref e) = path {
|
|
|
|
log::error!("save error: {}", &e);
|
|
|
|
}
|
|
|
|
let path = path.unwrap();
|
|
|
|
|
|
|
|
let res = self.write(&path);
|
|
|
|
if let Err(e) = res {
|
2023-08-17 20:09:44 +00:00
|
|
|
log::error!("save error: {}", &e);
|
2022-09-26 07:43:49 +00:00
|
|
|
} else {
|
2023-08-17 20:09:44 +00:00
|
|
|
log::info!(r#"config saved to: "{}""#, path.to_str().unwrap());
|
2022-09-26 07:43:49 +00:00
|
|
|
}
|
|
|
|
}
|
2022-09-24 16:23:53 +00:00
|
|
|
}
|