diff --git a/src-tauri/src/config/encrypt.rs b/src-tauri/src/config/encrypt.rs index 91f7798a..4e6b9dec 100644 --- a/src-tauri/src/config/encrypt.rs +++ b/src-tauri/src/config/encrypt.rs @@ -5,8 +5,10 @@ use aes_gcm::{ }; use base64::{Engine, engine::general_purpose::STANDARD}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::cell::Cell; const NONCE_LENGTH: usize = 12; +thread_local!(static ENCRYPTION_CONTEXT: Cell = const { Cell::new(false) }); /// Encrypt data #[allow(deprecated)] @@ -59,39 +61,62 @@ where T: Serialize, S: Serializer, { - // 如果序列化失败,返回 None - let json = match serde_json::to_string(value) { - Ok(j) => j, - Err(_) => return serializer.serialize_none(), - }; - - // 如果加密失败,返回 None - match encrypt_data(&json) { - Ok(encrypted) => serializer.serialize_str(&encrypted), - Err(_) => serializer.serialize_none(), + if is_encryption_active() { + let json = serde_json::to_string(value).map_err(serde::ser::Error::custom)?; + let encrypted = encrypt_data(&json).map_err(serde::ser::Error::custom)?; + serializer.serialize_str(&encrypted) + } else { + value.serialize(serializer) } } /// Deserialize decrypted function -pub fn deserialize_encrypted<'a, T, D>(deserializer: D) -> Result +pub fn deserialize_encrypted<'a, D, T>(deserializer: D) -> Result where T: for<'de> Deserialize<'de> + Default, D: Deserializer<'a>, { - // 如果反序列化字符串失败,返回默认值 - let encrypted = match String::deserialize(deserializer) { - Ok(s) => s, - Err(_) => return Ok(T::default()), - }; + if is_encryption_active() { + let encrypted_opt: Option = Option::deserialize(deserializer)?; - // 如果解密失败,返回默认值 - let decrypted_string = match decrypt_data(&encrypted) { - Ok(data) => data, - Err(_) => return Ok(T::default()), - }; - // 如果 JSON 解析失败,返回默认值 - match serde_json::from_str(&decrypted_string) { - Ok(value) => Ok(value), - Err(_) => Ok(T::default()), + match encrypted_opt { + Some(encrypted) if !encrypted.is_empty() => { + let decrypted_string = + decrypt_data(&encrypted).map_err(serde::de::Error::custom)?; + serde_json::from_str(&decrypted_string).map_err(serde::de::Error::custom) + } + _ => Ok(T::default()), + } + } else { + T::deserialize(deserializer) } } + +pub struct EncryptionGuard; + +impl EncryptionGuard { + pub fn new() -> Self { + ENCRYPTION_CONTEXT.with(|ctx| { + ctx.set(true); + }); + EncryptionGuard + } +} + +impl Default for EncryptionGuard { + fn default() -> Self { + Self::new() + } +} + +impl Drop for EncryptionGuard { + fn drop(&mut self) { + ENCRYPTION_CONTEXT.with(|ctx| { + ctx.set(false); + }); + } +} + +fn is_encryption_active() -> bool { + ENCRYPTION_CONTEXT.with(|ctx| ctx.get()) +} diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs index 5de30e9f..f91026c3 100644 --- a/src-tauri/src/config/verge.rs +++ b/src-tauri/src/config/verge.rs @@ -552,156 +552,3 @@ impl IVerge { } } } - -#[derive(Debug, Clone, Serialize)] -pub struct IVergeResponse { - pub app_log_level: Option, - pub app_log_max_size: Option, - pub app_log_max_count: Option, - pub language: Option, - pub theme_mode: Option, - pub tray_event: Option, - pub env_type: Option, - pub start_page: Option, - pub startup_script: Option, - pub traffic_graph: Option, - pub enable_memory_usage: Option, - pub enable_group_icon: Option, - pub common_tray_icon: Option, - #[cfg(target_os = "macos")] - pub tray_icon: Option, - pub menu_icon: Option, - pub menu_order: Option>, - pub sysproxy_tray_icon: Option, - pub tun_tray_icon: Option, - pub enable_tun_mode: Option, - pub enable_auto_launch: Option, - pub enable_silent_start: Option, - pub enable_system_proxy: Option, - pub enable_proxy_guard: Option, - pub enable_global_hotkey: Option, - pub use_default_bypass: Option, - pub system_proxy_bypass: Option, - pub proxy_guard_duration: Option, - pub proxy_auto_config: Option, - pub pac_file_content: Option, - pub proxy_host: Option, - pub theme_setting: Option, - pub web_ui_list: Option>, - pub clash_core: Option, - pub hotkeys: Option>, - pub auto_close_connection: Option, - pub auto_check_update: Option, - pub default_latency_test: Option, - pub default_latency_timeout: Option, - pub enable_auto_delay_detection: Option, - pub enable_builtin_enhanced: Option, - pub proxy_layout_column: Option, - pub test_list: Option>, - pub auto_log_clean: Option, - #[cfg(not(target_os = "windows"))] - pub verge_redir_port: Option, - #[cfg(not(target_os = "windows"))] - pub verge_redir_enabled: Option, - #[cfg(target_os = "linux")] - pub verge_tproxy_port: Option, - #[cfg(target_os = "linux")] - pub verge_tproxy_enabled: Option, - pub verge_mixed_port: Option, - pub verge_socks_port: Option, - pub verge_socks_enabled: Option, - pub verge_port: Option, - pub verge_http_enabled: Option, - pub webdav_url: Option, - pub webdav_username: Option, - pub webdav_password: Option, - pub enable_tray_speed: Option, - // pub enable_tray_icon: Option, - pub tray_inline_proxy_groups: Option, - pub enable_auto_light_weight_mode: Option, - pub auto_light_weight_minutes: Option, - pub enable_dns_settings: Option, - pub home_cards: Option, - pub enable_hover_jump_navigator: Option, - pub hover_jump_navigator_delay: Option, - pub enable_external_controller: Option, -} - -impl From for IVergeResponse { - fn from(verge: IVerge) -> Self { - // 先获取验证后的clash_core值,避免后续借用冲突 - let valid_clash_core = verge.get_valid_clash_core(); - Self { - app_log_level: verge.app_log_level, - app_log_max_size: verge.app_log_max_size, - app_log_max_count: verge.app_log_max_count, - language: verge.language, - theme_mode: verge.theme_mode, - tray_event: verge.tray_event, - env_type: verge.env_type, - start_page: verge.start_page, - startup_script: verge.startup_script, - traffic_graph: verge.traffic_graph, - enable_memory_usage: verge.enable_memory_usage, - enable_group_icon: verge.enable_group_icon, - common_tray_icon: verge.common_tray_icon, - #[cfg(target_os = "macos")] - tray_icon: verge.tray_icon, - menu_icon: verge.menu_icon, - menu_order: verge.menu_order, - sysproxy_tray_icon: verge.sysproxy_tray_icon, - tun_tray_icon: verge.tun_tray_icon, - enable_tun_mode: verge.enable_tun_mode, - enable_auto_launch: verge.enable_auto_launch, - enable_silent_start: verge.enable_silent_start, - enable_system_proxy: verge.enable_system_proxy, - enable_proxy_guard: verge.enable_proxy_guard, - enable_global_hotkey: verge.enable_global_hotkey, - use_default_bypass: verge.use_default_bypass, - system_proxy_bypass: verge.system_proxy_bypass, - proxy_guard_duration: verge.proxy_guard_duration, - proxy_auto_config: verge.proxy_auto_config, - pac_file_content: verge.pac_file_content, - proxy_host: verge.proxy_host, - theme_setting: verge.theme_setting, - web_ui_list: verge.web_ui_list, - clash_core: Some(valid_clash_core), - hotkeys: verge.hotkeys, - auto_close_connection: verge.auto_close_connection, - auto_check_update: verge.auto_check_update, - default_latency_test: verge.default_latency_test, - default_latency_timeout: verge.default_latency_timeout, - enable_auto_delay_detection: verge.enable_auto_delay_detection, - enable_builtin_enhanced: verge.enable_builtin_enhanced, - proxy_layout_column: verge.proxy_layout_column, - test_list: verge.test_list, - auto_log_clean: verge.auto_log_clean, - #[cfg(not(target_os = "windows"))] - verge_redir_port: verge.verge_redir_port, - #[cfg(not(target_os = "windows"))] - verge_redir_enabled: verge.verge_redir_enabled, - #[cfg(target_os = "linux")] - verge_tproxy_port: verge.verge_tproxy_port, - #[cfg(target_os = "linux")] - verge_tproxy_enabled: verge.verge_tproxy_enabled, - verge_mixed_port: verge.verge_mixed_port, - verge_socks_port: verge.verge_socks_port, - verge_socks_enabled: verge.verge_socks_enabled, - verge_port: verge.verge_port, - verge_http_enabled: verge.verge_http_enabled, - webdav_url: verge.webdav_url, - webdav_username: verge.webdav_username, - webdav_password: verge.webdav_password, - enable_tray_speed: verge.enable_tray_speed, - // enable_tray_icon: verge.enable_tray_icon, - tray_inline_proxy_groups: verge.tray_inline_proxy_groups, - enable_auto_light_weight_mode: verge.enable_auto_light_weight_mode, - auto_light_weight_minutes: verge.auto_light_weight_minutes, - enable_dns_settings: verge.enable_dns_settings, - home_cards: verge.home_cards, - enable_hover_jump_navigator: verge.enable_hover_jump_navigator, - hover_jump_navigator_delay: verge.hover_jump_navigator_delay, - enable_external_controller: verge.enable_external_controller, - } - } -} diff --git a/src-tauri/src/core/backup.rs b/src-tauri/src/core/backup.rs index 3e94a733..3ad7eca4 100644 --- a/src-tauri/src/core/backup.rs +++ b/src-tauri/src/core/backup.rs @@ -87,7 +87,7 @@ impl WebDavClient { (*cfg_arc).clone() } else { // 释放锁后获取异步配置 - let verge = Config::verge().await.latest_arc(); + let verge = Config::verge().await.data_arc(); if verge.webdav_url.is_none() || verge.webdav_username.is_none() || verge.webdav_password.is_none() diff --git a/src-tauri/src/utils/help.rs b/src-tauri/src/utils/help.rs index 8b40f364..258fea2c 100644 --- a/src-tauri/src/utils/help.rs +++ b/src-tauri/src/utils/help.rs @@ -1,4 +1,4 @@ -use crate::{enhance::seq::SeqMap, logging, utils::logging::Type}; +use crate::{config::EncryptionGuard, enhance::seq::SeqMap, logging, utils::logging::Type}; use anyhow::{Context, Result, anyhow, bail}; use nanoid::nanoid; use serde::{Serialize, de::DeserializeOwned}; @@ -11,6 +11,7 @@ pub async fn read_yaml(path: &PathBuf) -> Result { bail!("file not found \"{}\"", path.display()); } + let _guard = EncryptionGuard::new(); let yaml_str = tokio::fs::read_to_string(path).await?; Ok(serde_yaml_ng::from_str::(&yaml_str)?) @@ -65,6 +66,7 @@ pub async fn save_yaml( data: &T, prefix: Option<&str>, ) -> Result<()> { + let _guard = EncryptionGuard::new(); let data_str = serde_yaml_ng::to_string(data)?; let yaml_str = match prefix {