mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Finished the create function of the tar example
This commit is contained in:
parent
7e24ee2232
commit
6c9a26d326
|
@ -1 +1,2 @@
|
||||||
build/
|
build/
|
||||||
|
.cache
|
||||||
|
|
|
@ -24,6 +24,7 @@ target_link_libraries(helpers PUBLIC
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
sandbox2::file_base
|
sandbox2::file_base
|
||||||
sandbox2::executor
|
sandbox2::executor
|
||||||
|
sandbox2::temp_file
|
||||||
glog::glog
|
glog::glog
|
||||||
libarchive_sapi
|
libarchive_sapi
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
std::string MakeAbsolutePathAtCWD(std::string path) {
|
std::string MakeAbsolutePathAtCWD(const std::string &path) {
|
||||||
std::string result = sandbox2::file_util::fileops::MakeAbsolute(
|
std::string result = sandbox2::file_util::fileops::MakeAbsolute(
|
||||||
path, sandbox2::file_util::fileops::GetCWD());
|
path, sandbox2::file_util::fileops::GetCWD());
|
||||||
CHECK(result != "") << "Could not create absolute path for: " << path;
|
CHECK(result != "") << "Could not create absolute path for: " << path;
|
||||||
return sandbox2::file::CleanPath(result);
|
return sandbox2::file::CleanPath(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> MakeAbsolutePathsVec(char *argv[]) {
|
std::vector<std::string> MakeAbsolutePathsVec(const char *argv[]) {
|
||||||
std::vector<std::string> arr;
|
std::vector<std::string> arr;
|
||||||
sandbox2::util::CharPtrArrToVecString(argv, &arr);
|
sandbox2::util::CharPtrArrToVecString(const_cast<char *const *>(argv), &arr);
|
||||||
std::transform(arr.begin(), arr.end(), arr.begin(), MakeAbsolutePathAtCWD);
|
std::transform(arr.begin(), arr.end(), arr.begin(), MakeAbsolutePathAtCWD);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
@ -45,3 +45,13 @@ std::string CheckStatusAndGetString(const sapi::StatusOr<char *> &status,
|
||||||
// sandbox.GetCString(sapi::v::RemotePtr(ret.value())); CHECK(ret.ok()) <<
|
// sandbox.GetCString(sapi::v::RemotePtr(ret.value())); CHECK(ret.ok()) <<
|
||||||
// "Could not transfer error message"; return ret2.value();
|
// "Could not transfer error message"; return ret2.value();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
std::string CreateTempDirAtCWD() {
|
||||||
|
std::string cwd = sandbox2::file_util::fileops::GetCWD();
|
||||||
|
CHECK(!cwd.empty()) << "Could not get current working directory";
|
||||||
|
cwd.append("/");
|
||||||
|
|
||||||
|
sapi::StatusOr<std::string> result = sandbox2::CreateTempDir(cwd);
|
||||||
|
CHECK(result.ok()) << "Could not create temporary directory";
|
||||||
|
return result.value();
|
||||||
|
}
|
|
@ -7,15 +7,16 @@
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
#include "sandboxed_api/sandbox2/util/path.h"
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
|
#include "sandboxed_api/sandbox2/util/temp_file.h"
|
||||||
|
|
||||||
// Used to convert the paths provided as arguments for the program
|
// Used to convert the paths provided as arguments for the program
|
||||||
// (the paths used) to an array of absolute paths. This allows the user
|
// (the paths used) to an array of absolute paths. This allows the user
|
||||||
// to use either relative or absolute paths
|
// to use either relative or absolute paths
|
||||||
std::vector<std::string> MakeAbsolutePathsVec(char *argv[]);
|
std::vector<std::string> MakeAbsolutePathsVec(const char *argv[]);
|
||||||
|
|
||||||
// Converts only one string to an absolute path by prepending the current
|
// Converts only one string to an absolute path by prepending the current
|
||||||
// working directory to the relative path
|
// working directory to the relative path
|
||||||
std::string MakeAbsolutePathAtCWD(std::string path);
|
std::string MakeAbsolutePathAtCWD(const std::string &path);
|
||||||
|
|
||||||
// Calls the archive_error_string and returns the mesage after it was
|
// Calls the archive_error_string and returns the mesage after it was
|
||||||
// transferred to the client process. std::string GetErrorString(sapi::v::Ptr
|
// transferred to the client process. std::string GetErrorString(sapi::v::Ptr
|
||||||
|
@ -28,4 +29,6 @@ std::string CheckStatusAndGetString(const sapi::StatusOr<char *> &status,
|
||||||
// &sandbox, LibarchiveApi *api, sapi::StatusOr<char *>
|
// &sandbox, LibarchiveApi *api, sapi::StatusOr<char *>
|
||||||
// (LibarchiveApi::*func)(sapi::v::Ptr *));
|
// (LibarchiveApi::*func)(sapi::v::Ptr *));
|
||||||
|
|
||||||
|
std::string CreateTempDirAtCWD();
|
||||||
|
|
||||||
#endif // SAPI_LIBARCHIVE_HELPERS_H
|
#endif // SAPI_LIBARCHIVE_HELPERS_H
|
||||||
|
|
|
@ -1,74 +1,119 @@
|
||||||
#ifndef SAPI_LIBARCHIVE_SANDBOX_H
|
#ifndef SAPI_LIBARCHIVE_SANDBOX_H
|
||||||
#define SAPI_LIBARCHIVE_SANDBOX_H
|
#define SAPI_LIBARCHIVE_SANDBOX_H
|
||||||
|
|
||||||
|
#include <asm/unistd_64.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
#include "libarchive_sapi.sapi.h"
|
#include "libarchive_sapi.sapi.h"
|
||||||
|
|
||||||
class SapiLibarchiveSandboxCreate : public LibarchiveSandbox {
|
class SapiLibarchiveSandboxCreate : public LibarchiveSandbox {
|
||||||
public:
|
public:
|
||||||
// TODO
|
// TODO
|
||||||
explicit SapiLibarchiveSandboxCreate() {}
|
explicit SapiLibarchiveSandboxCreate(const std::vector<std::string> &files,
|
||||||
|
absl::string_view archive_path)
|
||||||
|
: files_(files), archive_path_(archive_path) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||||
sandbox2::PolicyBuilder*) override {
|
sandbox2::PolicyBuilder *) override {
|
||||||
return sandbox2::PolicyBuilder().BuildOrDie();
|
sandbox2::PolicyBuilder policy =
|
||||||
|
sandbox2::PolicyBuilder()
|
||||||
|
.AddDirectoryAt(archive_path_, "/output", false)
|
||||||
|
.AllowRead()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowGetIDs()
|
||||||
|
.AllowSafeFcntl()
|
||||||
|
.AllowStat()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowSyscalls({
|
||||||
|
__NR_futex,
|
||||||
|
__NR_lseek,
|
||||||
|
__NR_close,
|
||||||
|
__NR_gettid,
|
||||||
|
__NR_umask,
|
||||||
|
__NR_utimensat,
|
||||||
|
__NR_unlink,
|
||||||
|
__NR_mkdir,
|
||||||
|
__NR_fstatfs,
|
||||||
|
__NR_socket,
|
||||||
|
__NR_connect,
|
||||||
|
__NR_ioctl,
|
||||||
|
__NR_flistxattr,
|
||||||
|
__NR_recvmsg,
|
||||||
|
__NR_getdents64,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto &i : files_) {
|
||||||
|
std::cout << "ADD FILE -------" << i << std::endl;
|
||||||
|
struct stat s;
|
||||||
|
stat(i.c_str(), &s);
|
||||||
|
if (S_ISDIR(s.st_mode)) {
|
||||||
|
policy = policy.AddDirectory(i);
|
||||||
|
} else {
|
||||||
|
policy = policy.AddFile(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return policy.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> files_;
|
||||||
|
absl::string_view archive_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SapiLibarchiveSandboxExtract : public LibarchiveSandbox {
|
class SapiLibarchiveSandboxExtract : public LibarchiveSandbox {
|
||||||
public:
|
public:
|
||||||
// TODO
|
// TODO
|
||||||
explicit SapiLibarchiveSandboxExtract(const std::string& archive_path,
|
explicit SapiLibarchiveSandboxExtract(absl::string_view archive_path,
|
||||||
const int do_extract)
|
const int do_extract,
|
||||||
: archive_path_(archive_path), do_extract_(do_extract) {}
|
absl::string_view tmp_dir)
|
||||||
|
: archive_path_(archive_path),
|
||||||
|
do_extract_(do_extract),
|
||||||
|
tmp_dir_(tmp_dir) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void ModifyExecutor(sandbox2::Executor* executor) override {
|
virtual void ModifyExecutor(sandbox2::Executor *executor) override {
|
||||||
// TODO create /output/ + chdir here if do_execute
|
|
||||||
if (do_extract_) {
|
if (do_extract_) {
|
||||||
// TODO change the directory
|
executor = &executor->set_cwd(std::string(tmp_dir_));
|
||||||
std::cout << "changing dir" << std::endl;
|
|
||||||
if (!sandbox2::file_util::fileops::Exists("/output", false)) {
|
|
||||||
CHECK(sandbox2::util::CreateDirRecursive("/output", 644))
|
|
||||||
<< "Could not create /output directory";
|
|
||||||
}
|
|
||||||
executor = &executor->set_cwd("/output");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||||
sandbox2::PolicyBuilder*) override {
|
sandbox2::PolicyBuilder *) override {
|
||||||
// TODO no auto
|
sandbox2::PolicyBuilder policy = sandbox2::PolicyBuilder()
|
||||||
auto policy = sandbox2::PolicyBuilder()
|
.AllowRead()
|
||||||
.AllowRead()
|
.AllowWrite()
|
||||||
.AllowWrite()
|
.AllowOpen()
|
||||||
.AllowOpen()
|
.AllowSystemMalloc()
|
||||||
.AllowSystemMalloc()
|
.AllowGetIDs()
|
||||||
.AllowGetIDs()
|
.AllowSafeFcntl()
|
||||||
.AllowSafeFcntl()
|
.AllowStat()
|
||||||
.AllowStat()
|
.AllowExit()
|
||||||
.AllowExit()
|
.AllowSyscalls({
|
||||||
.AllowSyscalls({
|
__NR_futex,
|
||||||
__NR_futex,
|
__NR_lseek,
|
||||||
__NR_lseek,
|
__NR_close,
|
||||||
__NR_close,
|
__NR_gettid,
|
||||||
__NR_gettid,
|
__NR_umask,
|
||||||
__NR_umask,
|
__NR_utimensat,
|
||||||
})
|
__NR_unlink,
|
||||||
.AddFile(archive_path_);
|
__NR_mkdir,
|
||||||
|
})
|
||||||
|
.AddFile(archive_path_);
|
||||||
|
|
||||||
if (do_extract_) {
|
if (do_extract_) {
|
||||||
// map "/output/" to cwd
|
// map "/output/" to cwd
|
||||||
policy = policy.AddDirectoryAt(sandbox2::file_util::fileops::GetCWD(),
|
std::string cwd = sandbox2::file_util::fileops::GetCWD();
|
||||||
"/output", false);
|
policy = policy.AddDirectoryAt(cwd, tmp_dir_, false);
|
||||||
}
|
}
|
||||||
return policy.BuildOrDie();
|
return policy.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string archive_path_;
|
absl::string_view archive_path_;
|
||||||
|
absl::string_view tmp_dir_;
|
||||||
const int do_extract_;
|
const int do_extract_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "sandbox.h"
|
#include "sandbox.h"
|
||||||
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
|
#include "sandboxed_api/var_array.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
|
* NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
|
||||||
|
@ -220,98 +223,387 @@ int main(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_CREATE
|
#ifndef NO_CREATE
|
||||||
static char buff[16384];
|
// static char buff[16384];
|
||||||
|
|
||||||
static void create(const char *filename, int compress, const char **argv) {
|
static void create(const char *initial_filename, int compress,
|
||||||
std::cout << "CREATE FILENAME=" << filename << std::endl;
|
const char **argv) {
|
||||||
|
// We split the filename path into dirname and filename. To the filename we
|
||||||
|
// prepend /output/ so that it will work with the security policy.
|
||||||
|
|
||||||
|
std::string abs_path = MakeAbsolutePathAtCWD(std::string(initial_filename));
|
||||||
|
|
||||||
|
std::cout << "initial_filename = " << initial_filename << std::endl;
|
||||||
|
|
||||||
|
auto [archive_path, filename_tmp] = sandbox2::file::SplitPath(abs_path);
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "filename_tmp = " << filename_tmp << std::endl;
|
||||||
|
std::cout << "archive_path_first = " << archive_path << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
std::string filename("/output/");
|
||||||
|
filename.append(filename_tmp);
|
||||||
|
std::cout << "filename = " << filename << std::endl;
|
||||||
|
std::cout << "archive_path = " << archive_path << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "absolute_paths: " << std::endl;
|
||||||
|
std::vector<std::string> absolute_paths = MakeAbsolutePathsVec(argv);
|
||||||
|
for (const auto &i : absolute_paths) {
|
||||||
|
std::cout << i << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "=======\n";
|
||||||
|
|
||||||
|
std::vector<std::string> relative_paths;
|
||||||
|
sandbox2::util::CharPtrArrToVecString(const_cast<char *const *>(argv), &relative_paths);
|
||||||
|
|
||||||
|
SapiLibarchiveSandboxCreate sandbox(absolute_paths, archive_path);
|
||||||
|
CHECK(sandbox.Init().ok()) << "Error during sandbox initialization";
|
||||||
|
LibarchiveApi api(&sandbox);
|
||||||
|
|
||||||
|
ssize_t len;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
sapi::StatusOr<archive *> ret = api.archive_write_new();
|
||||||
|
CHECK(ret.ok()) << "write_new call failed";
|
||||||
|
CHECK(ret.value() != NULL) << "Failed to create write archive";
|
||||||
|
|
||||||
|
sapi::v::RemotePtr a(ret.value());
|
||||||
|
|
||||||
|
sapi::StatusOr<int> ret2;
|
||||||
|
|
||||||
|
switch (compress) {
|
||||||
|
#ifndef NO_BZIP2_CREATE
|
||||||
|
case 'j':
|
||||||
|
case 'y':
|
||||||
|
ret2 = api.archive_write_add_filter_bzip2(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_add_filter_bzip2 call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_add_filter_bzip2 call";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_COMPRESS_CREATE
|
||||||
|
case 'Z':
|
||||||
|
ret2 = api.archive_write_add_filter_compress(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_add_filter_compress call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_add_filter_compress call";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_GZIP_CREATE
|
||||||
|
case 'z':
|
||||||
|
ret2 = api.archive_write_add_filter_gzip(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_add_filter_gzip call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_add_filter_gzip call";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ret2 = api.archive_write_add_filter_none(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_add_filter_none call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_add_filter_none call";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret2 = api.archive_write_set_format_ustar(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_set_format_ustar call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_set_format_ustar call";
|
||||||
|
|
||||||
|
const char *filename_ptr = filename.data();
|
||||||
|
if (filename_ptr != NULL && strcmp(filename_ptr, "-") == 0) {
|
||||||
|
filename_ptr = NULL;
|
||||||
|
}
|
||||||
|
ret2 = api.archive_write_open_filename(
|
||||||
|
&a, sapi::v::ConstCStr(filename_ptr).PtrBefore());
|
||||||
|
CHECK(ret2.ok()) << "write_open_filename call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_open_filename call";
|
||||||
|
|
||||||
|
int file_idx = 0;
|
||||||
|
|
||||||
|
// while (*argv != NULL) {
|
||||||
|
for (int file_idx = 0; file_idx < absolute_paths.size(); ++file_idx) {
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "\n\nhandling file: " << relative_paths[file_idx] << std::endl;
|
||||||
|
ret = api.archive_read_disk_new();
|
||||||
|
CHECK(ret.ok()) << "read_disk_new call failed";
|
||||||
|
CHECK(ret.value() != NULL) << "Failed to create read_disk archive";
|
||||||
|
|
||||||
|
sapi::v::RemotePtr disk(ret.value());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_LOOKUP
|
||||||
|
ret2 = api.archive_read_disk_set_standard_lookup(&disk);
|
||||||
|
CHECK(ret2.ok()) << "read_disk_set_standard_lookup call failed";
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from read_disk_set_standard_lookup call";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ret2 = api.archive_read_disk_open(&disk,
|
||||||
|
// sapi::v::ConstCStr(*argv).PtrBefore());
|
||||||
|
|
||||||
|
ret2 = api.archive_read_disk_open(&disk,
|
||||||
|
sapi::v::ConstCStr(absolute_paths[file_idx].c_str()).PtrBefore());
|
||||||
|
|
||||||
|
CHECK(ret2.ok()) << "read_disk_open call failed";
|
||||||
|
CHECK(ret2.value() == ARCHIVE_OK)
|
||||||
|
<< CheckStatusAndGetString(api.archive_error_string(&disk), sandbox);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int needcr = 0;
|
||||||
|
|
||||||
|
sapi::StatusOr<archive_entry *> ret3;
|
||||||
|
ret3 = api.archive_entry_new();
|
||||||
|
|
||||||
|
CHECK(ret3.ok()) << "entry_new call failed";
|
||||||
|
CHECK(ret3.value() != NULL) << "Failed to create archive_entry";
|
||||||
|
|
||||||
|
sapi::v::RemotePtr entry(ret3.value());
|
||||||
|
|
||||||
|
ret2 = api.archive_read_next_header2(&disk, &entry);
|
||||||
|
CHECK(ret2.ok()) << "read_next_header2 call failed";
|
||||||
|
|
||||||
|
if (ret2.value() == ARCHIVE_EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CHECK(ret2.value() == ARCHIVE_OK)
|
||||||
|
<< CheckStatusAndGetString(api.archive_error_string(&disk), sandbox);
|
||||||
|
|
||||||
|
ret2 = api.archive_read_disk_descend(&disk);
|
||||||
|
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.
|
||||||
|
|
||||||
|
// std::cout << "relative = " << relative_paths[file_idx] << std::endl;
|
||||||
|
// std::cout << "absolute = " << absolute_paths[file_idx] << std::endl;
|
||||||
|
std::string path_name = CheckStatusAndGetString(api.archive_entry_pathname(&entry), sandbox);
|
||||||
|
|
||||||
|
std::cout << "path_name initial = " << 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 '../'.
|
||||||
|
|
||||||
|
size_t found = path_name.find_first_not_of("/");
|
||||||
|
if (found != std::string::npos) {
|
||||||
|
path_name.erase(path_name.begin(), path_name.begin() + found);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "path_name 2 = " << path_name << std::endl;
|
||||||
|
|
||||||
|
found = path_name.rfind("../");
|
||||||
|
std::cout << "found = " << found << std::endl;
|
||||||
|
if (found != std::string::npos) {
|
||||||
|
path_name = path_name.substr(found + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
std::cout << "pathname = ";
|
||||||
|
std::cout << CheckStatusAndGetString(api.archive_entry_pathname(&entry),
|
||||||
|
sandbox);
|
||||||
|
needcr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ret2 = api.archive_write_header(&a, &entry);
|
||||||
|
CHECK(ret2.ok()) << "write_header call failed";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (ret2.value() < ARCHIVE_OK) {
|
||||||
|
std::cout << CheckStatusAndGetString(api.archive_error_string(&a),
|
||||||
|
sandbox);
|
||||||
|
needcr = 1;
|
||||||
|
}
|
||||||
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
|
<< "Unexpected result from write_header call";
|
||||||
|
|
||||||
|
|
||||||
|
if (ret2.value() > ARCHIVE_FAILED) {
|
||||||
|
// TODO copy part here
|
||||||
|
int fd = open(CheckStatusAndGetString(
|
||||||
|
api.archive_entry_sourcepath(&entry), sandbox)
|
||||||
|
.c_str(),
|
||||||
|
O_RDONLY);
|
||||||
|
|
||||||
|
CHECK(fd >= 0) << "Could not open file";
|
||||||
|
|
||||||
|
sapi::v::Fd sapi_fd(fd);
|
||||||
|
sapi::v::Int read_ret;
|
||||||
|
sapi::v::Array<char> buff(16384);
|
||||||
|
sapi::v::UInt ssize(16384);
|
||||||
|
// CHECK(sandbox.Allocate(&buff, true).ok()) << "Could not allocate
|
||||||
|
// buffer";
|
||||||
|
CHECK(sandbox.TransferToSandboxee(&sapi_fd).ok())
|
||||||
|
<< "Could not transfer file descriptor";
|
||||||
|
// sandbox.Call()
|
||||||
|
CHECK(sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrBoth(), &ssize)
|
||||||
|
.ok())
|
||||||
|
<< "Read call failed";
|
||||||
|
while (read_ret.GetValue() > 0) {
|
||||||
|
CHECK(api.archive_write_data(&a, buff.PtrBoth(), read_ret.GetValue())
|
||||||
|
.ok())
|
||||||
|
<< "write_data call failed";
|
||||||
|
// CHECK(ret.ok());
|
||||||
|
CHECK(
|
||||||
|
sandbox.Call("read", &read_ret, &sapi_fd, buff.PtrBoth(), &ssize)
|
||||||
|
.ok())
|
||||||
|
<< "Read call failed";
|
||||||
|
}
|
||||||
|
// TODO close fds
|
||||||
|
CHECK(sapi_fd.CloseRemoteFd(sandbox.GetRpcChannel()).ok()) << "Could not close remote fd";
|
||||||
|
sapi_fd.CloseLocalFd();
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(api.archive_entry_free(&entry).ok()) << "entry_free call failed";
|
||||||
|
if (needcr) {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret2 = api.archive_read_close(&disk);
|
||||||
|
CHECK(ret2.ok()) << "read_close call failed";
|
||||||
|
CHECK(!ret2.value()) << "Unexpected result from read_close call";
|
||||||
|
|
||||||
|
ret2 = api.archive_read_free(&disk);
|
||||||
|
CHECK(ret2.ok()) << "read_free call failed";
|
||||||
|
CHECK(!ret2.value()) << "Unexpected result from read_free call";
|
||||||
|
|
||||||
|
// ++argv;
|
||||||
|
// ++file_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret2 = api.archive_write_close(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_close call failed";
|
||||||
|
CHECK(!ret2.value()) << "Unexpected result from write_close call";
|
||||||
|
|
||||||
|
ret2 = api.archive_write_free(&a);
|
||||||
|
CHECK(ret2.ok()) << "write_free call failed";
|
||||||
|
CHECK(!ret2.value()) << "Unexpected result from write_free call";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void extract(const char *filename, int do_extract, int flags) {
|
static void extract(const char *filename, int do_extract, int flags) {
|
||||||
|
std::string tmp_dir;
|
||||||
|
if (do_extract) {
|
||||||
|
tmp_dir = CreateTempDirAtCWD();
|
||||||
|
}
|
||||||
std::cout << "extract" << std::endl;
|
std::cout << "extract" << std::endl;
|
||||||
std::string filename_absolute = MakeAbsolutePathAtCWD(filename);
|
std::string filename_absolute = MakeAbsolutePathAtCWD(filename);
|
||||||
|
|
||||||
std::cout << "filename = " << filename_absolute << std::endl;
|
std::cout << "filename = " << filename_absolute << std::endl;
|
||||||
|
|
||||||
SapiLibarchiveSandboxExtract sandbox(filename_absolute, do_extract);
|
SapiLibarchiveSandboxExtract sandbox(filename_absolute, do_extract, tmp_dir);
|
||||||
CHECK(sandbox.Init().ok()) << "Error during sandbox initialization";
|
CHECK(sandbox.Init().ok()) << "Error during sandbox initialization";
|
||||||
|
|
||||||
LibarchiveApi api(&sandbox);
|
LibarchiveApi api(&sandbox);
|
||||||
|
|
||||||
struct archive *a;
|
// struct archive *a;
|
||||||
struct archive *ext;
|
// struct archive *ext;
|
||||||
struct archive_entry *entry;
|
// struct archive_entry *entry;
|
||||||
int r;
|
// int r;
|
||||||
api.archive_read_new().IgnoreError();
|
|
||||||
sapi::StatusOr<archive *> ret = api.archive_read_new();
|
sapi::StatusOr<archive *> ret = api.archive_read_new();
|
||||||
CHECK(ret.ok()) << "archive_read_new call failed";
|
CHECK(ret.ok()) << "archive_read_new call failed";
|
||||||
// std::cout << "RET VALUE = " << ret.value() << std::endl;
|
// std::cout << "RET VALUE = " << ret.value() << std::endl;
|
||||||
CHECK(ret.value() != NULL) << "Failed to create read archive";
|
CHECK(ret.value() != NULL) << "Failed to create read archive";
|
||||||
a = ret.value();
|
// a = ret.value();
|
||||||
|
|
||||||
|
sapi::v::RemotePtr a(ret.value());
|
||||||
|
|
||||||
ret = api.archive_write_disk_new();
|
ret = api.archive_write_disk_new();
|
||||||
CHECK(ret.ok()) << "write_disk_new call failed";
|
CHECK(ret.ok()) << "write_disk_new call failed";
|
||||||
CHECK(ret.value() != NULL) << "Failed to create write disk archive";
|
CHECK(ret.value() != NULL) << "Failed to create write disk archive";
|
||||||
ext = ret.value();
|
// ext = ret.value();
|
||||||
|
|
||||||
sapi::v::RemotePtr a_ptr(a);
|
sapi::v::RemotePtr ext(ret.value());
|
||||||
sapi::v::RemotePtr ext_ptr(ext);
|
|
||||||
|
|
||||||
sapi::StatusOr<int> ret2;
|
sapi::StatusOr<int> ret2;
|
||||||
ret2 = api.archive_write_disk_set_options(&ext_ptr, flags);
|
ret2 = api.archive_write_disk_set_options(&ext, flags);
|
||||||
CHECK(ret2.ok()) << "write_disk_set_options call failed";
|
CHECK(ret2.ok()) << "write_disk_set_options call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from write_disk_set_options call";
|
<< "Unexpected result from write_disk_set_options call";
|
||||||
|
|
||||||
#ifndef NO_BZIP2_EXTRACT
|
#ifndef NO_BZIP2_EXTRACT
|
||||||
ret2 = api.archive_read_support_filter_bzip2(&a_ptr);
|
ret2 = api.archive_read_support_filter_bzip2(&a);
|
||||||
CHECK(ret2.ok()) << "read_support_filter_bzip2 call failed";
|
CHECK(ret2.ok()) << "read_support_filter_bzip2 call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from read_support_filter_bzip2 call";
|
<< "Unexpected result from read_support_filter_bzip2 call";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_GZIP_EXTRACT
|
#ifndef NO_GZIP_EXTRACT
|
||||||
ret2 = api.archive_read_support_filter_gzip(&a_ptr);
|
ret2 = api.archive_read_support_filter_gzip(&a);
|
||||||
CHECK(ret2.ok()) << "read_suppport_filter_gzip call failed";
|
CHECK(ret2.ok()) << "read_suppport_filter_gzip call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from read_suppport_filter_gzip call";
|
<< "Unexpected result from read_suppport_filter_gzip call";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_COMPRESS_EXTRACT
|
#ifndef NO_COMPRESS_EXTRACT
|
||||||
ret2 = api.archive_read_support_filter_compress(&a_ptr);
|
ret2 = api.archive_read_support_filter_compress(&a);
|
||||||
CHECK(ret2.ok()) << "read_support_filter_compress call failed";
|
CHECK(ret2.ok()) << "read_support_filter_compress call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from read_support_filter_compress call";
|
<< "Unexpected result from read_support_filter_compress call";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_TAR_EXTRACT
|
#ifndef NO_TAR_EXTRACT
|
||||||
ret2 = api.archive_read_support_format_tar(&a_ptr);
|
ret2 = api.archive_read_support_format_tar(&a);
|
||||||
CHECK(ret2.ok()) << "read_support_format_tar call failed";
|
CHECK(ret2.ok()) << "read_support_format_tar call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result fromread_support_format_tar call";
|
<< "Unexpected result fromread_support_format_tar call";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_CPIO_EXTRACT
|
#ifndef NO_CPIO_EXTRACT
|
||||||
ret2 = api.archive_read_support_format_cpio(&a_ptr);
|
ret2 = api.archive_read_support_format_cpio(&a);
|
||||||
CHECK(ret2.ok()) << "read_support_format_cpio call failed";
|
CHECK(ret2.ok()) << "read_support_format_cpio call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from read_support_format_tar call";
|
<< "Unexpected result from read_support_format_tar call";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_LOOKUP
|
#ifndef NO_LOOKUP
|
||||||
ret2 = api.archive_write_disk_set_standard_lookup(&ext_ptr);
|
ret2 = api.archive_write_disk_set_standard_lookup(&ext);
|
||||||
CHECK(ret2.ok()) << "write_disk_set_standard_lookup call failed";
|
CHECK(ret2.ok()) << "write_disk_set_standard_lookup call failed";
|
||||||
CHECK(ret2.value() != ARCHIVE_FATAL)
|
CHECK(ret2.value() != ARCHIVE_FATAL)
|
||||||
<< "Unexpected result from write_disk_set_standard_lookup call";
|
<< "Unexpected result from write_disk_set_standard_lookup call";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (filename != NULL && strcmp(filename, "-") == 0) filename = NULL;
|
const char *filename_ptr = filename_absolute.c_str();
|
||||||
|
if (filename_ptr != NULL && strcmp(filename_ptr, "-") == 0) {
|
||||||
|
filename_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sapi::v::ConstCStr sapi_filename(filename_absolute.c_str());
|
// sapi::v::ConstCStr sapi_filename(filename_absolute.c_str());
|
||||||
|
|
||||||
std::cout << "opening filename" << std::endl;
|
std::cout << "opening filename" << std::endl;
|
||||||
|
|
||||||
ret2 =
|
ret2 = api.archive_read_open_filename(
|
||||||
api.archive_read_open_filename(&a_ptr, sapi_filename.PtrBefore(), 10240);
|
&a, sapi::v::ConstCStr(filename_ptr).PtrBefore(), 10240);
|
||||||
CHECK(ret2.ok()) << "read_open_filename call failed";
|
CHECK(ret2.ok()) << "read_open_filename call failed";
|
||||||
// CHECK(!ret2.value()) << GetErrorString(&a_ptr, sandbox, api);
|
// CHECK(!ret2.value()) << GetErrorString(&a_ptr, sandbox, api);
|
||||||
CHECK(!ret2.value()) << CheckStatusAndGetString(
|
CHECK(!ret2.value()) << CheckStatusAndGetString(api.archive_error_string(&a),
|
||||||
api.archive_error_string(&a_ptr), sandbox);
|
sandbox);
|
||||||
// CHECK(!ret2.value()) << CallFunctionAndGetString(&a_ptr, sandbox, &api,
|
// CHECK(!ret2.value()) << CallFunctionAndGetString(&a_ptr, sandbox, &api,
|
||||||
// &api.archive_error_string);
|
// &api.archive_error_string);
|
||||||
|
|
||||||
|
@ -320,7 +612,7 @@ static void extract(const char *filename, int do_extract, int flags) {
|
||||||
std::cout << "================reading headers==============" << std::endl;
|
std::cout << "================reading headers==============" << std::endl;
|
||||||
sapi::v::IntBase<struct archive_entry *> entry_ptr_tmp(0);
|
sapi::v::IntBase<struct archive_entry *> entry_ptr_tmp(0);
|
||||||
|
|
||||||
ret2 = api.archive_read_next_header(&a_ptr, entry_ptr_tmp.PtrBoth());
|
ret2 = api.archive_read_next_header(&a, entry_ptr_tmp.PtrBoth());
|
||||||
// std::cout << "val = " << ret2.value() << std::endl;
|
// std::cout << "val = " << ret2.value() << std::endl;
|
||||||
CHECK(ret2.ok()) << "read_next_header call failed";
|
CHECK(ret2.ok()) << "read_next_header call failed";
|
||||||
// CHECK(ret2.value() != ARCHIVE_OK) << GetErrorString(&a_ptr, sandbox,
|
// CHECK(ret2.value() != ARCHIVE_OK) << GetErrorString(&a_ptr, sandbox,
|
||||||
|
@ -331,17 +623,17 @@ static void extract(const char *filename, int do_extract, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(ret2.value() == ARCHIVE_OK)
|
CHECK(ret2.value() == ARCHIVE_OK)
|
||||||
<< CheckStatusAndGetString(api.archive_error_string(&a_ptr), sandbox);
|
<< CheckStatusAndGetString(api.archive_error_string(&a), sandbox);
|
||||||
|
|
||||||
sapi::v::RemotePtr entry_ptr(entry_ptr_tmp.GetValue());
|
sapi::v::RemotePtr entry(entry_ptr_tmp.GetValue());
|
||||||
|
|
||||||
if (verbose && do_extract) {
|
if (verbose && do_extract) {
|
||||||
std::cout << "x ";
|
std::cout << "x ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose || !do_extract) {
|
if (verbose || !do_extract) {
|
||||||
std::cout << CheckStatusAndGetString(
|
std::cout << CheckStatusAndGetString(api.archive_entry_pathname(&entry),
|
||||||
api.archive_entry_pathname(&entry_ptr), sandbox)
|
sandbox)
|
||||||
<< " ";
|
<< " ";
|
||||||
needcr = 1;
|
needcr = 1;
|
||||||
}
|
}
|
||||||
|
@ -350,16 +642,16 @@ static void extract(const char *filename, int do_extract, int flags) {
|
||||||
|
|
||||||
if (do_extract) {
|
if (do_extract) {
|
||||||
std::cout << "EXTRACT HERE" << std::endl;
|
std::cout << "EXTRACT HERE" << std::endl;
|
||||||
ret2 = api.archive_write_header(&ext_ptr, &entry_ptr);
|
ret2 = api.archive_write_header(&ext, &entry);
|
||||||
CHECK(ret2.ok()) << "write_header call faield";
|
CHECK(ret2.ok()) << "write_header call failed";
|
||||||
|
|
||||||
std::cout << "val = " << ret2.value() << std::endl;
|
std::cout << "val = " << ret2.value() << std::endl;
|
||||||
|
|
||||||
if (ret2.value() != ARCHIVE_OK) {
|
if (ret2.value() != ARCHIVE_OK) {
|
||||||
std::cout << CheckStatusAndGetString(api.archive_error_string(&a_ptr),
|
std::cout << CheckStatusAndGetString(api.archive_error_string(&a),
|
||||||
sandbox);
|
sandbox);
|
||||||
needcr = 1;
|
needcr = 1;
|
||||||
} else if (copy_data(&a_ptr, &ext_ptr, api, sandbox) != ARCHIVE_OK) {
|
} else if (copy_data(&a, &ext, api, sandbox) != ARCHIVE_OK) {
|
||||||
needcr = 1;
|
needcr = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,21 +663,25 @@ static void extract(const char *filename, int do_extract, int flags) {
|
||||||
|
|
||||||
std::cout << "out of loop" << std::endl;
|
std::cout << "out of loop" << std::endl;
|
||||||
|
|
||||||
ret2 = api.archive_read_close(&a_ptr);
|
ret2 = api.archive_read_close(&a);
|
||||||
CHECK(ret2.ok()) << "read_close call failed";
|
CHECK(ret2.ok()) << "read_close call failed";
|
||||||
CHECK(!ret2.value()) << "Unexpected value from read_close call";
|
CHECK(!ret2.value()) << "Unexpected value from read_close call";
|
||||||
|
|
||||||
ret2 = api.archive_read_free(&a_ptr);
|
ret2 = api.archive_read_free(&a);
|
||||||
CHECK(ret2.ok()) << "read_free call failed";
|
CHECK(ret2.ok()) << "read_free call failed";
|
||||||
CHECK(!ret2.value()) << "Unexpected result from read_free call";
|
CHECK(!ret2.value()) << "Unexpected result from read_free call";
|
||||||
|
|
||||||
ret2 = api.archive_write_close(&ext_ptr);
|
ret2 = api.archive_write_close(&ext);
|
||||||
CHECK(ret2.ok()) << "write_close call failed";
|
CHECK(ret2.ok()) << "write_close call failed";
|
||||||
CHECK(!ret2.value()) << "Unexpected result from write_close call";
|
CHECK(!ret2.value()) << "Unexpected result from write_close call";
|
||||||
|
|
||||||
ret2 = api.archive_write_free(&ext_ptr);
|
ret2 = api.archive_write_free(&ext);
|
||||||
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) {
|
||||||
|
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,
|
||||||
|
@ -412,9 +708,9 @@ static int copy_data(sapi::v::RemotePtr *ar, sapi::v::RemotePtr *aw,
|
||||||
return ret.value();
|
return ret.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::v::RemotePtr buff_ptr(buff_ptr_tmp.GetValue());
|
sapi::v::RemotePtr buff(buff_ptr_tmp.GetValue());
|
||||||
|
|
||||||
ret = api.archive_write_data_block(aw, &buff_ptr, size.GetValue(),
|
ret = api.archive_write_data_block(aw, &buff, size.GetValue(),
|
||||||
offset.GetValue());
|
offset.GetValue());
|
||||||
|
|
||||||
CHECK(ret.ok()) << "write_data_block call failed";
|
CHECK(ret.ok()) << "write_data_block call failed";
|
||||||
|
|
|
@ -34,3 +34,4 @@ archive_write_header
|
||||||
archive_write_new
|
archive_write_new
|
||||||
archive_write_open_filename
|
archive_write_open_filename
|
||||||
archive_write_set_format_ustar
|
archive_write_set_format_ustar
|
||||||
|
archive_entry_set_pathname
|
||||||
|
|
Loading…
Reference in New Issue
Block a user