feat: v1.8.4, load config from multipl locations
This commit is contained in:
@@ -7,7 +7,6 @@ use tabled::{Table, Tabled};
|
||||
use tabled::settings::Style;
|
||||
|
||||
use crate::config::TinyEncryptConfig;
|
||||
use crate::consts::TINY_ENC_CONFIG_FILE;
|
||||
use crate::util_envelop;
|
||||
|
||||
#[derive(Tabled, Eq)]
|
||||
@@ -57,7 +56,7 @@ pub struct CmdConfig {
|
||||
}
|
||||
|
||||
pub fn config(cmd_version: CmdConfig) -> XResult<()> {
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE)?;
|
||||
let config = TinyEncryptConfig::load_default()?;
|
||||
|
||||
if cmd_version.profile.is_some() || cmd_version.key_filter.is_some() {
|
||||
return config_key_filter(&cmd_version, &config);
|
||||
|
||||
@@ -31,7 +31,7 @@ use crate::consts::{
|
||||
ENC_AES256_GCM_KYBER1204, ENC_AES256_GCM_P256, ENC_AES256_GCM_P384,
|
||||
ENC_AES256_GCM_X25519, ENC_CHACHA20_POLY1305_KYBER1204, ENC_CHACHA20_POLY1305_P256,
|
||||
ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519,
|
||||
SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT,
|
||||
SALT_COMMENT, TINY_ENC_FILE_EXT,
|
||||
};
|
||||
use crate::crypto_cryptor::{Cryptor, KeyNonce};
|
||||
use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
|
||||
@@ -105,7 +105,7 @@ impl Drop for CmdDecrypt {
|
||||
pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
|
||||
if cmd_decrypt.split_print { util_msg::set_logger_std_out(false); }
|
||||
debugging!("Cmd decrypt: {:?}", cmd_decrypt);
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
|
||||
let config = TinyEncryptConfig::load_default().ok();
|
||||
|
||||
let start = Instant::now();
|
||||
let mut succeed_count = 0;
|
||||
|
||||
@@ -12,7 +12,12 @@ use rust_util::{debugging, failure, iff, information, opt_result, simple_error,
|
||||
|
||||
use crate::compress::GzStreamEncoder;
|
||||
use crate::config::{TinyEncryptConfig, TinyEncryptConfigEnvelop};
|
||||
use crate::consts::{ENC_AES256_GCM_KYBER1204, ENC_AES256_GCM_P256, ENC_AES256_GCM_P384, ENC_AES256_GCM_X25519, ENC_CHACHA20_POLY1305_KYBER1204, ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384, ENC_CHACHA20_POLY1305_X25519, SALT_COMMENT, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT, TINY_ENC_PEM_FILE_EXT, TINY_ENC_PEM_NAME};
|
||||
use crate::consts::{
|
||||
ENC_AES256_GCM_KYBER1204, ENC_AES256_GCM_P256, ENC_AES256_GCM_P384, ENC_AES256_GCM_X25519,
|
||||
ENC_CHACHA20_POLY1305_KYBER1204, ENC_CHACHA20_POLY1305_P256, ENC_CHACHA20_POLY1305_P384,
|
||||
ENC_CHACHA20_POLY1305_X25519, SALT_COMMENT, TINY_ENC_FILE_EXT, TINY_ENC_PEM_FILE_EXT,
|
||||
TINY_ENC_PEM_NAME,
|
||||
};
|
||||
use crate::crypto_cryptor::{Cryptor, KeyNonce};
|
||||
use crate::spec::{
|
||||
EncEncryptedMeta, EncMetadata,
|
||||
@@ -76,7 +81,7 @@ pub struct CmdEncrypt {
|
||||
}
|
||||
|
||||
pub fn encrypt(cmd_encrypt: CmdEncrypt) -> XResult<()> {
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE)?;
|
||||
let config = TinyEncryptConfig::load_default()?;
|
||||
debugging!("Found tiny encrypt config: {:?}", config);
|
||||
let envelops = config.find_envelops(&cmd_encrypt.profile, &cmd_encrypt.key_filter)?;
|
||||
if envelops.is_empty() { return simple_error!("Cannot find any valid envelops"); }
|
||||
|
||||
@@ -11,7 +11,6 @@ use zeroize::Zeroize;
|
||||
use crate::{config, consts, util, util_env};
|
||||
use crate::cmd_decrypt::{decrypt_limited_content_to_vec, select_envelop, try_decrypt_key};
|
||||
use crate::config::TinyEncryptConfig;
|
||||
use crate::consts::TINY_ENC_CONFIG_FILE;
|
||||
use crate::crypto_cryptor::{Cryptor, KeyNonce};
|
||||
use crate::util::SecVec;
|
||||
use crate::util_enc_file;
|
||||
@@ -46,7 +45,7 @@ impl Drop for CmdExecEnv {
|
||||
pub fn exec_env(cmd_exec_env: CmdExecEnv) -> XResult<()> {
|
||||
util_msg::set_logger_std_out(false);
|
||||
debugging!("Cmd exec env: {:?}", cmd_exec_env);
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
|
||||
let config = TinyEncryptConfig::load_default().ok();
|
||||
if cmd_exec_env.command_arguments.is_empty() {
|
||||
return simple_error!("No commands assigned.");
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use simpledateformat::format_human2;
|
||||
|
||||
use crate::{config, util, util_enc_file, util_envelop};
|
||||
use crate::config::TinyEncryptConfig;
|
||||
use crate::consts::{DATE_TIME_FORMAT, TINY_ENC_AES_GCM, TINY_ENC_CONFIG_FILE};
|
||||
use crate::consts::{DATE_TIME_FORMAT, TINY_ENC_AES_GCM};
|
||||
use crate::util::is_tiny_enc_file;
|
||||
use crate::wrap_key::WrapKey;
|
||||
|
||||
@@ -28,7 +28,7 @@ pub struct CmdInfo {
|
||||
}
|
||||
|
||||
pub fn info(cmd_info: CmdInfo) -> XResult<()> {
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
|
||||
let config = TinyEncryptConfig::load_default().ok();
|
||||
for (i, path) in cmd_info.paths.iter().enumerate() {
|
||||
let path = config::resolve_path_namespace(&config, path, true);
|
||||
if i > 0 { println!("{}", "-".repeat(88)); }
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::config::TinyEncryptConfig;
|
||||
use crate::consts::TINY_ENC_CONFIG_FILE;
|
||||
use crate::spec::TinyEncryptEnvelop;
|
||||
use crate::{cmd_encrypt, crypto_cryptor, util, util_env};
|
||||
use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD};
|
||||
@@ -164,7 +163,7 @@ pub fn simple_decrypt(cmd_simple_decrypt: CmdSimpleDecrypt) -> XResult<()> {
|
||||
}
|
||||
|
||||
pub fn inner_simple_encrypt(cmd_simple_encrypt: CmdSimpleEncrypt) -> XResult<()> {
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE)?;
|
||||
let config = TinyEncryptConfig::load_default()?;
|
||||
debugging!("Found tiny encrypt config: {:?}", config);
|
||||
let envelops = config.find_envelops(&cmd_simple_encrypt.profile, &cmd_simple_encrypt.key_filter)?;
|
||||
if envelops.is_empty() { return simple_error!("Cannot find any valid envelops"); }
|
||||
@@ -197,7 +196,7 @@ pub fn inner_simple_encrypt(cmd_simple_encrypt: CmdSimpleEncrypt) -> XResult<()>
|
||||
|
||||
#[cfg(feature = "decrypt")]
|
||||
pub fn inner_simple_decrypt(cmd_simple_decrypt: CmdSimpleDecrypt) -> XResult<()> {
|
||||
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
|
||||
let config = TinyEncryptConfig::load_default().ok();
|
||||
|
||||
let pin = cmd_simple_decrypt.pin.clone().or_else(util_env::get_pin);
|
||||
let slot = cmd_simple_decrypt.slot.clone();
|
||||
|
||||
109
src/config.rs
109
src/config.rs
@@ -1,14 +1,14 @@
|
||||
use std::{env, fs};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
|
||||
use rust_util::{debugging, opt_result, simple_error, warning, XResult};
|
||||
use rust_util::util_file::resolve_file_path;
|
||||
use rust_util::{debugging, opt_result, simple_error, warning, XResult};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::consts::TINY_ENC_FILE_EXT;
|
||||
use crate::consts::{TINY_ENC_CONFIG_FILE, TINY_ENC_CONFIG_FILE_2, TINY_ENC_FILE_EXT};
|
||||
use crate::spec::TinyEncryptEnvelopType;
|
||||
|
||||
/// Config file sample:
|
||||
@@ -65,13 +65,34 @@ pub struct TinyEncryptConfigEnvelop {
|
||||
}
|
||||
|
||||
impl TinyEncryptConfig {
|
||||
pub fn load_default() -> XResult<Self> {
|
||||
let resolved_file = resolve_file_path(TINY_ENC_CONFIG_FILE);
|
||||
let resolved_file_2 = resolve_file_path(TINY_ENC_CONFIG_FILE_2);
|
||||
let config_file = if fs::metadata(&resolved_file).is_ok() {
|
||||
debugging!("Load config from: {resolved_file}");
|
||||
resolved_file
|
||||
} else if fs::metadata(&resolved_file_2).is_ok() {
|
||||
debugging!("Load config from: {resolved_file_2}");
|
||||
resolved_file_2
|
||||
} else {
|
||||
warning!("Cannot find config file from:\n- {resolved_file}\n- {resolved_file_2}");
|
||||
resolved_file
|
||||
};
|
||||
Self::load(&config_file)
|
||||
}
|
||||
|
||||
pub fn load(file: &str) -> XResult<Self> {
|
||||
let resolved_file = resolve_file_path(file);
|
||||
let config_contents = opt_result!(
|
||||
fs::read_to_string(resolved_file), "Read config file: {}, failed: {}", file
|
||||
fs::read_to_string(resolved_file),
|
||||
"Read config file: {}, failed: {}",
|
||||
file
|
||||
);
|
||||
let mut config: TinyEncryptConfig = opt_result!(
|
||||
serde_json::from_str(&config_contents),"Parse config file: {}, failed: {}", file);
|
||||
serde_json::from_str(&config_contents),
|
||||
"Parse config file: {}, failed: {}",
|
||||
file
|
||||
);
|
||||
let mut splited_profiles = HashMap::new();
|
||||
for (k, v) in config.profiles.into_iter() {
|
||||
if !k.contains(',') {
|
||||
@@ -90,8 +111,8 @@ impl TinyEncryptConfig {
|
||||
if let Some(environment) = &config.environment {
|
||||
for (k, v) in environment {
|
||||
let v = match v {
|
||||
StringOrVecString::String(s) => { s.to_string() }
|
||||
StringOrVecString::Vec(vs) => { vs.join(",") }
|
||||
StringOrVecString::String(s) => s.to_string(),
|
||||
StringOrVecString::Vec(vs) => vs.join(","),
|
||||
};
|
||||
debugging!("Set env: {}={}", k, v);
|
||||
env::set_var(k, v);
|
||||
@@ -104,10 +125,17 @@ impl TinyEncryptConfig {
|
||||
pub fn resolve_path_namespace(&self, path: &Path, append_te: bool) -> PathBuf {
|
||||
if let Some(path_str) = path.to_str() {
|
||||
if path_str.starts_with(':') {
|
||||
let namespace = path_str.chars().skip(1)
|
||||
.take_while(|c| *c != ':').collect::<String>();
|
||||
let mut filename = path_str.chars().skip(1)
|
||||
.skip_while(|c| *c != ':').skip(1).collect::<String>();
|
||||
let namespace = path_str
|
||||
.chars()
|
||||
.skip(1)
|
||||
.take_while(|c| *c != ':')
|
||||
.collect::<String>();
|
||||
let mut filename = path_str
|
||||
.chars()
|
||||
.skip(1)
|
||||
.skip_while(|c| *c != ':')
|
||||
.skip(1)
|
||||
.collect::<String>();
|
||||
if append_te && !filename.ends_with(TINY_ENC_FILE_EXT) {
|
||||
filename.push_str(TINY_ENC_FILE_EXT);
|
||||
}
|
||||
@@ -145,7 +173,10 @@ impl TinyEncryptConfig {
|
||||
}
|
||||
if k_filter.ends_with('*') {
|
||||
let new_k_filter = k_filter.chars().collect::<Vec<_>>();
|
||||
let new_k_filter = new_k_filter.iter().take(new_k_filter.len() - 1).collect::<String>();
|
||||
let new_k_filter = new_k_filter
|
||||
.iter()
|
||||
.take(new_k_filter.len() - 1)
|
||||
.collect::<String>();
|
||||
if e.kid.starts_with(&new_k_filter) || envelop_type.starts_with(&new_k_filter) {
|
||||
return true;
|
||||
}
|
||||
@@ -155,18 +186,30 @@ impl TinyEncryptConfig {
|
||||
}
|
||||
|
||||
pub fn find_by_kid_or_filter<F>(&self, kid: &str, f: F) -> Vec<&TinyEncryptConfigEnvelop>
|
||||
where F: Fn(&TinyEncryptConfigEnvelop) -> bool {
|
||||
self.envelops.iter().filter(|e| {
|
||||
if e.kid == kid { return true; }
|
||||
if let Some(sid) = &e.sid {
|
||||
if sid == kid { return true; }
|
||||
}
|
||||
f(e)
|
||||
}).collect()
|
||||
where
|
||||
F: Fn(&TinyEncryptConfigEnvelop) -> bool,
|
||||
{
|
||||
self.envelops
|
||||
.iter()
|
||||
.filter(|e| {
|
||||
if e.kid == kid {
|
||||
return true;
|
||||
}
|
||||
if let Some(sid) = &e.sid {
|
||||
if sid == kid {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
f(e)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn find_envelops(&self, profile: &Option<String>, key_filter: &Option<String>)
|
||||
-> XResult<Vec<&TinyEncryptConfigEnvelop>> {
|
||||
pub fn find_envelops(
|
||||
&self,
|
||||
profile: &Option<String>,
|
||||
key_filter: &Option<String>,
|
||||
) -> XResult<Vec<&TinyEncryptConfigEnvelop>> {
|
||||
debugging!("Profile: {:?}", profile);
|
||||
debugging!("Key filter: {:?}", key_filter);
|
||||
let mut matched_envelops_map = HashMap::new();
|
||||
@@ -203,17 +246,29 @@ impl TinyEncryptConfig {
|
||||
return simple_error!("Profile or key filter cannot find any valid envelopes");
|
||||
}
|
||||
envelops.sort_by(|e1, e2| {
|
||||
if e1.r#type < e2.r#type { return Ordering::Greater; }
|
||||
if e1.r#type > e2.r#type { return Ordering::Less; }
|
||||
if e1.kid < e2.kid { return Ordering::Greater; }
|
||||
if e1.kid > e2.kid { return Ordering::Less; }
|
||||
if e1.r#type < e2.r#type {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
if e1.r#type > e2.r#type {
|
||||
return Ordering::Less;
|
||||
}
|
||||
if e1.kid < e2.kid {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
if e1.kid > e2.kid {
|
||||
return Ordering::Less;
|
||||
}
|
||||
Ordering::Equal
|
||||
});
|
||||
Ok(envelops)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_path_namespace(config: &Option<TinyEncryptConfig>, path: &Path, append_te: bool) -> PathBuf {
|
||||
pub fn resolve_path_namespace(
|
||||
config: &Option<TinyEncryptConfig>,
|
||||
path: &Path,
|
||||
append_te: bool,
|
||||
) -> PathBuf {
|
||||
match config {
|
||||
None => path.to_path_buf(),
|
||||
Some(config) => config.resolve_path_namespace(path, append_te),
|
||||
|
||||
@@ -12,6 +12,7 @@ pub const ENC_CHACHA20_POLY1305_KYBER1204: &str = "chacha20-poly1305-kyber1204";
|
||||
pub const TINY_ENC_FILE_EXT: &str = ".tinyenc";
|
||||
pub const TINY_ENC_PEM_FILE_EXT: &str = ".tinyenc.pem";
|
||||
pub const TINY_ENC_CONFIG_FILE: &str = "~/.tinyencrypt/config-rs.json";
|
||||
pub const TINY_ENC_CONFIG_FILE_2: &str = "/etc/tinyencrypt/config-rs.json";
|
||||
|
||||
pub const TINY_ENC_PEM_NAME: &str = "TINY ENCRYPT";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user