#include "../src/security/archive/ArchiveSandbox.hpp" #include #include #include #include #include #include #include #include int main() { namespace fs = std::filesystem; char pattern[] = "/tmp/bastionguard-sandbox-tests-XXXXXX"; char* temporary = ::mkdtemp(pattern); assert(temporary); const fs::path dir(temporary); const auto fake_bwrap = dir / "bwrap"; const auto worker = dir / "worker"; const auto archive = dir / "test.zip"; { std::ofstream out(fake_bwrap); out << "#!/bin/sh\n" "case \"${BG_FAKE_MODE:-normal}\" in\n" " huge) head -c 2097152 /dev/zero | tr '\\000' 'X';;\n" " inherited) (sleep 3) & printf '{}\\n';;\n" " *) printf '{\"is_zip\":true,\"risk_score\":0}\\n';;\n" "esac\n"; } assert(::chmod(fake_bwrap.c_str(), 0700) == 0); { std::ofstream out(worker); out << "placeholder"; } { std::ofstream out(archive); out << "PK"; } const std::string original_path = std::getenv("PATH") ? std::getenv("PATH") : "/usr/bin:/bin"; const auto test_path = dir.string() + ":" + original_path; assert(::setenv("PATH", test_path.c_str(), 1) == 0); assert(::setenv("BG_FAKE_MODE", "normal", 1) == 0); const auto normal = analyze_archive_in_sandbox(worker.string(), archive.string(), 3); assert(normal.success && normal.is_zip && !normal.sandbox_failed); assert(::setenv("BG_FAKE_MODE", "huge", 1) == 0); const auto huge = analyze_archive_in_sandbox(worker.string(), archive.string(), 3); assert(!huge.success && huge.sandbox_failed && huge.reason_code == "ARCHIVE_SANDBOX_OUTPUT_LIMIT"); assert(::setenv("BG_FAKE_MODE", "inherited", 1) == 0); const auto inherited = run_archive_worker_bwrap(worker.string(), archive.string(), 1); assert(inherited.timed_out); // parent exited but descendant kept stdout open const auto missing = analyze_archive_in_sandbox((dir / "missing").string(), archive.string(), 1); assert(!missing.success && missing.sandbox_failed); fs::remove_all(dir); std::cout << "archive sandbox regressions: OK\n"; }