diff --git a/dpmdk/include/CommonModuleAPI.hpp b/dpmdk/include/CommonModuleAPI.hpp index e4a3cc5..a6ce942 100644 --- a/dpmdk/include/CommonModuleAPI.hpp +++ b/dpmdk/include/CommonModuleAPI.hpp @@ -31,6 +31,8 @@ #include #include +#include +#include /** * @brief Fatal log level constant @@ -161,6 +163,59 @@ extern "C" { * @return The module path */ const char* dpm_get_module_path(void); + + /** + * @brief Checks if a module exists + * + * Verifies if a module exists at the configured module path. + * + * @param module_name Name of the module to check + * @return true if the module exists, false otherwise + */ + bool dpm_module_exists(const char* module_name); + + /** + * @brief Loads a DPM module + * + * Attempts to load a module from the configured module path. + * + * @param module_name Name of the module to load + * @param module_handle Pointer to store the loaded module handle + * @return 0 on success, non-zero on failure + */ + int dpm_load_module(const char* module_name, void** module_handle); + + /** + * @brief Checks if a symbol exists in a module + * + * Verifies if a specific symbol exists in a loaded module. + * + * @param module_handle Handle to a loaded module + * @param symbol_name Name of the symbol to check + * @return true if the symbol exists, false otherwise + */ + bool dpm_symbol_exists(void* module_handle, const char* symbol_name); + + /** + * @brief Executes a symbol in a module + * + * Attempts to execute a function in a loaded module. + * + * @param module_handle Handle to a loaded module + * @param symbol_name Name of the symbol to execute + * @param args Arguments to pass to the function + * @return 0 on success, non-zero on failure + */ + int dpm_execute_symbol(void* module_handle, const char* symbol_name, void* args); + + /** + * @brief Unloads a module + * + * Frees resources used by a loaded module. + * + * @param module_handle Handle to a loaded module + */ + void dpm_unload_module(void* module_handle); } /** diff --git a/dpmdk/include/StandaloneModuleImpl.hpp b/dpmdk/include/StandaloneModuleImpl.hpp index 27daffe..fec7a10 100644 --- a/dpmdk/include/StandaloneModuleImpl.hpp +++ b/dpmdk/include/StandaloneModuleImpl.hpp @@ -33,6 +33,8 @@ #include #include #include +#include +#include // All implementations must be inline to prevent multiple definition errors when included in multiple files /** @@ -93,10 +95,102 @@ inline void dpm_set_logging_level(int level) { */ inline const char* dpm_get_module_path(void) { // Get from environment variable or use default - const char* env_path = getenv("DPM_MODULE_PATH"); + const char* env_path = dpm_get_config("modules", "modules_path"); return env_path ? env_path : "/usr/lib/dpm/modules/"; } +/** + * @brief Standalone implementation of dpm_module_exists + */ +inline bool dpm_module_exists(const char* module_name) { + if (!module_name) return false; + + // Get the module path + const char* module_path = dpm_get_module_path(); + if (!module_path) return false; + + // Build path to the module + std::string module_file = std::string(module_path) + "/" + module_name + ".so"; + + // Check if file exists + struct stat buffer; + return (stat(module_file.c_str(), &buffer) == 0); +} + +/** + * @brief Standalone implementation of dpm_load_module + */ +inline int dpm_load_module(const char* module_name, void** module_handle) { + if (!module_name || !module_handle) return 1; + + // Get the module path + const char* module_path = dpm_get_module_path(); + if (!module_path) return 1; + + // Build path to the module + std::string module_file = std::string(module_path) + "/" + module_name + ".so"; + + // Check if the file exists + if (!dpm_module_exists(module_name)) return 1; + + // Load the module + *module_handle = dlopen(module_file.c_str(), RTLD_LAZY); + if (!*module_handle) return 1; + + return 0; +} + +/** + * @brief Standalone implementation of dpm_symbol_exists + */ +inline bool dpm_symbol_exists(void* module_handle, const char* symbol_name) { + if (!module_handle || !symbol_name) return false; + + // Clear any error + dlerror(); + + // Look up the symbol + void* symbol = dlsym(module_handle, symbol_name); + + // Check for errors + const char* error = dlerror(); + if (error) return false; + + return (symbol != NULL); +} + +/** + * @brief Standalone implementation of dpm_execute_symbol + */ +inline int dpm_execute_symbol(void* module_handle, const char* symbol_name, void* args) { + if (!module_handle || !symbol_name) return 1; + + // Clear any error + dlerror(); + + // Look up the symbol + void* symbol = dlsym(module_handle, symbol_name); + + // Check for errors + const char* error = dlerror(); + if (error || !symbol) return 1; + + // Cast to function pointer and call + typedef int (*FunctionPtr)(void*); + FunctionPtr func = (FunctionPtr)symbol; + + return func(args); +} + +/** + * @brief Standalone implementation of dpm_unload_module + */ +inline void dpm_unload_module(void* module_handle) { + if (module_handle) { + dlclose(module_handle); + } +} + /** * @brief Standalone module main function * diff --git a/dpmdk/src/CommonModuleAPI.cpp b/dpmdk/src/CommonModuleAPI.cpp index f6b5418..c22724a 100644 --- a/dpmdk/src/CommonModuleAPI.cpp +++ b/dpmdk/src/CommonModuleAPI.cpp @@ -1,11 +1,9 @@ /** * @file CommonModuleAPI.cpp - * @brief Implementation stub for DPM module interface + * @brief Implementation for DPMDK functions * - * This file serves primarily as a documentation reference for the module - * interface. The actual implementations of dpm_get_config and dpm_log are - * provided by the DPM core, while dpm_module_execute, dpm_module_get_version, - * and dpm_get_description must be implemented by each module. + * Implements the module utility functions provided by the DPMDK library + * for module interoperability and loading. * * @copyright Copyright (c) 2025 SILO GROUP LLC * @author Chris Punches @@ -28,5 +26,86 @@ * For bug reports or contributions, please contact the dhlp-contributors * mailing list at: https://lists.darkhorselinux.org/mailman/listinfo/dhlp-contributors */ - #include "CommonModuleAPI.hpp" + +// Only define these functions when not in standalone mode +#ifndef BUILD_STANDALONE + +extern "C" bool dpm_module_exists(const char* module_name) { + if (!module_name) return false; + + // Get the module path + const char* module_path = dpm_get_module_path(); + if (!module_path) return false; + + // Build path to the module + std::string module_file = std::string(module_path) + "/" + module_name + ".so"; + + // Check if file exists + struct stat buffer; + return (stat(module_file.c_str(), &buffer) == 0); +} + +extern "C" int dpm_load_module(const char* module_name, void** module_handle) { + if (!module_name || !module_handle) return 1; + + // Get the module path + const char* module_path = dpm_get_module_path(); + if (!module_path) return 1; + + // Build path to the module + std::string module_file = std::string(module_path) + "/" + module_name + ".so"; + + // Check if the file exists + if (!dpm_module_exists(module_name)) return 1; + + // Load the module + *module_handle = dlopen(module_file.c_str(), RTLD_LAZY); + if (!*module_handle) return 1; + + return 0; +} + +extern "C" bool dpm_symbol_exists(void* module_handle, const char* symbol_name) { + if (!module_handle || !symbol_name) return false; + + // Clear any error + dlerror(); + + // Look up the symbol + void* symbol = dlsym(module_handle, symbol_name); + + // Check for errors + const char* error = dlerror(); + if (error) return false; + + return (symbol != NULL); +} + +extern "C" int dpm_execute_symbol(void* module_handle, const char* symbol_name, void* args) { + if (!module_handle || !symbol_name) return 1; + + // Clear any error + dlerror(); + + // Look up the symbol + void* symbol = dlsym(module_handle, symbol_name); + + // Check for errors + const char* error = dlerror(); + if (error || !symbol) return 1; + + // Cast to function pointer and call + typedef int (*FunctionPtr)(void*); + FunctionPtr func = (FunctionPtr)symbol; + + return func(args); +} + +extern "C" void dpm_unload_module(void* module_handle) { + if (module_handle) { + dlclose(module_handle); + } +} + +#endif // BUILD_STANDALONE \ No newline at end of file diff --git a/modules/verify/CMakeLists.txt b/modules/verify/CMakeLists.txt index 91a97c5..4ae13f9 100644 --- a/modules/verify/CMakeLists.txt +++ b/modules/verify/CMakeLists.txt @@ -10,10 +10,11 @@ else() set(DPM_ROOT_DIR "${CMAKE_SOURCE_DIR}") endif() -# Create shared library +# Create shared library - add CommonModuleAPI.cpp to the sources add_library(verify MODULE verify.cpp src/verify_commands.cpp + ${DPM_ROOT_DIR}/dpmdk/src/CommonModuleAPI.cpp # Add this line ) # Set output properties @@ -27,12 +28,17 @@ set_target_properties( target_include_directories(verify PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${DPM_ROOT_DIR} + ${DPM_ROOT_DIR}/dpmdk/include # Add this line ) +# Link with required libraries +target_link_libraries(verify dl) + # Standalone version - used for debugging add_executable(verify_standalone verify.cpp src/verify_commands.cpp + ${DPM_ROOT_DIR}/dpmdk/src/CommonModuleAPI.cpp # Add this line ) # Define the BUILD_STANDALONE macro for the standalone build @@ -42,8 +48,12 @@ target_compile_definitions(verify_standalone PRIVATE BUILD_STANDALONE) target_include_directories(verify_standalone PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${DPM_ROOT_DIR} + ${DPM_ROOT_DIR}/dpmdk/include # Add this line ) +# Link with required libraries for standalone too +target_link_libraries(verify_standalone dl) + # Set the output name for the standalone executable set_target_properties( verify_standalone PROPERTIES diff --git a/modules/verify/include/verify_commands.hpp b/modules/verify/include/verify_commands.hpp index 935c81f..56129b8 100644 --- a/modules/verify/include/verify_commands.hpp +++ b/modules/verify/include/verify_commands.hpp @@ -42,6 +42,17 @@ enum Command { */ int cmd_checksum(int argc, char** argv); +/** + * @brief Handler for the checksum help command + * + * Displays help information for the checksum command. + * + * @param argc Number of arguments + * @param argv Array of arguments + * @return 0 on success + */ +int cmd_checksum_help(int argc, char** argv); + /** * @brief Handler for the signature command * @@ -53,6 +64,17 @@ int cmd_checksum(int argc, char** argv); */ int cmd_signature(int argc, char** argv); +/** + * @brief Handler for the signature help command + * + * Displays help information for the signature command. + * + * @param argc Number of arguments + * @param argv Array of arguments + * @return 0 on success + */ +int cmd_signature_help(int argc, char** argv); + /** * @brief Handler for the help command * @@ -64,6 +86,29 @@ int cmd_signature(int argc, char** argv); */ int cmd_help(int argc, char** argv); +/** + * @brief Handler for the check command + * + * Checks if the build module can be loaded. This validates that the integration + * between the verify module and build module is working correctly. + * + * @param argc Number of arguments + * @param argv Array of arguments + * @return 0 on success, non-zero on failure + */ +int cmd_check(int argc, char** argv); + +/** + * @brief Handler for the check help command + * + * Displays help information for the check command. + * + * @param argc Number of arguments + * @param argv Array of arguments + * @return 0 on success + */ +int cmd_check_help(int argc, char** argv); + /** * @brief Handler for unknown commands * @@ -88,13 +133,11 @@ int cmd_unknown(const char* command, int argc, char** argv); Command parse_command(const char* cmd_str); /** - * @brief Handler for the check command + * @brief Helper function to check and load the build module * - * Checks if the build module can be loaded. This validates that the integration - * between the verify module and build module is working correctly. + * Checks if the build module exists and can be loaded. * - * @param argc Number of arguments - * @param argv Array of arguments + * @param module_handle Reference to a void pointer that will hold the module handle * @return 0 on success, non-zero on failure */ -int cmd_check(int argc, char** argv); \ No newline at end of file +int check_and_load_build_module(void*& module_handle); \ No newline at end of file diff --git a/modules/verify/src/verify_commands.cpp b/modules/verify/src/verify_commands.cpp index d380f0b..ebefb0f 100644 --- a/modules/verify/src/verify_commands.cpp +++ b/modules/verify/src/verify_commands.cpp @@ -13,35 +13,36 @@ #include "verify_commands.hpp" int check_and_load_build_module(void*& module_handle) { - // Get the module path using the new direct accessor - const char* module_path = dpm_get_module_path(); - if (!module_path || strlen(module_path) == 0) { - dpm_log(LOG_ERROR, "Module path not available"); + // Check if build module exists + if (!dpm_module_exists("build")) { + dpm_log(LOG_ERROR, "Build module not found"); return 1; } - // Create a proper path object - std::filesystem::path modules_dir(module_path); - - // Build path to the build module - std::filesystem::path build_module_path = modules_dir / "build.so"; - - // Check if the file exists - if (!std::filesystem::exists(build_module_path)) { - dpm_log(LOG_ERROR, ("Build module not found at: " + build_module_path.string()).c_str()); - return 1; + // Load the build module + int result = dpm_load_module("build", &module_handle); + if (result != 0) { + dpm_log(LOG_ERROR, "Failed to load build module"); + return result; } - // Load the module - module_handle = dlopen(build_module_path.c_str(), RTLD_LAZY); - if (!module_handle) { - dpm_log(LOG_ERROR, ("Failed to load build module: " + std::string(dlerror())).c_str()); - return 1; - } - - // Clear any error - dlerror(); + return 0; +} +int cmd_checksum_help(int argc, char** argv) { + dpm_con(LOG_INFO, "Usage: dpm verify checksum [options]"); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Verifies the checksums of uninstalled packages."); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Options:"); + dpm_con(LOG_INFO, " -a, --all Verify all uninstalled packages"); + dpm_con(LOG_INFO, " -p, --package NAME Verify a specific package"); + dpm_con(LOG_INFO, " -v, --verbose Enable verbose output"); + dpm_con(LOG_INFO, " -h, --help Display this help message"); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Examples:"); + dpm_con(LOG_INFO, " dpm verify checksum --all"); + dpm_con(LOG_INFO, " dpm verify checksum --package=mypackage"); return 0; } @@ -72,20 +73,7 @@ int cmd_checksum(int argc, char** argv) { // If help was requested, show it and return if (show_help) { - dpm_con(LOG_INFO, "Usage: dpm verify checksum [options]"); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Verifies the checksums of installed packages."); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Options:"); - dpm_con(LOG_INFO, " -a, --all Verify all installed packages"); - dpm_con(LOG_INFO, " -p, --package NAME Verify a specific package"); - dpm_con(LOG_INFO, " -v, --verbose Enable verbose output"); - dpm_con(LOG_INFO, " -h, --help Display this help message"); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Examples:"); - dpm_con(LOG_INFO, " dpm verify checksum --all"); - dpm_con(LOG_INFO, " dpm verify checksum --package=mypackage"); - return 0; + return cmd_checksum_help(argc, argv); } // Set verbose logging if requested @@ -117,6 +105,23 @@ int cmd_checksum(int argc, char** argv) { return 0; } +int cmd_signature_help(int argc, char** argv) { + dpm_con(LOG_INFO, "Usage: dpm verify signature [options]"); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Verifies the signatures of installed packages."); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Options:"); + dpm_con(LOG_INFO, " -a, --all Verify all installed packages"); + dpm_con(LOG_INFO, " -p, --package NAME Verify a specific package"); + dpm_con(LOG_INFO, " -v, --verbose Enable verbose output"); + dpm_con(LOG_INFO, " -h, --help Display this help message"); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Examples:"); + dpm_con(LOG_INFO, " dpm verify signature --all"); + dpm_con(LOG_INFO, " dpm verify signature --package=mypackage"); + return 0; +} + int cmd_signature(int argc, char** argv) { // Parse command line arguments bool all_packages = false; @@ -144,20 +149,7 @@ int cmd_signature(int argc, char** argv) { // If help was requested, show it and return if (show_help) { - dpm_con(LOG_INFO, "Usage: dpm verify signature [options]"); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Verifies the signatures of installed packages."); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Options:"); - dpm_con(LOG_INFO, " -a, --all Verify all installed packages"); - dpm_con(LOG_INFO, " -p, --package NAME Verify a specific package"); - dpm_con(LOG_INFO, " -v, --verbose Enable verbose output"); - dpm_con(LOG_INFO, " -h, --help Display this help message"); - dpm_con(LOG_INFO, ""); - dpm_con(LOG_INFO, "Examples:"); - dpm_con(LOG_INFO, " dpm verify signature --all"); - dpm_con(LOG_INFO, " dpm verify signature --package=mypackage"); - return 0; + return cmd_signature_help(argc, argv); } // Set verbose logging if requested @@ -189,6 +181,17 @@ int cmd_signature(int argc, char** argv) { return 0; } +int cmd_check_help(int argc, char** argv) { + dpm_con(LOG_INFO, "Usage: dpm verify check [options]"); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Checks build module integration."); + dpm_con(LOG_INFO, ""); + dpm_con(LOG_INFO, "Options:"); + dpm_con(LOG_INFO, " -v, --verbose Enable verbose output"); + dpm_con(LOG_INFO, " -h, --help Display this help message"); + return 0; +} + int cmd_help(int argc, char** argv) { dpm_con(LOG_INFO, "DPM Verify Module - Verifies the integrity and signatures of installed packages."); dpm_con(LOG_INFO, ""); @@ -236,6 +239,31 @@ Command parse_command(const char* cmd_str) { } int cmd_check(int argc, char** argv) { + // Parse command line arguments + bool verbose = false; + bool show_help = false; + + // Process command-line arguments + for (int i = 1; i < argc; i++) { + std::string arg = argv[i]; + + if (arg == "-v" || arg == "--verbose") { + verbose = true; + } else if (arg == "-h" || arg == "--help" || arg == "help") { + show_help = true; + } + } + + // If help was requested, show it and return + if (show_help) { + return cmd_check_help(argc, argv); + } + + // Set verbose logging if requested + if (verbose) { + dpm_set_logging_level(LOG_DEBUG); + } + dpm_log(LOG_INFO, "Checking build module integration..."); void* module_handle = nullptr; @@ -248,9 +276,18 @@ int cmd_check(int argc, char** argv) { dpm_log(LOG_INFO, "Successfully loaded build module."); + // Check if the dpm_module_execute symbol exists + if (!dpm_symbol_exists(module_handle, "dpm_module_execute")) { + dpm_log(LOG_ERROR, "Symbol 'dpm_module_execute' not found in build module."); + dpm_unload_module(module_handle); + return 1; + } + + dpm_log(LOG_INFO, "Symbol 'dpm_module_execute' found in build module."); + // Clean up if (module_handle) { - dlclose(module_handle); + dpm_unload_module(module_handle); } return 0;