feat(anti-forensics): implement incremental auto-vacuum, chunk shredding, and plausible deniability
This commit is contained in:
+53
-15
@@ -107,33 +107,56 @@ pub async fn mount_container(
|
||||
.read_meta()
|
||||
.context("Konnte Container-Header nicht lesen")?;
|
||||
|
||||
let (dek, version) = match auth {
|
||||
let (dek, version, vault_id) = match auth {
|
||||
ContainerAuth::Password(ref password) => {
|
||||
ui::step(2, 4, "🔑", "Leite KEK via Argon2id ab...");
|
||||
let kek = derive_kek(password, &meta.kdf_salt, &meta.kdf_params)
|
||||
.context("Schlüsselableitung fehlgeschlagen")?;
|
||||
let mut unwrapped = None;
|
||||
|
||||
ui::step(3, 4, "🔓", "Entschlüssele DEK via AES-256-GCM...");
|
||||
let dek = unwrap_dek(
|
||||
&kek,
|
||||
&meta.wrapped_dek,
|
||||
&meta.header_nonce,
|
||||
&meta.header_tag,
|
||||
)
|
||||
.context("Ungültiges Master-Passwort oder Container beschädigt")?;
|
||||
(dek, meta.version)
|
||||
for slot in &meta.slots {
|
||||
if let Ok(kek) = derive_kek(password, &slot.kdf_salt, &slot.kdf_params) {
|
||||
if let Ok(dek) = unwrap_dek(
|
||||
&kek,
|
||||
&slot.wrapped_dek,
|
||||
&slot.header_nonce,
|
||||
&slot.header_tag,
|
||||
) {
|
||||
unwrapped = Some((dek, slot.version, slot.slot_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match unwrapped {
|
||||
Some((dek, ver, slot_id)) => {
|
||||
ui::step(3, 4, "🔓", "Master-Passwort erfolgreich verifiziert & DEK entschlüsselt!");
|
||||
(dek, ver, slot_id)
|
||||
}
|
||||
None => {
|
||||
bail!("Ungültiges Master-Passwort oder Container beschädigt");
|
||||
}
|
||||
}
|
||||
}
|
||||
ContainerAuth::RecoveryKey(ref phrase) => {
|
||||
ui::step(2, 4, "🔑", "Dekodiere DEK aus 24-Wort Notfallschlüssel...");
|
||||
let dek = mnemonic_to_dek(phrase)
|
||||
.context("Ungültiger 24-Wort Notfallschlüssel")?;
|
||||
ui::step(3, 4, "🔓", "Notfallschlüssel erfolgreich verifiziert!");
|
||||
(dek, meta.version)
|
||||
|
||||
let vault_id = if db.has_hidden_vault().unwrap_or(false) {
|
||||
let is_hidden = {
|
||||
let children = db.list_children_in_vault(2, 1, &dek).unwrap_or_default();
|
||||
!children.is_empty()
|
||||
};
|
||||
if is_hidden { 1 } else { 0 }
|
||||
} else {
|
||||
0
|
||||
};
|
||||
(dek, meta.version, vault_id)
|
||||
}
|
||||
};
|
||||
|
||||
// WebDAV Filesystem und Handler konfigurieren (mit Anti-Leak Shield)
|
||||
let fs = SanctumFs::with_options(db.clone(), dek, version, anti_leak);
|
||||
// WebDAV Filesystem und Handler konfigurieren (mit Anti-Leak Shield & Vault-Routing)
|
||||
let fs = SanctumFs::with_vault(db.clone(), dek, version, anti_leak, vault_id);
|
||||
let last_activity = fs.last_activity();
|
||||
let dav_server = DavHandler::builder()
|
||||
.filesystem(Box::new(fs))
|
||||
@@ -300,6 +323,9 @@ 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 vault_id == 1 {
|
||||
println!(" • Vault: {} (Verschlüsselte Dateinamen)", ui::magenta("Hidden Vault (Slot 1)"));
|
||||
}
|
||||
if let Some(secs) = idle_timeout {
|
||||
println!(" • Auto-Lock: Inaktivität nach {}s", secs);
|
||||
}
|
||||
@@ -350,6 +376,18 @@ pub async fn mount_container(
|
||||
let _ = shutdown_tx.send(true);
|
||||
let _ = server_handle.await;
|
||||
|
||||
// Storage-Kompaktierung (Incremental Vacuum), falls freie Seiten existieren
|
||||
if let Ok(freelist) = db.freelist_count() {
|
||||
if freelist > 0 {
|
||||
print!(" {} Führe Storage-Kompaktierung aus ({} freie Seiten) ... ", ui::dim("[-]"), freelist);
|
||||
let _ = std::io::Write::flush(&mut std::io::stdout());
|
||||
match db.incremental_vacuum(None) {
|
||||
Ok(freed) => println!("{} ({} Seiten freigegeben)", ui::green("OK"), freed),
|
||||
Err(e) => println!("{}", ui::yellow(&format!("Warnung ({e})"))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SQLite WAL Checkpoint erzwingen
|
||||
print!(" {} Führe SQLite WAL-Checkpoint aus ... ", ui::dim("[-]"));
|
||||
let _ = std::io::Write::flush(&mut std::io::stdout());
|
||||
|
||||
Reference in New Issue
Block a user