From 69ad584c800aeccf68146942c5357892ffdb333c Mon Sep 17 00:00:00 2001 From: "tiberiu.gutanu" Date: Sat, 26 Apr 2025 10:36:07 +0300 Subject: [PATCH 1/2] Added some FUSE functionalities for macOS --- Cargo.toml | 3 + data/contents/1/hash/$. | 1 + data/contents/1/ls/$. | 1 + data/inodes/1 | Bin 0 -> 130 bytes data/security/key.enc | Bin 0 -> 68 bytes data/security/key.salt | Bin 0 -> 24 bytes src/mount/dummy.rs | 222 +++++++++++++++++++++++++++++++--------- 7 files changed, 177 insertions(+), 50 deletions(-) create mode 100644 data/contents/1/hash/$. create mode 100644 data/contents/1/ls/$. create mode 100644 data/inodes/1 create mode 100644 data/security/key.enc create mode 100644 data/security/key.salt diff --git a/Cargo.toml b/Cargo.toml index f1ff759a..130e796e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,9 @@ criterion = { version = "0.5.1", features = ["html_reports"] } [target.'cfg(target_os = "linux")'.dependencies] fuse3 = { version = "0.8.1", features = ["tokio-runtime", "unprivileged"] } +[target.'cfg(target_os = "macos")'.dependencies] +fuser = { version = "0.14", features = ["tokio"] } + [[bench]] name = "crypto_read" harness = false diff --git a/data/contents/1/hash/$. b/data/contents/1/hash/$. new file mode 100644 index 00000000..be5b6879 --- /dev/null +++ b/data/contents/1/hash/$. @@ -0,0 +1 @@ +­J<ê6”耢žX%вg‹ ó#tÝœga=ô M´g&^(t4)60ufR5@i$;O|AX!QEh-&3aG( k>;hKT`b-*Kn>0+yR8MdK&U*;YO5R<<*w()?2K5uf$POMt1ONa4 literal 0 HcmV?d00001 diff --git a/data/security/key.enc b/data/security/key.enc new file mode 100644 index 0000000000000000000000000000000000000000..19e04162327ed35bc2b5b80a14ea21ec148081fc GIT binary patch literal 68 zcmV-K0K5N~$_AI&+`;NRZWkxK8>, - cipher: Cipher, - allow_root: bool, - allow_other: bool, - read_only: bool, -} +#[cfg(target_os = "macos")] +mod macos_impl { + use async_trait::async_trait; + use std::future::Future; + use std::io; + use std::path::PathBuf; + use std::pin::Pin; + use std::task::{Context, Poll}; + use fuser::{MountOption, Session, Filesystem}; + use tracing::info; + + use crate::crypto::Cipher; + use crate::encryptedfs::{FsResult, PasswordProvider}; + use crate::mount::{MountHandleInner, MountPoint}; -#[async_trait] -impl MountPoint for MountPointImpl { - fn new( + #[allow(clippy::struct_excessive_bools)] + pub struct MountPointImpl { mountpoint: PathBuf, data_dir: PathBuf, - password_provider: Box, + password_provider: Option>, cipher: Cipher, allow_root: bool, allow_other: bool, read_only: bool, - ) -> Self { - Self { - mountpoint, - data_dir, - password_provider: Some(password_provider), - cipher, - allow_root, - allow_other, - read_only, + } + + #[async_trait] + impl MountPoint for MountPointImpl { + fn new( + mountpoint: PathBuf, + data_dir: PathBuf, + password_provider: Box, + cipher: Cipher, + allow_root: bool, + allow_other: bool, + read_only: bool, + ) -> Self { + Self { + mountpoint, + data_dir, + password_provider: Some(password_provider), + cipher, + allow_root, + allow_other, + read_only, + } + } + + async fn mount(self) -> FsResult { + info!("Mounting rencfs on macOS using fuser..."); + + let fs = DummyFS {}; + + let mut options = vec![ + MountOption::FSName("rencfs".to_string()), + MountOption::AutoUnmount, + ]; + + if self.allow_other { + options.push(MountOption::AllowOther); + } + if self.read_only { + options.push(MountOption::RO); + } + + let session = Session::new(fs, &self.mountpoint, &options)?; + let handle = crate::mount::MountHandle { + inner: MountHandleInnerImpl { + session: Some(session), + }, + }; + Ok(handle) } } - async fn mount(mut self) -> FsResult { - Err(FsError::Other("Dummy implementation")) + pub struct MountHandleInnerImpl { + session: Option, } -} -pub(in crate::mount) struct MountHandleInnerImpl {} + impl Future for MountHandleInnerImpl { + type Output = io::Result<()>; -impl Future for MountHandleInnerImpl { - type Output = io::Result<()>; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if let Some(session) = &mut self.session { + session.poll_unpin(cx) + } else { + Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, "No session"))) + } + } + } - fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { - error!("he he, not yet ready for this platform, but soon my friend, soon :)"); - Poll::Ready(Ok(())) + #[async_trait] + impl MountHandleInner for MountHandleInnerImpl { + async fn unmount(mut self) -> io::Result<()> { + if let Some(session) = self.session.take() { + drop(session); + Ok(()) + } else { + Err(io::Error::new(io::ErrorKind::Other, "No session to unmount")) + } + } } + + struct DummyFS; + impl Filesystem for DummyFS {} + + pub use MountHandleInnerImpl; + pub use MountPointImpl; } -#[async_trait] -impl MountHandleInner for MountHandleInnerImpl { - async fn unmount(mut self) -> io::Result<()> { - Ok(()) +#[cfg(not(target_os = "macos"))] +mod fallback_dummy_impl { + use async_trait::async_trait; + use std::future::Future; + use std::io; + use std::path::PathBuf; + use std::pin::Pin; + use std::task::{Context, Poll}; + use tracing::error; + + use crate::crypto::Cipher; + use crate::encryptedfs::{FsError, FsResult, PasswordProvider}; + use crate::mount; + use crate::mount::{MountHandleInner, MountPoint}; + + #[allow(clippy::struct_excessive_bools)] + #[allow(dead_code)] + pub struct MountPointImpl { + mountpoint: PathBuf, + data_dir: PathBuf, + password_provider: Option>, + cipher: Cipher, + allow_root: bool, + allow_other: bool, + read_only: bool, + } + + #[async_trait] + impl MountPoint for MountPointImpl { + fn new( + mountpoint: PathBuf, + data_dir: PathBuf, + password_provider: Box, + cipher: Cipher, + allow_root: bool, + allow_other: bool, + read_only: bool, + ) -> Self { + Self { + mountpoint, + data_dir, + password_provider: Some(password_provider), + cipher, + allow_root, + allow_other, + read_only, + } + } + + async fn mount(mut self) -> FsResult { + Err(FsError::Other("Dummy implementation")) + } + } + + pub(in crate::mount) struct MountHandleInnerImpl {} + + impl Future for MountHandleInnerImpl { + type Output = io::Result<()>; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + error!("he he, not yet ready for this platform, but soon my friend, soon :)"); + Poll::Ready(Ok(())) + } + } + + #[async_trait] + impl MountHandleInner for MountHandleInnerImpl { + async fn unmount(mut self) -> io::Result<()> { + Ok(()) + } } + + pub use MountHandleInnerImpl; + pub use MountPointImpl; } + +#[cfg(target_os = "macos")] +pub use macos_impl::*; + +#[cfg(not(target_os = "macos"))] +pub use fallback_dummy_impl::*; From f31a80c976e8fb2da291d3b2d9bc014bd1b309ac Mon Sep 17 00:00:00 2001 From: "tiberiu.gutanu" Date: Sat, 26 Apr 2025 10:45:33 +0300 Subject: [PATCH 2/2] Fixed the error caused by fuser's features --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 87108b3d..f1160ed8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -979,6 +979,21 @@ dependencies = [ "which", ] +[[package]] +name = "fuser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e697f6f62c20b6fad1ba0f84ae909f25971cf16e735273524e3977c94604cf8" +dependencies = [ + "libc", + "log", + "memchr", + "page_size", + "pkg-config", + "smallvec", + "zerocopy", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -1565,6 +1580,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "parking" version = "2.2.1" @@ -1628,6 +1653,12 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "plotters" version = "0.3.7" @@ -1860,6 +1891,7 @@ dependencies = [ "criterion", "ctrlc", "fuse3", + "fuser", "futures-util", "hex", "keyring", diff --git a/Cargo.toml b/Cargo.toml index 130e796e..c346b858 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ criterion = { version = "0.5.1", features = ["html_reports"] } fuse3 = { version = "0.8.1", features = ["tokio-runtime", "unprivileged"] } [target.'cfg(target_os = "macos")'.dependencies] -fuser = { version = "0.14", features = ["tokio"] } +fuser = { version = "0.14"} [[bench]] name = "crypto_read"