feat: v1.8.4, load config from multipl locations

This commit is contained in:
2025-01-13 00:37:48 +08:00
parent b21714cb4b
commit cc5178d1c1
10 changed files with 229 additions and 191 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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"); }

View File

@@ -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.");
}

View File

@@ -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)); }

View File

@@ -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();

View File

@@ -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),

View File

@@ -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";