diff --git a/Cargo.lock b/Cargo.lock index 2359345d71..2b34dad3e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1752,7 +1752,6 @@ dependencies = [ "rustls 0.23.40", "serde", "serde_json", - "sha2 0.10.9", "sqlx", "tiberius", "tokio", diff --git a/crates/dbx-core/Cargo.toml b/crates/dbx-core/Cargo.toml index f538723bca..73b594ae2c 100644 --- a/crates/dbx-core/Cargo.toml +++ b/crates/dbx-core/Cargo.toml @@ -33,4 +33,3 @@ csv = "1" calamine = "0.30.1" base64 = "0.22" async-trait = "0.1" -sha2 = "0.10" diff --git a/crates/dbx-core/src/agent_manager.rs b/crates/dbx-core/src/agent_manager.rs index 0ce4731179..898966e879 100644 --- a/crates/dbx-core/src/agent_manager.rs +++ b/crates/dbx-core/src/agent_manager.rs @@ -142,7 +142,6 @@ pub struct DriverInfo { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ArtifactInfo { pub url: String, - pub sha256: String, pub size: u64, } diff --git a/crates/dbx-core/src/agent_service.rs b/crates/dbx-core/src/agent_service.rs index ecbcb28589..44a975fba5 100644 --- a/crates/dbx-core/src/agent_service.rs +++ b/crates/dbx-core/src/agent_service.rs @@ -159,16 +159,7 @@ pub fn download_temp_path(dest: &std::path::Path) -> std::path::PathBuf { dest.with_file_name(format!("{file_name}.download")) } -pub fn verify_and_replace_download( - tmp: &std::path::Path, - dest: &std::path::Path, - expected_sha256: &str, -) -> Result<(), String> { - if let Err(err) = verify_file_sha256(tmp, expected_sha256) { - std::fs::remove_file(tmp).ok(); - return Err(err); - } - +pub fn replace_download(tmp: &std::path::Path, dest: &std::path::Path) -> Result<(), String> { if let Some(parent) = dest.parent() { std::fs::create_dir_all(parent).map_err(|e| e.to_string())?; } @@ -194,26 +185,3 @@ fn backup_path(dest: &std::path::Path) -> std::path::PathBuf { let file_name = dest.file_name().and_then(|name| name.to_str()).unwrap_or("download"); dest.with_file_name(format!("{file_name}.backup-{}", uuid::Uuid::new_v4())) } - -pub fn verify_file_sha256(path: &std::path::Path, expected_sha256: &str) -> Result<(), String> { - use sha2::{Digest, Sha256}; - let expected = expected_sha256.trim().to_ascii_lowercase(); - let mut file = - std::fs::File::open(path).map_err(|e| format!("Failed to open file for SHA-256 verification: {e}"))?; - let mut hasher = Sha256::new(); - let mut buffer = [0u8; 8192]; - loop { - let n = std::io::Read::read(&mut file, &mut buffer) - .map_err(|e| format!("Failed to read file for SHA-256 verification: {e}"))?; - if n == 0 { - break; - } - hasher.update(&buffer[..n]); - } - let actual = hasher.finalize().iter().map(|byte| format!("{byte:02x}")).collect::(); - if actual == expected { - Ok(()) - } else { - Err(format!("SHA-256 mismatch for {}: expected {expected}, got {actual}", path.display())) - } -} diff --git a/crates/dbx-core/tests/agent_service.rs b/crates/dbx-core/tests/agent_service.rs index 9ab62e7e79..b2c43ae3cf 100644 --- a/crates/dbx-core/tests/agent_service.rs +++ b/crates/dbx-core/tests/agent_service.rs @@ -2,7 +2,7 @@ use dbx_core::agent_manager::{ AgentManager, AgentRegistry, ArtifactInfo, DriverInfo, InstalledDriver, DEFAULT_JRE_KEY, }; use dbx_core::agent_service::{build_agent_list, github_url_to_r2_path, local_agent_jar_candidates}; -use dbx_core::agent_service::{is_app_version_compatible, verify_and_replace_download, verify_file_sha256}; +use dbx_core::agent_service::{is_app_version_compatible, replace_download}; fn test_manager(name: &str) -> AgentManager { let dir = std::env::temp_dir().join(format!("dbx-agent-service-{name}-{}", uuid::Uuid::new_v4())); @@ -18,11 +18,7 @@ fn registry_with_driver(db_type: &str, version: &str, jre: &str) -> AgentRegistr label: db_type.to_string(), min_app_version: "0.1.0".to_string(), jre: jre.to_string(), - jar: ArtifactInfo { - url: format!("https://example.com/dbx-agent-{db_type}.jar"), - sha256: "sha".to_string(), - size: 42, - }, + jar: ArtifactInfo { url: format!("https://example.com/dbx-agent-{db_type}.jar"), size: 42 }, }, ); AgentRegistry { jre: None, jres: std::collections::HashMap::new(), drivers } @@ -104,20 +100,7 @@ fn accepts_current_app_when_min_version_is_not_newer() { } #[test] -fn verifies_file_sha256() { - let path = test_path("sha256"); - std::fs::write(&path, b"dbx").unwrap(); - - verify_file_sha256(&path, "e4a49ac91ae97a25f60bbe2fa6e25809af94df975aa42d3db29edc17e44e6989").unwrap(); - let err = - verify_file_sha256(&path, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap_err(); - - assert!(err.contains("SHA-256 mismatch")); - std::fs::remove_file(path).ok(); -} - -#[test] -fn atomic_replace_keeps_existing_destination_when_hash_fails() { +fn atomic_replace_moves_download_into_place() { let dir = test_path("atomic"); std::fs::create_dir_all(&dir).unwrap(); let dest = dir.join("agent.jar"); @@ -125,12 +108,9 @@ fn atomic_replace_keeps_existing_destination_when_hash_fails() { std::fs::write(&dest, b"old").unwrap(); std::fs::write(&tmp, b"new").unwrap(); - let err = - verify_and_replace_download(&tmp, &dest, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") - .unwrap_err(); + replace_download(&tmp, &dest).unwrap(); - assert!(err.contains("SHA-256 mismatch")); - assert_eq!(std::fs::read(&dest).unwrap(), b"old"); + assert_eq!(std::fs::read(&dest).unwrap(), b"new"); assert!(!tmp.exists()); std::fs::remove_dir_all(dir).ok(); } diff --git a/crates/dbx-web/src/routes/agents.rs b/crates/dbx-web/src/routes/agents.rs index 5bf22ff889..ceaba3b4b6 100644 --- a/crates/dbx-web/src/routes/agents.rs +++ b/crates/dbx-web/src/routes/agents.rs @@ -9,7 +9,7 @@ use dbx_core::agent_manager::{ }; use dbx_core::agent_service::{ build_agent_list, download_temp_path, fetch_registry, find_local_agent_jar, github_url_to_r2_path, - install_local_agent, invalidate_registry_cache, verify_and_replace_download, + install_local_agent, invalidate_registry_cache, replace_download, }; use futures::Stream; use serde::Deserialize; @@ -233,7 +233,6 @@ async fn install_agent_from_registry( &platform_jre.url, &github_url_to_r2_path(&platform_jre.url, "jre"), &jre_archive, - &platform_jre.sha256, platform_jre.size, Some(db_type), current, @@ -253,7 +252,6 @@ async fn install_agent_from_registry( &driver.jar.url, &github_url_to_r2_path(&driver.jar.url, "driver"), &jar_path, - &driver.jar.sha256, driver.jar.size, Some(db_type), current, @@ -293,7 +291,6 @@ async fn reinstall_jre_core(am: &AgentManager, jre_key: &str, tx: &broadcast::Se &platform_jre.url, &github_url_to_r2_path(&platform_jre.url, "jre"), &jre_archive, - &platform_jre.sha256, platform_jre.size, None, None, @@ -319,7 +316,6 @@ async fn download_with_progress( url: &str, r2_path: &str, dest: &std::path::Path, - expected_sha256: &str, total_size: u64, db_type: Option<&str>, current: Option, @@ -346,7 +342,7 @@ async fn download_with_progress( } std::io::Write::flush(&mut file).map_err(|err| format!("Failed to flush temp file: {err}"))?; drop(file); - verify_and_replace_download(&tmp, dest, expected_sha256) + replace_download(&tmp, dest) } fn send_install_progress( diff --git a/src-tauri/src/commands/agents.rs b/src-tauri/src/commands/agents.rs index c3ec0a372b..244224085c 100644 --- a/src-tauri/src/commands/agents.rs +++ b/src-tauri/src/commands/agents.rs @@ -7,7 +7,7 @@ use dbx_core::agent_manager::{ }; use dbx_core::agent_service::{ build_agent_list, download_temp_path, fetch_registry, find_local_agent_jar, github_url_to_r2_path, - install_local_agent, invalidate_registry_cache, verify_and_replace_download, + install_local_agent, invalidate_registry_cache, replace_download, }; use dbx_core::connection::AppState; @@ -73,7 +73,6 @@ pub async fn install_agent( &platform_jre.url, &github_url_to_r2_path(&platform_jre.url, "jre"), &jre_archive, - &platform_jre.sha256, platform_jre.size, ) .await?; @@ -100,7 +99,6 @@ pub async fn install_agent( &driver.jar.url, &github_url_to_r2_path(&driver.jar.url, "driver"), &jar_path, - &driver.jar.sha256, driver.jar.size, ) .await?; @@ -162,7 +160,6 @@ pub async fn upgrade_all_agents(app: tauri::AppHandle, state: State<'_, Arc Result<(), String> { if let Some(parent) = dest.parent() { @@ -365,7 +359,7 @@ async fn download_with_progress( } std::io::Write::flush(&mut file).map_err(|e| format!("Failed to flush temp file: {e}"))?; drop(file); - verify_and_replace_download(&tmp, dest, expected_sha256) + replace_download(&tmp, dest) } fn extract_archive(archive: &std::path::Path, dest: &std::path::Path) -> Result<(), String> {