added cleanup struct to remove temporary directory

This commit is contained in:
root 2020-09-21 15:11:10 +00:00
parent 6c9a26d326
commit c2c3f6b44d
2 changed files with 71 additions and 74 deletions

View File

@ -47,14 +47,14 @@ class SapiLibarchiveSandboxCreate : public LibarchiveSandbox {
}); });
for (const auto &i : files_) { for (const auto &i : files_) {
std::cout << "ADD FILE -------" << i << std::endl; std::cout << "ADD FILE -------" << i << std::endl;
struct stat s; struct stat s;
stat(i.c_str(), &s); stat(i.c_str(), &s);
if (S_ISDIR(s.st_mode)) { if (S_ISDIR(s.st_mode)) {
policy = policy.AddDirectory(i); policy = policy.AddDirectory(i);
} else { } else {
policy = policy.AddFile(i); policy = policy.AddFile(i);
} }
} }
return policy.BuildOrDie(); return policy.BuildOrDie();

View File

@ -231,23 +231,20 @@ static void create(const char *initial_filename, int compress,
// prepend /output/ so that it will work with the security policy. // prepend /output/ so that it will work with the security policy.
std::string abs_path = MakeAbsolutePathAtCWD(std::string(initial_filename)); std::string abs_path = MakeAbsolutePathAtCWD(std::string(initial_filename));
std::cout << "initial_filename = " << initial_filename << std::endl; std::cout << "initial_filename = " << initial_filename << std::endl;
auto [archive_path, filename_tmp] = sandbox2::file::SplitPath(abs_path); auto [archive_path, filename_tmp] = sandbox2::file::SplitPath(abs_path);
std::cout << "filename_tmp = " << filename_tmp << std::endl; std::cout << "filename_tmp = " << filename_tmp << std::endl;
std::cout << "archive_path_first = " << archive_path << std::endl; std::cout << "archive_path_first = " << archive_path << std::endl;
std::string filename("/output/"); std::string filename("/output/");
filename.append(filename_tmp); filename.append(filename_tmp);
std::cout << "filename = " << filename << std::endl; std::cout << "filename = " << filename << std::endl;
std::cout << "archive_path = " << archive_path << std::endl; std::cout << "archive_path = " << archive_path << std::endl;
std::cout << "absolute_paths: " << std::endl;
std::cout << "absolute_paths: " << std::endl;
std::vector<std::string> absolute_paths = MakeAbsolutePathsVec(argv); std::vector<std::string> absolute_paths = MakeAbsolutePathsVec(argv);
for (const auto &i : absolute_paths) { for (const auto &i : absolute_paths) {
std::cout << i << std::endl; std::cout << i << std::endl;
@ -255,7 +252,8 @@ static void create(const char *initial_filename, int compress,
std::cout << "=======\n"; std::cout << "=======\n";
std::vector<std::string> relative_paths; std::vector<std::string> relative_paths;
sandbox2::util::CharPtrArrToVecString(const_cast<char *const *>(argv), &relative_paths); sandbox2::util::CharPtrArrToVecString(const_cast<char *const *>(argv),
&relative_paths);
SapiLibarchiveSandboxCreate sandbox(absolute_paths, archive_path); SapiLibarchiveSandboxCreate sandbox(absolute_paths, archive_path);
CHECK(sandbox.Init().ok()) << "Error during sandbox initialization"; CHECK(sandbox.Init().ok()) << "Error during sandbox initialization";
@ -321,12 +319,10 @@ static void create(const char *initial_filename, int compress,
CHECK(ret2.value() != ARCHIVE_FATAL) CHECK(ret2.value() != ARCHIVE_FATAL)
<< "Unexpected result from write_open_filename call"; << "Unexpected result from write_open_filename call";
int file_idx = 0; int file_idx = 0;
// while (*argv != NULL) { // while (*argv != NULL) {
for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) { for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
std::cout << "\n\nhandling file: " << relative_paths[file_idx] << std::endl; std::cout << "\n\nhandling file: " << relative_paths[file_idx] << std::endl;
ret = api.archive_read_disk_new(); ret = api.archive_read_disk_new();
CHECK(ret.ok()) << "read_disk_new call failed"; CHECK(ret.ok()) << "read_disk_new call failed";
@ -334,8 +330,6 @@ for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
sapi::v::RemotePtr disk(ret.value()); sapi::v::RemotePtr disk(ret.value());
#ifndef NO_LOOKUP #ifndef NO_LOOKUP
ret2 = api.archive_read_disk_set_standard_lookup(&disk); ret2 = api.archive_read_disk_set_standard_lookup(&disk);
CHECK(ret2.ok()) << "read_disk_set_standard_lookup call failed"; CHECK(ret2.ok()) << "read_disk_set_standard_lookup call failed";
@ -343,20 +337,17 @@ for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
<< "Unexpected result from read_disk_set_standard_lookup call"; << "Unexpected result from read_disk_set_standard_lookup call";
#endif #endif
// ret2 = api.archive_read_disk_open(&disk, // ret2 = api.archive_read_disk_open(&disk,
// sapi::v::ConstCStr(*argv).PtrBefore()); // sapi::v::ConstCStr(*argv).PtrBefore());
ret2 = api.archive_read_disk_open(&disk, ret2 = api.archive_read_disk_open(
sapi::v::ConstCStr(absolute_paths[file_idx].c_str()).PtrBefore()); &disk,
sapi::v::ConstCStr(absolute_paths[file_idx].c_str()).PtrBefore());
CHECK(ret2.ok()) << "read_disk_open call failed"; CHECK(ret2.ok()) << "read_disk_open call failed";
CHECK(ret2.value() == ARCHIVE_OK) CHECK(ret2.value() == ARCHIVE_OK)
<< CheckStatusAndGetString(api.archive_error_string(&disk), sandbox); << CheckStatusAndGetString(api.archive_error_string(&disk), sandbox);
for (;;) { for (;;) {
int needcr = 0; int needcr = 0;
@ -375,70 +366,66 @@ for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
break; break;
} }
CHECK(ret2.value() == ARCHIVE_OK) CHECK(ret2.value() == ARCHIVE_OK)
<< CheckStatusAndGetString(api.archive_error_string(&disk), sandbox); << CheckStatusAndGetString(api.archive_error_string(&disk), sandbox);
ret2 = api.archive_read_disk_descend(&disk); ret2 = api.archive_read_disk_descend(&disk);
CHECK(ret2.ok()) << "read_disk_descend call failed"; CHECK(ret2.ok()) << "read_disk_descend call failed";
// After using the absolute path before, we now need to add the pathname
// to the archive entry. This would help store the files by their relative
// paths. However, in the case where a directory is added to the archive,
// all of the files inside of it are addes as well so we replace the
// absolute path prefix with the relative one. Example: we add the folder
// test_files which becomes /absolute/path/test_files and the files inside
// of it will become /absolute/path/test_files/file1 and we change it to
// test_files/file1 so that it is relative.
// After using the absolute path before, we now need to add the pathname // std::cout << "relative = " << relative_paths[file_idx] << std::endl;
// to the archive entry. This would help store the files by their relative paths. // std::cout << "absolute = " << absolute_paths[file_idx] << std::endl;
// However, in the case where a directory is added to the archive, all of the files inside std::string path_name =
// of it are addes as well so we replace the absolute path prefix with the relative one. CheckStatusAndGetString(api.archive_entry_pathname(&entry), sandbox);
// Example: we add the folder test_files which becomes /absolute/path/test_files and
// the files inside of it will become /absolute/path/test_files/file1 and we change it to
// test_files/file1 so that it is relative.
// std::cout << "relative = " << relative_paths[file_idx] << std::endl; std::cout << "path_name initial = " << path_name << std::endl;
// std::cout << "absolute = " << absolute_paths[file_idx] << std::endl; path_name.replace(path_name.begin(),
std::string path_name = CheckStatusAndGetString(api.archive_entry_pathname(&entry), sandbox); path_name.begin() + absolute_paths[file_idx].length(),
relative_paths[file_idx]);
std::cout << "path_name initial = " << path_name << std::endl; // std::cout << "path_name after = " << path_name << std::endl;
path_name.replace(path_name.begin(), path_name.begin() + absolute_paths[file_idx].length(), relative_paths[file_idx]);
// std::cout << "path_name after = " << path_name << std::endl; // On top of those changes, we need to remove leading '/' characters
// and also remove everything up to the last occurrence of '../'.
// On top of those changes, we need to remove leading '/' characters size_t found = path_name.find_first_not_of("/");
// and also remove everything up to the last occurrence of '../'. if (found != std::string::npos) {
size_t found = path_name.find_first_not_of("/");
if (found != std::string::npos) {
path_name.erase(path_name.begin(), path_name.begin() + found); path_name.erase(path_name.begin(), path_name.begin() + found);
} }
std::cout << "path_name 2 = " << path_name << std::endl; std::cout << "path_name 2 = " << path_name << std::endl;
found = path_name.rfind("../"); found = path_name.rfind("../");
std::cout << "found = " << found << std::endl; std::cout << "found = " << found << std::endl;
if (found != std::string::npos) { if (found != std::string::npos) {
path_name = path_name.substr(found + 3); path_name = path_name.substr(found + 3);
} }
std::cout << "path_name 3 = " << path_name << std::endl; std::cout << "path_name 3 = " << path_name << std::endl;
CHECK(api.archive_entry_set_pathname(&entry, sapi::v::ConstCStr(path_name.c_str()).PtrBefore()).ok()) << "Could not set pathname";
CHECK(api.archive_entry_set_pathname(
&entry, sapi::v::ConstCStr(path_name.c_str()).PtrBefore())
.ok())
<< "Could not set pathname";
if (verbose) { if (verbose) {
std::cout << "pathname = "; std::cout << "pathname = ";
std::cout << CheckStatusAndGetString(api.archive_entry_pathname(&entry), std::cout << CheckStatusAndGetString(api.archive_entry_pathname(&entry),
sandbox); sandbox);
needcr = 1; needcr = 1;
} }
ret2 = api.archive_write_header(&a, &entry); ret2 = api.archive_write_header(&a, &entry);
CHECK(ret2.ok()) << "write_header call failed"; CHECK(ret2.ok()) << "write_header call failed";
if (ret2.value() < ARCHIVE_OK) { if (ret2.value() < ARCHIVE_OK) {
std::cout << CheckStatusAndGetString(api.archive_error_string(&a), std::cout << CheckStatusAndGetString(api.archive_error_string(&a),
sandbox); sandbox);
@ -446,7 +433,6 @@ for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
} }
CHECK(ret2.value() != ARCHIVE_FATAL) CHECK(ret2.value() != ARCHIVE_FATAL)
<< "Unexpected result from write_header call"; << "Unexpected result from write_header call";
if (ret2.value() > ARCHIVE_FAILED) { if (ret2.value() > ARCHIVE_FAILED) {
// TODO copy part here // TODO copy part here
@ -461,27 +447,30 @@ for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
sapi::v::Int read_ret; sapi::v::Int read_ret;
sapi::v::Array<char> buff(16384); sapi::v::Array<char> buff(16384);
sapi::v::UInt ssize(16384); sapi::v::UInt ssize(16384);
CHECK(sandbox.Allocate(&buff, true).ok()) << "Could not allocate remote buffer";
// CHECK(sandbox.Allocate(&buff, true).ok()) << "Could not allocate // CHECK(sandbox.Allocate(&buff, true).ok()) << "Could not allocate
// buffer"; // buffer";
CHECK(sandbox.TransferToSandboxee(&sapi_fd).ok()) CHECK(sandbox.TransferToSandboxee(&sapi_fd).ok())
<< "Could not transfer file descriptor"; << "Could not transfer file descriptor";
// sandbox.Call() // sandbox.Call()
CHECK(sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrBoth(), &ssize) CHECK(sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrNone(), &ssize)
.ok()) .ok())
<< "Read call failed"; << "Read call failed";
while (read_ret.GetValue() > 0) { while (read_ret.GetValue() > 0) {
CHECK(api.archive_write_data(&a, buff.PtrBoth(), read_ret.GetValue()) CHECK(api.archive_write_data(&a, buff.PtrNone(), read_ret.GetValue())
.ok()) .ok())
<< "write_data call failed"; << "write_data call failed";
// CHECK(ret.ok()); // CHECK(ret.ok());
CHECK( CHECK(
sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrBoth(), &ssize) sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrNone(), &ssize)
.ok()) .ok())
<< "Read call failed"; << "Read call failed";
} }
// TODO close fds // TODO close fds
CHECK(sapi_fd.CloseRemoteFd(sandbox.GetRpcChannel()).ok()) << "Could not close remote fd"; // CHECK(sapi_fd.CloseRemoteFd(sandbox.GetRpcChannel()).ok())
sapi_fd.CloseLocalFd(); // << "Could not close remote fd";
// sapi_fd.CloseLocalFd();
} }
CHECK(api.archive_entry_free(&entry).ok()) << "entry_free call failed"; CHECK(api.archive_entry_free(&entry).ok()) << "entry_free call failed";
@ -517,6 +506,14 @@ static void extract(const char *filename, int do_extract, int flags) {
if (do_extract) { if (do_extract) {
tmp_dir = CreateTempDirAtCWD(); tmp_dir = CreateTempDirAtCWD();
} }
struct ExtractTempDirectoryCleanup {
~ExtractTempDirectoryCleanup() {
sandbox2::file_util::fileops::DeleteRecursively(capture);
}
const std::string capture;
} cleanup{tmp_dir};
std::cout << "extract" << std::endl; std::cout << "extract" << std::endl;
std::string filename_absolute = MakeAbsolutePathAtCWD(filename); std::string filename_absolute = MakeAbsolutePathAtCWD(filename);
@ -679,9 +676,9 @@ static void extract(const char *filename, int do_extract, int flags) {
CHECK(ret2.ok()) << "write_free call failed"; CHECK(ret2.ok()) << "write_free call failed";
CHECK(!ret2.value()) << "Unexpected result from write_free call"; CHECK(!ret2.value()) << "Unexpected result from write_free call";
if (do_extract) { // if (do_extract) {
sandbox2::file_util::fileops::DeleteRecursively(tmp_dir); // sandbox2::file_util::fileops::DeleteRecursively(tmp_dir);
} // }
} }
static int copy_data(sapi::v::RemotePtr *ar, sapi::v::RemotePtr *aw, static int copy_data(sapi::v::RemotePtr *ar, sapi::v::RemotePtr *aw,