Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"}

[[bench]]
name = "crypto_read"
harness = false
Expand Down
1 change: 1 addition & 0 deletions data/contents/1/hash/$.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�J<�6����X%вg���#tݜga=�M�<SY���" e��q
Expand Down
1 change: 1 addition & 0 deletions data/contents/1/ls/$.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�9���g�S��VBzdLsk��2�V�j�Opd���?�0��I
Expand Down
Binary file added data/inodes/1
Binary file not shown.
Binary file added data/security/key.enc
Binary file not shown.
Binary file added data/security/key.salt
Binary file not shown.
222 changes: 172 additions & 50 deletions src/mount/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,191 @@
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<Box<dyn PasswordProvider>>,
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<dyn PasswordProvider>,
password_provider: Option<Box<dyn PasswordProvider>>,
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<dyn PasswordProvider>,
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<crate::mount::MountHandle> {
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<mount::MountHandle> {
Err(FsError::Other("Dummy implementation"))
pub struct MountHandleInnerImpl {
session: Option<Session>,
}
}

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<Self::Output> {
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<Self::Output> {
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<Box<dyn PasswordProvider>>,
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<dyn PasswordProvider>,
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<mount::MountHandle> {
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<Self::Output> {
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::*;