Securely wipe state.db on exit (#216)
- Add secure_wipe_file() to utils/crypto.py for file overwrites + deletion - Add secure_wipe parameter to StateManager.stop() method - Wipes all SQLite WAL files (.db, .db-wal, .db-shm) with 3 passes - Normal exit now calls state.stop(secure_wipe=True) to clear state database - Falls back to regular delete if secure wipe fails - Prevents state.db from persisting on disk after shutdown
This commit is contained in:
+1
-1
@@ -244,7 +244,7 @@ def start(daemon, passive_only):
|
|||||||
res_mon.stop()
|
res_mon.stop()
|
||||||
engine.stop_all()
|
engine.stop_all()
|
||||||
tool_manager.stop_all()
|
tool_manager.stop_all()
|
||||||
state.stop()
|
state.stop(secure_wipe=True)
|
||||||
bus.stop()
|
bus.stop()
|
||||||
console.print("[green]SystemMonitor stopped.[/green]")
|
console.print("[green]SystemMonitor stopped.[/green]")
|
||||||
|
|
||||||
|
|||||||
+22
-2
@@ -63,8 +63,12 @@ class StateManager:
|
|||||||
self._writer_thread.start()
|
self._writer_thread.start()
|
||||||
logger.info("StateManager writer started (db=%s)", self._db_path)
|
logger.info("StateManager writer started (db=%s)", self._db_path)
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self, secure_wipe: bool = False) -> None:
|
||||||
"""Flush remaining writes and stop the writer thread."""
|
"""Flush remaining writes and stop the writer thread.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
secure_wipe: If True, securely overwrite and delete the state database.
|
||||||
|
"""
|
||||||
if not self._running:
|
if not self._running:
|
||||||
return
|
return
|
||||||
self._running = False
|
self._running = False
|
||||||
@@ -75,6 +79,22 @@ class StateManager:
|
|||||||
if self._write_conn:
|
if self._write_conn:
|
||||||
self._write_conn.close()
|
self._write_conn.close()
|
||||||
self._write_conn = None
|
self._write_conn = None
|
||||||
|
|
||||||
|
# Secure wipe if requested
|
||||||
|
if secure_wipe:
|
||||||
|
from utils.crypto import secure_wipe_file
|
||||||
|
# SQLite creates multiple files in WAL mode: db, db-wal, db-shm
|
||||||
|
for suffix in ["", "-wal", "-shm"]:
|
||||||
|
filepath = self._db_path + suffix
|
||||||
|
if os.path.isfile(filepath):
|
||||||
|
try:
|
||||||
|
if secure_wipe_file(filepath, passes=3):
|
||||||
|
logger.info("Securely wiped %s", filepath)
|
||||||
|
else:
|
||||||
|
logger.warning("Secure wipe failed for %s (used regular delete)", filepath)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to wipe %s: %s", filepath, e)
|
||||||
|
|
||||||
logger.info("StateManager stopped")
|
logger.info("StateManager stopped")
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
@@ -246,3 +246,39 @@ class LUKSContainer:
|
|||||||
@property
|
@property
|
||||||
def is_open(self) -> bool:
|
def is_open(self) -> bool:
|
||||||
return Path(self.device_path).exists()
|
return Path(self.device_path).exists()
|
||||||
|
|
||||||
|
|
||||||
|
def secure_wipe_file(filepath: str, passes: int = 1) -> bool:
|
||||||
|
"""Securely wipe a file by overwriting with random data before deletion.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath: Path to file to wipe
|
||||||
|
passes: Number of overwrite passes (default 1, use 3 for stronger security)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if file was successfully wiped, False otherwise
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
file_size = os.path.getsize(filepath)
|
||||||
|
if file_size == 0:
|
||||||
|
# Empty file, just delete
|
||||||
|
os.unlink(filepath)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Overwrite passes
|
||||||
|
for _ in range(passes):
|
||||||
|
with open(filepath, "wb") as f:
|
||||||
|
f.write(os.urandom(file_size))
|
||||||
|
f.flush()
|
||||||
|
os.fsync(f.fileno())
|
||||||
|
|
||||||
|
# Delete the file
|
||||||
|
os.unlink(filepath)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
# Fallback: try regular delete if secure wipe fails
|
||||||
|
try:
|
||||||
|
os.unlink(filepath)
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user