adding missing files from previous, and various fixes for PGP signing; path mgmt is a little clunky
parent
78891a1881
commit
8b7e594d33
|
@ -57,12 +57,12 @@ int seal_final_package(const std::string &stage_dir, const std::string &output_d
|
||||||
* Extracts a sealed package file back to its original stage directory structure
|
* Extracts a sealed package file back to its original stage directory structure
|
||||||
* by expanding the gzipped tarballs.
|
* by expanding the gzipped tarballs.
|
||||||
*
|
*
|
||||||
* @param package_path Path to the sealed package file
|
* @param package_filepath Path to the sealed package file
|
||||||
* @param output_dir Path to extract the package stage to
|
* @param output_dir Path to extract the package stage to
|
||||||
* @param force Whether to force the operation even if warnings occur
|
* @param force Whether to force the operation even if warnings occur
|
||||||
* @return 0 on success, non-zero on failure
|
* @return 0 on success, non-zero on failure
|
||||||
*/
|
*/
|
||||||
int unseal_package(const std::string& package_path, const std::string& output_dir, bool force);
|
int unseal_package(const std::string& package_filepath, const std::string& output_dir, bool force);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
#include <dpmdk/include/CommonModuleAPI.hpp>
|
#include <dpmdk/include/CommonModuleAPI.hpp>
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
#include "sealing.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Signs a package stage directory
|
* @brief Signs a package stage directory
|
||||||
|
|
|
@ -500,11 +500,13 @@ int seal_final_package(const std::string &stage_dir, const std::string &output_d
|
||||||
// the user supplied an output directory so call it stage_name.dpm and prefix the path
|
// the user supplied an output directory so call it stage_name.dpm and prefix the path
|
||||||
// with the output dir
|
// with the output dir
|
||||||
std::string stage_basename = stage_path.filename().string();
|
std::string stage_basename = stage_path.filename().string();
|
||||||
output_path = output_dir + stage_basename + ".dpm";
|
|
||||||
|
// it's here
|
||||||
|
output_path = std::filesystem::path(output_dir) / std::filesystem::path(stage_basename + ".dpm");
|
||||||
}
|
}
|
||||||
|
|
||||||
dpm_log( LOG_INFO, "Sealing DPM Package." );
|
dpm_log( LOG_INFO, "Sealing DPM Package." );
|
||||||
bool result = compress_directory( stage_path, output_path.string() );
|
bool result = compress_directory( stage_path.string(), output_path.string() );
|
||||||
if ( ! result ) {
|
if ( ! result ) {
|
||||||
dpm_log( LOG_FATAL, "Could not create DPM package from stage." );
|
dpm_log( LOG_FATAL, "Could not create DPM package from stage." );
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -513,46 +515,52 @@ int seal_final_package(const std::string &stage_dir, const std::string &output_d
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unseal_package(const std::string& package_path, const std::string& output_dir_arg, bool force)
|
int unseal_package(const std::string& package_filepath, const std::string& output_dir, bool force)
|
||||||
{
|
{
|
||||||
dpm_log(LOG_INFO, ("Unsealing package: " + package_path).c_str());
|
dpm_log(LOG_INFO, ("Unsealing package: " + package_filepath).c_str());
|
||||||
|
|
||||||
// Determine the output directory path
|
// Extract filename from package path
|
||||||
std::filesystem::path output_path;
|
std::filesystem::path supplied_package_path(package_filepath);
|
||||||
|
std::string package_filename = supplied_package_path.filename().string();
|
||||||
|
|
||||||
if (output_dir_arg.empty()) {
|
// Verify it has .dpm extension
|
||||||
// Extract filename from package path
|
const std::string dpm_extension = ".dpm";
|
||||||
std::filesystem::path package_fs_path(package_path);
|
if (!package_filename.ends_with(dpm_extension)) {
|
||||||
std::string package_name = package_fs_path.filename().string();
|
dpm_log(LOG_FATAL, "Refusing to unseal package: file must have .dpm extension");
|
||||||
|
return 1;
|
||||||
// Verify it has .dpm extension
|
|
||||||
const std::string dpm_extension = ".dpm";
|
|
||||||
if (!package_name.ends_with(dpm_extension)) {
|
|
||||||
dpm_log(LOG_FATAL, "Refusing to unseal package: file must have .dpm extension");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove .dpm extension
|
|
||||||
std::string stage_name = package_name.substr(0, package_name.length() - dpm_extension.length());
|
|
||||||
|
|
||||||
// Set output path to parent_directory/filename_without_extension
|
|
||||||
output_path = package_fs_path.parent_path() / stage_name;
|
|
||||||
} else {
|
|
||||||
// Use the provided output directory
|
|
||||||
output_path = std::filesystem::path(output_dir_arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if output directory already exists
|
// Remove .dpm extension to establish the tatget stage directory to extract to
|
||||||
if (std::filesystem::exists(output_path)) {
|
std::string target_stage_name = package_filename.substr(0, package_filename.length() - dpm_extension.length());
|
||||||
|
|
||||||
|
// Determine the output directory path based on whether output_dir was supplied or not
|
||||||
|
std::filesystem::path output_directory;
|
||||||
|
|
||||||
|
if (output_dir.empty()) {
|
||||||
|
// output_dir was not supplied, so set it to the supplied package path's parent dir + target_stage_name
|
||||||
|
|
||||||
|
// Set output path to parent_directory/filename_without_extension
|
||||||
|
output_directory = supplied_package_path.parent_path() / target_stage_name;
|
||||||
|
} else {
|
||||||
|
// output_dir was supplied, so use that
|
||||||
|
|
||||||
|
// Use the provided output directory
|
||||||
|
output_directory = std::filesystem::path(output_dir) / target_stage_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target path already exists
|
||||||
|
if (std::filesystem::exists(output_directory)) {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
dpm_log(LOG_ERROR, ("Output directory already exists: " + output_path.string() +
|
// a stage dir already exists with this name at that path so it can't be used unless --force is used
|
||||||
|
// to overwrite it
|
||||||
|
dpm_log(LOG_ERROR, ("Output directory already exists: " + output_directory.string() +
|
||||||
". Use --force to overwrite.").c_str());
|
". Use --force to overwrite.").c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If force flag is set, remove the existing directory
|
// If force flag is set, remove the existing directory
|
||||||
try {
|
try {
|
||||||
std::filesystem::remove_all(output_path);
|
std::filesystem::remove_all(output_directory);
|
||||||
} catch (const std::filesystem::filesystem_error& e) {
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
dpm_log(LOG_ERROR, ("Failed to remove existing directory: " + std::string(e.what())).c_str());
|
dpm_log(LOG_ERROR, ("Failed to remove existing directory: " + std::string(e.what())).c_str());
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -561,20 +569,20 @@ int unseal_package(const std::string& package_path, const std::string& output_di
|
||||||
|
|
||||||
// Create the output directory
|
// Create the output directory
|
||||||
try {
|
try {
|
||||||
std::filesystem::create_directories(output_path);
|
std::filesystem::create_directories(output_directory);
|
||||||
} catch (const std::filesystem::filesystem_error& e) {
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
dpm_log(LOG_ERROR, ("Failed to create output directory: " + std::string(e.what())).c_str());
|
dpm_log(LOG_ERROR, ("Failed to create output directory: " + std::string(e.what())).c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the package to the output directory
|
// Extract the package to the output directory
|
||||||
bool result = uncompress_archive(package_path, output_path.string());
|
bool result = uncompress_archive(package_filepath, output_directory.string());
|
||||||
if (!result) {
|
if (!result) {
|
||||||
dpm_log(LOG_ERROR, "Failed to extract package");
|
dpm_log(LOG_ERROR, "Failed to extract package");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dpm_log(LOG_INFO, ("Package unsealed successfully to: " + output_path.string()).c_str());
|
dpm_log(LOG_INFO, ("Package unsealed successfully to: " + output_directory.string()).c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// File: signing.cpp
|
|
||||||
|
|
||||||
#include "signing.hpp"
|
#include "signing.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,8 +192,65 @@ int sign_stage_directory(const std::string& stage_dir, const std::string& key_id
|
||||||
}
|
}
|
||||||
|
|
||||||
int sign_package_file(const std::string& package_path, const std::string& key_id, bool force) {
|
int sign_package_file(const std::string& package_path, const std::string& key_id, bool force) {
|
||||||
// This is a placeholder implementation
|
|
||||||
dpm_log(LOG_INFO, ("Signing package file: " + package_path).c_str());
|
dpm_log(LOG_INFO, ("Signing package file: " + package_path).c_str());
|
||||||
dpm_log(LOG_ERROR, "Package file signing not yet implemented");
|
|
||||||
return 1;
|
// Get the temporary stage path by removing .dpm extension
|
||||||
|
std::string tmp_stage_path = package_path;
|
||||||
|
if (tmp_stage_path.ends_with(".dpm")) {
|
||||||
|
tmp_stage_path = tmp_stage_path.substr(0, tmp_stage_path.length() - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if temporary stage path already exists - fail if it does
|
||||||
|
if (std::filesystem::exists(tmp_stage_path)) {
|
||||||
|
dpm_log(LOG_ERROR, ("Temporary stage directory already exists: " + tmp_stage_path).c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Unseal the package to the stage parent path
|
||||||
|
std::filesystem::path stage_parent_path = std::filesystem::path(tmp_stage_path).parent_path();
|
||||||
|
dpm_log(LOG_INFO, "Unsealing package file...");
|
||||||
|
int result = unseal_package(package_path, stage_parent_path, force);
|
||||||
|
if (result != 0) {
|
||||||
|
dpm_log(LOG_ERROR, "Failed to unseal package file");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Sign the stage directory components
|
||||||
|
dpm_log(LOG_INFO, "Signing package components...");
|
||||||
|
result = sign_stage_directory(tmp_stage_path, key_id, force);
|
||||||
|
if (result != 0) {
|
||||||
|
dpm_log(LOG_ERROR, "Failed to sign package components");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string backup_path = package_path + ".old";
|
||||||
|
|
||||||
|
// Back up the original package
|
||||||
|
try {
|
||||||
|
std::filesystem::rename(package_path, backup_path);
|
||||||
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
|
dpm_log(LOG_ERROR, ("Failed to backup original package: " + std::string(e.what())).c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create a new sealed package at the original location
|
||||||
|
dpm_log(LOG_INFO, "Creating signed package file...");
|
||||||
|
|
||||||
|
// seal the package path
|
||||||
|
result = seal_final_package(tmp_stage_path, stage_parent_path.string(), force);
|
||||||
|
if (result != 0) {
|
||||||
|
dpm_log(LOG_ERROR, "Failed to create signed package");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Clean up
|
||||||
|
try {
|
||||||
|
std::filesystem::remove_all(tmp_stage_path);
|
||||||
|
std::filesystem::remove(backup_path);
|
||||||
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
|
dpm_log(LOG_WARN, ("Failed to clean up temporary files: " + std::string(e.what())).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
dpm_log(LOG_INFO, ("Successfully signed package: " + package_path).c_str());
|
||||||
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue