feat(opsec): implement inactivity auto-lock, session lock detection, and anti-leak shield
This commit is contained in:
+64
-3
@@ -2,6 +2,8 @@ use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use dav_server::{fakels::FakeLs, DavHandler};
|
||||
@@ -83,6 +85,9 @@ pub async fn mount_container(
|
||||
auth: ContainerAuth,
|
||||
open_explorer: bool,
|
||||
enable_tray: bool,
|
||||
idle_timeout: Option<u64>,
|
||||
lock_on_screen_lock: bool,
|
||||
anti_leak: bool,
|
||||
) -> Result<()> {
|
||||
let drive_str = format_drive(drive_letter);
|
||||
|
||||
@@ -127,8 +132,9 @@ pub async fn mount_container(
|
||||
}
|
||||
};
|
||||
|
||||
// WebDAV Filesystem und Handler konfigurieren
|
||||
let fs = SanctumFs::new(db.clone(), dek, version);
|
||||
// WebDAV Filesystem und Handler konfigurieren (mit Anti-Leak Shield)
|
||||
let fs = SanctumFs::with_options(db.clone(), dek, version, anti_leak);
|
||||
let last_activity = fs.last_activity();
|
||||
let dav_server = DavHandler::builder()
|
||||
.filesystem(Box::new(fs))
|
||||
.locksystem(FakeLs::new())
|
||||
@@ -248,6 +254,44 @@ pub async fn mount_container(
|
||||
None
|
||||
};
|
||||
|
||||
// Inaktivitäts-Timer (Auto-Lock)
|
||||
let (idle_shutdown_tx, mut idle_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1);
|
||||
if let Some(timeout_secs) = idle_timeout {
|
||||
if timeout_secs > 0 {
|
||||
let last_act = last_activity.clone();
|
||||
let idle_tx = idle_shutdown_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut interval = tokio::time::interval(std::time::Duration::from_secs(1));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map(|d| d.as_secs())
|
||||
.unwrap_or(0);
|
||||
let last = last_act.load(Ordering::Relaxed);
|
||||
if now.saturating_sub(last) >= timeout_secs {
|
||||
let _ = idle_tx.send(()).await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Windows-Sitzungssperre (Win + L Auto-Lock)
|
||||
let (session_lock_tx, mut session_lock_rx) = tokio::sync::mpsc::channel::<()>(1);
|
||||
let _session_monitor = if lock_on_screen_lock {
|
||||
match crate::windows::start_session_lock_monitor(session_lock_tx) {
|
||||
Ok(guard) => Some(guard),
|
||||
Err(e) => {
|
||||
warn!("Konnte Windows Session-Lock Monitor nicht aktivieren: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
println!();
|
||||
println!("┌─────────────────────────────────────────────────────────────┐");
|
||||
println!("│ ✔ Sanctum Container erfolgreich gemountet │");
|
||||
@@ -256,6 +300,15 @@ pub async fn mount_container(
|
||||
println!(" • Container: {}", container_path.display());
|
||||
println!(" • Netzlaufwerk: {} (im Windows Explorer bereit)", ui::cyan(&drive_str));
|
||||
println!(" • WebDAV-URL: http://127.0.0.1:{}/", bound_port);
|
||||
if let Some(secs) = idle_timeout {
|
||||
println!(" • Auto-Lock: Inaktivität nach {}s", secs);
|
||||
}
|
||||
if lock_on_screen_lock {
|
||||
println!(" • Sitzung: Automatisches Sperren bei Win + L aktiv");
|
||||
}
|
||||
if anti_leak {
|
||||
println!(" • Anti-Leak: Explorer-Metadatenfilter aktiv (Thumbs.db, desktop.ini blockiert)");
|
||||
}
|
||||
if enable_tray {
|
||||
println!(" • System-Tray: Icon aktiv (Rechtsklick für Explorer/Trennen)");
|
||||
}
|
||||
@@ -263,7 +316,7 @@ pub async fn mount_container(
|
||||
println!(" [{}] Drücke [Ctrl+C] oder nutze das Tray-Icon zum Beenden.", ui::yellow("Tipp"));
|
||||
println!();
|
||||
|
||||
// Warten auf Strg+C ODER Signal aus dem System-Tray
|
||||
// Warten auf Beendigungssignal (Ctrl+C, Tray-Klick, Inaktivität, Win+L)
|
||||
tokio::select! {
|
||||
res = tokio::signal::ctrl_c() => {
|
||||
let _ = res;
|
||||
@@ -274,6 +327,14 @@ pub async fn mount_container(
|
||||
println!();
|
||||
println!(" {} Beendigungssignal aus System-Tray empfangen.", ui::yellow("[!]"));
|
||||
}
|
||||
_ = session_lock_rx.recv() => {
|
||||
println!();
|
||||
println!(" {} Windows-Sitzung gesperrt (Win + L) — Auto-Lock ausgelöst!", ui::yellow("[!]"));
|
||||
}
|
||||
_ = idle_shutdown_rx.recv() => {
|
||||
println!();
|
||||
println!(" {} Inaktivitäts-Timeout erreicht — Auto-Lock ausgelöst!", ui::yellow("[!]"));
|
||||
}
|
||||
}
|
||||
print!(" {} Trenne Windows-Netzlaufwerk {} ... ", ui::dim("[-]"), drive_str);
|
||||
let _ = std::io::Write::flush(&mut std::io::stdout());
|
||||
|
||||
Reference in New Issue
Block a user