|
|
|
@ -85,8 +85,7 @@ namespace SignedPackage {
|
|
|
|
|
|
|
|
|
|
void extract_archive(
|
|
|
|
|
std::string pkg_path,
|
|
|
|
|
std::string target_path,
|
|
|
|
|
std::vector< std::string > filenames
|
|
|
|
|
std::string target_path
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
std::string cwd = std::filesystem::current_path();
|
|
|
|
@ -105,42 +104,27 @@ namespace SignedPackage {
|
|
|
|
|
std::filesystem::current_path(target_path);
|
|
|
|
|
|
|
|
|
|
struct ::archive_entry *entry;
|
|
|
|
|
int n = 0;
|
|
|
|
|
while (::archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
|
|
|
|
std::string pathname{::archive_entry_pathname(entry)};
|
|
|
|
|
|
|
|
|
|
if (!filenames.size() || std::find(filenames.begin(),
|
|
|
|
|
filenames.end(), pathname) != filenames.end()) {
|
|
|
|
|
do {
|
|
|
|
|
r = archive_read_extract(a, entry,
|
|
|
|
|
ARCHIVE_EXTRACT_ACL |
|
|
|
|
|
ARCHIVE_EXTRACT_FFLAGS |
|
|
|
|
|
ARCHIVE_EXTRACT_MAC_METADATA |
|
|
|
|
|
ARCHIVE_EXTRACT_NO_OVERWRITE |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_NODOTDOT |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_SYMLINKS |
|
|
|
|
|
ARCHIVE_EXTRACT_TIME |
|
|
|
|
|
ARCHIVE_EXTRACT_XATTR
|
|
|
|
|
);
|
|
|
|
|
} while (r == ARCHIVE_RETRY);
|
|
|
|
|
if (r != ARCHIVE_OK && r != ARCHIVE_WARN) {
|
|
|
|
|
std::filesystem::current_path(cwd);
|
|
|
|
|
throw_archive_read_error(a);
|
|
|
|
|
}
|
|
|
|
|
++n;
|
|
|
|
|
do {
|
|
|
|
|
r = archive_read_extract(a, entry,
|
|
|
|
|
ARCHIVE_EXTRACT_ACL |
|
|
|
|
|
ARCHIVE_EXTRACT_FFLAGS |
|
|
|
|
|
ARCHIVE_EXTRACT_MAC_METADATA |
|
|
|
|
|
ARCHIVE_EXTRACT_NO_OVERWRITE |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_NODOTDOT |
|
|
|
|
|
ARCHIVE_EXTRACT_SECURE_SYMLINKS |
|
|
|
|
|
ARCHIVE_EXTRACT_TIME |
|
|
|
|
|
ARCHIVE_EXTRACT_XATTR
|
|
|
|
|
);
|
|
|
|
|
} while (r == ARCHIVE_RETRY);
|
|
|
|
|
if (r != ARCHIVE_OK && r != ARCHIVE_WARN) {
|
|
|
|
|
std::filesystem::current_path(cwd);
|
|
|
|
|
throw_archive_read_error(a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (filenames.size() && n < filenames.size()) {
|
|
|
|
|
::archive_read_free(a);
|
|
|
|
|
std::filesystem::current_path(cwd);
|
|
|
|
|
throw std::range_error("illegal archive: missing file");
|
|
|
|
|
}
|
|
|
|
|
else if (filenames.size() && n > filenames.size()) {
|
|
|
|
|
::archive_read_free(a);
|
|
|
|
|
std::filesystem::current_path(cwd);
|
|
|
|
|
throw std::range_error("corrupt archive: double file");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::archive_read_free(a);
|
|
|
|
|
std::filesystem::current_path(cwd);
|
|
|
|
@ -197,7 +181,7 @@ namespace SignedPackage {
|
|
|
|
|
{
|
|
|
|
|
std::filesystem::path target_path = mktempdir();
|
|
|
|
|
|
|
|
|
|
extract_archive(pkg_path, target_path, { "DIST.A", "DIST.KEY" });
|
|
|
|
|
extract_archive(pkg_path, target_path);
|
|
|
|
|
decrypt_distribution_archive(target_path / "DIST.A",
|
|
|
|
|
target_path / "DIST.KEY", provisioning_key);
|
|
|
|
|
|
|
|
|
@ -208,6 +192,7 @@ namespace SignedPackage {
|
|
|
|
|
CryptoPP::PublicKey& deployment_key,
|
|
|
|
|
CryptoPP::PrivateKey& provisioning_key,
|
|
|
|
|
std::filesystem::path pkg_path,
|
|
|
|
|
std::string location,
|
|
|
|
|
std::filesystem::path target_path
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
@ -218,10 +203,14 @@ namespace SignedPackage {
|
|
|
|
|
std::filesystem::path decrypted_archive =
|
|
|
|
|
decrypt_distribution_archive(tmp_path / "DIST.A",
|
|
|
|
|
tmp_path / "DIST.KEY", provisioning_key);
|
|
|
|
|
std::filesystem::remove(tmp_path / "DIST.A");
|
|
|
|
|
|
|
|
|
|
extract_archive(decrypted_archive, tmp_path);
|
|
|
|
|
|
|
|
|
|
ensure_target_path(target_path);
|
|
|
|
|
extract_archive(decrypted_archive, target_path);
|
|
|
|
|
for (auto const& direntry : std::filesystem::directory_iterator{tmp_path / location}) {
|
|
|
|
|
std::filesystem::path source = direntry.path();
|
|
|
|
|
std::filesystem::rename(direntry.path(), target_path / source.filename());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::filesystem::remove_all(tmp_path);
|
|
|
|
|
}
|
|
|
|
@ -243,7 +232,7 @@ namespace SignedPackage {
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
std::string pkg_path = pEp::UpdateClient::update(p, update_key, notifyRead);
|
|
|
|
|
install_if_location_empty(deployment_key, provisioning_key, pkg_path, target_path);
|
|
|
|
|
install_if_location_empty(deployment_key, provisioning_key, pkg_path, "PER_USER_DIRECTORY", target_path);
|
|
|
|
|
std::filesystem::remove(pkg_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|