53 lines
2.2 KiB
C++
53 lines
2.2 KiB
C++
#include "../src/security/archive/ArchiveSandbox.hpp"
|
|
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
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";
|
|
}
|