diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 71662bb..5b07380 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -18,17 +18,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - [[package]] name = "anyhow" version = "1.0.102" @@ -53,48 +42,12 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - [[package]] name = "bumpalo" version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" -[[package]] -name = "bzip2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" -dependencies = [ - "libbz2-rs-sys", -] - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - [[package]] name = "cc" version = "1.2.57" @@ -111,16 +64,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clean_flash_common" version = "34.0.0" @@ -170,15 +113,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -188,26 +122,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "dlib" version = "0.5.3" @@ -345,16 +259,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.4.2" @@ -407,16 +311,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "block-padding", - "generic-array", -] - [[package]] name = "instant" version = "0.1.13" @@ -457,12 +351,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" -[[package]] -name = "libbz2-rs-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" - [[package]] name = "libc" version = "0.2.183" @@ -609,12 +497,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -[[package]] -name = "ppmd-rust" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efca4c95a19a79d1c98f791f10aebd5c1363b473244630bb7dbde1dc98455a24" - [[package]] name = "prettyplease" version = "0.2.37" @@ -776,29 +658,12 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29225600349ef74beda5a9fffb36ac660a24613c0bde9315d0c49be1d51e9c24" dependencies = [ - "aes", - "bzip2", - "cbc", "crc32fast", - "getrandom", "js-sys", "lzma-rust2", - "ppmd-rust", - "sha2", "wasm-bindgen", ] -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "shlex" version = "1.3.0" @@ -886,12 +751,6 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - [[package]] name = "unicode-ident" version = "1.0.24" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 97a7387..7f7abbe 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -9,7 +9,7 @@ members = [ [workspace.dependencies] ab_glyph = "0.2" -sevenz-rust2 = { version = "0.20", default-feaures = false, features = ["compress", "util"] } +sevenz-rust2 = { version = "0.20", default-features = false, features = ["compress", "util"] } minifb = "0.28" windows-sys = { version = "0.61", features = [ "Win32_Foundation", diff --git a/rust/crates/clean_flash_common/src/file_util.rs b/rust/crates/clean_flash_common/src/file_util.rs index 2f95e6c..d93765e 100644 --- a/rust/crates/clean_flash_common/src/file_util.rs +++ b/rust/crates/clean_flash_common/src/file_util.rs @@ -1,7 +1,10 @@ +#[cfg(windows)] use crate::uninstaller; use std::fs; use std::path::Path; +#[cfg(windows)] use std::thread; +#[cfg(windows)] use std::time::Duration; /// Attempt to delete a single file, retrying with escalating measures if needed. @@ -10,7 +13,8 @@ pub fn delete_file(path: &Path) { return; } - // Unregister ActiveX .ocx files before deletion. + // Unregister ActiveX .ocx files before deletion (Windows only). + #[cfg(windows)] if let Some(ext) = path.extension() { if ext.eq_ignore_ascii_case("ocx") { let _ = uninstaller::unregister_activex(&path.to_string_lossy()); diff --git a/rust/crates/clean_flash_common/src/lib.rs b/rust/crates/clean_flash_common/src/lib.rs index 63358a7..b7865cd 100644 --- a/rust/crates/clean_flash_common/src/lib.rs +++ b/rust/crates/clean_flash_common/src/lib.rs @@ -5,7 +5,15 @@ pub mod redirection; pub mod registry; pub mod resources; pub mod system_info; + +#[cfg(windows)] +#[path = "uninstaller_windows.rs"] +pub mod uninstaller; + +#[cfg(not(windows))] +#[path = "uninstaller_linux.rs"] pub mod uninstaller; + pub mod update_checker; pub mod winapi_helpers; diff --git a/rust/crates/clean_flash_common/src/native_host.rs b/rust/crates/clean_flash_common/src/native_host.rs index 9acc2e0..2e0003c 100644 --- a/rust/crates/clean_flash_common/src/native_host.rs +++ b/rust/crates/clean_flash_common/src/native_host.rs @@ -8,8 +8,8 @@ use std::fs; use std::path::{Path, PathBuf}; const MANIFEST_NAME: &str = "org.cleanflash.flash_player"; -const FIREFOX_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.firefox.json"; -const CHROME_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.chrome.json"; +const FIREFOX_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.json"; +const CHROME_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.json"; const FIREFOX_ALLOWED_EXTENSION: &str = "flash-player@cleanflash.org"; const ALLOWED_ORIGIN: &str = "chrome-extension://dcikaadaeajidejkoekdflmfdgeoldcb/"; @@ -402,12 +402,7 @@ pub fn uninstall_native_host(form: &dyn ProgressCallback) { pub fn uninstall_native_host(form: &dyn ProgressCallback) { form.update_progress_label("Removing native messaging host...", true); - // Remove the host folder and everything inside it. - let install_dir = get_native_host_install_dir(); - let host_exe = install_dir.join(HOST_BINARY_NAME); - let _ = fs::remove_file(&host_exe); - let _ = fs::remove_dir_all(&install_dir); - + // Remove the manifests. let home = match std::env::var("HOME") { Ok(h) => PathBuf::from(h), Err(_) => return, @@ -417,6 +412,12 @@ pub fn uninstall_native_host(form: &dyn ProgressCallback) { let _ = fs::remove_file(target.manifest_dir.join(CHROME_MANIFEST_FILENAME)); let _ = fs::remove_file(target.manifest_dir.join(FIREFOX_MANIFEST_FILENAME)); } + + // Remove the host folder and everything inside it. + let install_dir = get_native_host_install_dir(); + let host_exe = install_dir.join(HOST_BINARY_NAME); + let _ = fs::remove_file(&host_exe); + let _ = fs::remove_dir_all(&install_dir); } /// Check if a registry key exists under HKCU. diff --git a/rust/crates/clean_flash_common/src/process_utils.rs b/rust/crates/clean_flash_common/src/process_utils.rs index 2ed433e..1401c32 100644 --- a/rust/crates/clean_flash_common/src/process_utils.rs +++ b/rust/crates/clean_flash_common/src/process_utils.rs @@ -50,6 +50,7 @@ pub fn run_unmanaged_process(program: &str, args: &[&str]) { /// Collect the names of DLL modules loaded in a given process. /// Used to detect whether a browser has Flash DLLs loaded. +#[cfg(windows)] pub fn collect_modules(pid: u32) -> Vec { use windows_sys::Win32::Foundation::CloseHandle; use windows_sys::Win32::System::ProcessStatus::{ @@ -108,3 +109,8 @@ pub fn collect_modules(pid: u32) -> Vec { modules } + +#[cfg(not(windows))] +pub fn collect_modules(_pid: u32) -> Vec { + Vec::new() +} diff --git a/rust/crates/clean_flash_common/src/redirection.rs b/rust/crates/clean_flash_common/src/redirection.rs index 840c5e0..8de78e9 100644 --- a/rust/crates/clean_flash_common/src/redirection.rs +++ b/rust/crates/clean_flash_common/src/redirection.rs @@ -1,4 +1,5 @@ /// Disable WoW64 file system redirection. Returns a cookie to restore later. +#[cfg(windows)] pub fn disable_redirection() -> *mut std::ffi::c_void { let mut old_value: *mut std::ffi::c_void = std::ptr::null_mut(); unsafe { @@ -8,13 +9,23 @@ pub fn disable_redirection() -> *mut std::ffi::c_void { } /// Re-enable WoW64 file system redirection using the cookie from `disable_redirection`. +#[cfg(windows)] pub fn enable_redirection(old_value: *mut std::ffi::c_void) { unsafe { Wow64RevertWow64FsRedirection(old_value); } } +#[cfg(windows)] extern "system" { fn Wow64DisableWow64FsRedirection(old_value: *mut *mut std::ffi::c_void) -> i32; fn Wow64RevertWow64FsRedirection(old_value: *mut std::ffi::c_void) -> i32; } + +#[cfg(not(windows))] +pub fn disable_redirection() -> *mut std::ffi::c_void { + std::ptr::null_mut() +} + +#[cfg(not(windows))] +pub fn enable_redirection(_old_value: *mut std::ffi::c_void) {} diff --git a/rust/crates/clean_flash_common/src/registry.rs b/rust/crates/clean_flash_common/src/registry.rs index 72413d4..d737948 100644 --- a/rust/crates/clean_flash_common/src/registry.rs +++ b/rust/crates/clean_flash_common/src/registry.rs @@ -3,6 +3,7 @@ use std::fs; use std::io::Write; /// Apply registry contents by writing a .reg file and importing with reg.exe. +#[cfg(windows)] pub fn apply_registry(entries: &[&str]) -> Result<(), InstallError> { let combined = entries.join("\n\n"); let filled = system_info::fill_string(&combined); @@ -42,3 +43,8 @@ pub fn apply_registry(entries: &[&str]) -> Result<(), InstallError> { Ok(()) } + +#[cfg(not(windows))] +pub fn apply_registry(_entries: &[&str]) -> Result<(), InstallError> { + Ok(()) +} \ No newline at end of file diff --git a/rust/crates/clean_flash_common/src/uninstaller_linux.rs b/rust/crates/clean_flash_common/src/uninstaller_linux.rs new file mode 100644 index 0000000..5b8464d --- /dev/null +++ b/rust/crates/clean_flash_common/src/uninstaller_linux.rs @@ -0,0 +1,20 @@ +use crate::{native_host, InstallError, ProgressCallback}; +use std::fs; + +/// Perform the full uninstallation sequence on Linux. +/// +/// This removes the native messaging host binary, the Pepper (pp64) files +/// installed alongside it, and the browser manifests. +pub fn uninstall(form: &dyn ProgressCallback) -> Result<(), InstallError> { + form.update_progress_label("Removing native messaging host...", true); + native_host::uninstall_native_host(form); + + // Remove the entire install directory (host binary + pp64 files). + let install_dir = native_host::get_native_host_install_dir(); + if install_dir.exists() { + form.update_progress_label("Removing installed files...", true); + let _ = fs::remove_dir_all(&install_dir); + } + + Ok(()) +} diff --git a/rust/crates/clean_flash_common/src/uninstaller.rs b/rust/crates/clean_flash_common/src/uninstaller_windows.rs similarity index 97% rename from rust/crates/clean_flash_common/src/uninstaller.rs rename to rust/crates/clean_flash_common/src/uninstaller_windows.rs index df5a43d..6601d90 100644 --- a/rust/crates/clean_flash_common/src/uninstaller.rs +++ b/rust/crates/clean_flash_common/src/uninstaller_windows.rs @@ -204,6 +204,7 @@ fn should_kill_conditional_process(name: &str, pid: u32) -> bool { }) } +#[cfg(windows)] fn stop_processes() { use windows_sys::Win32::Foundation::CloseHandle; use windows_sys::Win32::System::Threading::{ @@ -237,6 +238,12 @@ fn stop_processes() { } } +#[cfg(not(windows))] +fn stop_processes() { + // Process termination via Windows API not available on Unix. +} + +#[cfg(windows)] fn get_process_creation_time(pid: u32) -> u64 { use windows_sys::Win32::Foundation::{CloseHandle, FILETIME}; use windows_sys::Win32::System::Threading::{GetProcessTimes, OpenProcess, PROCESS_QUERY_INFORMATION}; @@ -255,6 +262,12 @@ fn get_process_creation_time(pid: u32) -> u64 { } } +#[cfg(not(windows))] +fn get_process_creation_time(_pid: u32) -> u64 { + 0 +} + +#[cfg(windows)] fn enumerate_processes() -> Vec<(u32, String)> { use windows_sys::Win32::System::ProcessStatus::{EnumProcesses, GetModuleBaseNameW}; use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_QUERY_INFORMATION, PROCESS_VM_READ}; @@ -302,6 +315,11 @@ fn enumerate_processes() -> Vec<(u32, String)> { results } +#[cfg(not(windows))] +fn enumerate_processes() -> Vec<(u32, String)> { + Vec::new() +} + /// Perform the full uninstallation sequence. pub fn uninstall(form: &dyn ProgressCallback) -> Result<(), InstallError> { winapi_helpers::allow_modifications(); diff --git a/rust/crates/clean_flash_common/src/winapi_helpers.rs b/rust/crates/clean_flash_common/src/winapi_helpers.rs index 6f8735d..e7b8ca7 100644 --- a/rust/crates/clean_flash_common/src/winapi_helpers.rs +++ b/rust/crates/clean_flash_common/src/winapi_helpers.rs @@ -1,9 +1,16 @@ /// Enable SeRestorePrivilege and SeTakeOwnershipPrivilege for the current process. +#[cfg(windows)] pub fn allow_modifications() { let _ = modify_privilege("SeRestorePrivilege\0", true); let _ = modify_privilege("SeTakeOwnershipPrivilege\0", true); } +#[cfg(not(windows))] +pub fn allow_modifications() { + // No privilege modifications needed on Unix. +} + +#[cfg(windows)] fn modify_privilege(name: &str, enable: bool) -> Result<(), ()> { use windows_sys::Win32::Foundation::CloseHandle; use windows_sys::Win32::Security::{ diff --git a/rust/crates/clean_flash_installer/src/installer_linux.rs b/rust/crates/clean_flash_installer/src/installer_linux.rs new file mode 100644 index 0000000..e9dd933 --- /dev/null +++ b/rust/crates/clean_flash_installer/src/installer_linux.rs @@ -0,0 +1,103 @@ +use crate::install_flags::{self, InstallFlags}; +use clean_flash_common::{native_host, InstallError, ProgressCallback}; +use std::fs; +use std::io::{self, Cursor}; + +/// Extract native-host and pp64 entries from the embedded 7z archive, +/// placing them next to each other in the native host install directory. +fn install_from_archive( + archive_bytes: &[u8], + form: &dyn ProgressCallback, +) -> Result<(), InstallError> { + let native_host_dir = native_host::get_native_host_install_dir(); + let _ = fs::create_dir_all(&native_host_dir); + + form.update_progress_label("Extracting native messaging host files...", true); + + sevenz_rust2::decompress_with_extract_fn( + Cursor::new(archive_bytes), + ".", + |entry, reader, _dest| { + if entry.is_directory() { + io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?; + return Ok(true); + } + + let entry_name = entry.name().to_string(); + let parts: Vec<&str> = entry_name.split('/').collect(); + if parts.is_empty() { + return Ok(true); + } + + let dirname = parts[0]; + let install_key = dirname.split('-').next().unwrap_or(dirname); + + // Only extract native-host-64, pp64, and uninstaller entries. + let dominated = dirname == "native-host-64" + || install_key == "pp64" + || install_key == "uninstaller"; + if !dominated { + io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?; + return Ok(true); + } + + // Skip debug variants of pp64. + if install_key == "pp64" && dirname.contains("-debug") { + io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?; + return Ok(true); + } + + if dirname == "native-host-64" { + form.update_progress_label("Installing native messaging host...", true); + } else if install_key == "pp64" { + form.update_progress_label("Installing Pepper plugin files...", true); + } else if install_key == "uninstaller" { + form.update_progress_label("Extracting uninstaller...", true); + } + + let out_name = parts.last().unwrap_or(&dirname); + let out_path = native_host_dir.join(out_name); + + let mut buf = Vec::new(); + reader + .read_to_end(&mut buf) + .map_err(sevenz_rust2::Error::from)?; + fs::write(&out_path, &buf).map_err(sevenz_rust2::Error::from)?; + + // Make binaries executable. + #[cfg(unix)] + if dirname == "native-host-64" || install_key == "uninstaller" { + use std::os::unix::fs::PermissionsExt; + let _ = fs::set_permissions(&out_path, fs::Permissions::from_mode(0o755)); + } + + Ok(true) + }, + ) + .map_err(|e| InstallError::new(format!("Failed to extract archive: {}", e)))?; + + Ok(()) +} + +/// Main install entry point for Linux. +pub fn install( + form: &dyn ProgressCallback, + flags: &mut InstallFlags, +) -> Result<(), InstallError> { + if flags.is_none_set() { + return Ok(()); + } + + let archive_bytes: &[u8] = include_bytes!("../cleanflash.7z"); + + if archive_bytes.is_empty() { + return Ok(()); + } + + if flags.is_set(install_flags::NATIVE_HOST) { + install_from_archive(archive_bytes, form)?; + native_host::install_native_host(form)?; + } + + Ok(()) +} diff --git a/rust/crates/clean_flash_installer/src/installer.rs b/rust/crates/clean_flash_installer/src/installer_windows.rs similarity index 100% rename from rust/crates/clean_flash_installer/src/installer.rs rename to rust/crates/clean_flash_installer/src/installer_windows.rs diff --git a/rust/crates/clean_flash_installer/src/main.rs b/rust/crates/clean_flash_installer/src/main.rs index 405a95b..73caf38 100644 --- a/rust/crates/clean_flash_installer/src/main.rs +++ b/rust/crates/clean_flash_installer/src/main.rs @@ -2,6 +2,13 @@ mod install_flags; mod install_form; + +#[cfg(windows)] +#[path = "installer_windows.rs"] +mod installer; + +#[cfg(not(windows))] +#[path = "installer_linux.rs"] mod installer; use install_form::{InstallForm, HEIGHT, WIDTH};