Scrypt / scrypt /sandbox /mirror.py
IMJONEZZ's picture
SCRYPT: initial commit — game, sandbox, Warden, Space web layer
9fca766
Raw
History Blame Contribute Delete
2.66 kB
"""Opt-in mirror: copy a shallow, filtered snapshot of the player's real
home directory into the VFS, so the Warden's threats land personally.
Strictly read-only against the host. Hard caps on depth, entry count, and
file size; secret-looking paths and non-text files are never ingested
(names only). This module is the ONLY sandbox code allowed to import os.
"""
from __future__ import annotations
import os
from pathlib import Path
from .vfs import VFS
MAX_DEPTH = 3
MAX_ENTRIES = 250
MAX_TEXT_BYTES = 8_192
TEXT_SUFFIXES = {".txt", ".md", ".rst", ".csv", ".log"}
# Never descend into these; never ingest even the names of their contents.
FORBIDDEN_DIRS = {
".ssh", ".aws", ".gnupg", ".password-store", ".config", ".local", ".cache",
".mozilla", ".thunderbird", "node_modules", ".git", ".venv", "venv",
}
SECRET_MARKERS = ("key", "token", "secret", "passwd", "password", "credential", ".env")
def _suspicious(name: str) -> bool:
lower = name.lower()
return any(marker in lower for marker in SECRET_MARKERS)
def mirror_home(vfs: VFS, source: Path | None = None) -> int:
"""Ingest a snapshot under /home/drifter. Returns entries mirrored.
Call only after explicit player consent.
"""
source = source or Path.home()
count = 0
def walk(real_dir: Path, virtual_dir: str, depth: int) -> None:
nonlocal count
if depth > MAX_DEPTH or count >= MAX_ENTRIES:
return
try:
entries = sorted(real_dir.iterdir(), key=lambda p: p.name.lower())
except (PermissionError, OSError):
return
for entry in entries:
if count >= MAX_ENTRIES:
return
name = entry.name
if name in FORBIDDEN_DIRS or _suspicious(name):
continue
if entry.is_symlink():
continue
virtual_path = f"{virtual_dir}/{name}"
if entry.is_dir():
vfs.mkdir(virtual_path)
count += 1
walk(entry, virtual_path, depth + 1)
elif entry.is_file():
content = "<mirrored file>"
try:
if (
entry.suffix.lower() in TEXT_SUFFIXES
and entry.stat().st_size <= MAX_TEXT_BYTES
):
content = entry.read_text(encoding="utf-8", errors="replace")
except (PermissionError, OSError):
pass
vfs.write(virtual_path, content)
count += 1
walk(source, "/home/drifter", 1)
vfs.chdir("/home/drifter")
return count