aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt75
-rw-r--r--src/core/GpgConstants.cpp180
-rw-r--r--src/core/GpgConstants.h207
-rw-r--r--src/core/GpgContext.cpp660
-rw-r--r--src/core/GpgContext.h210
-rw-r--r--src/core/GpgCoreInit.cpp575
-rw-r--r--src/core/GpgCoreInit.h42
-rw-r--r--src/core/GpgFrontendCore.cpp (renamed from src/core/GpgInfo.cpp)6
-rw-r--r--src/core/GpgFrontendCore.h57
-rw-r--r--src/core/GpgFunctionObject.cpp137
-rw-r--r--src/core/GpgFunctionObject.h311
-rw-r--r--src/core/GpgGenKeyInfo.cpp284
-rw-r--r--src/core/GpgInfo.h65
-rw-r--r--src/core/GpgModel.h34
-rw-r--r--src/core/common/CoreCommonUtil.cpp58
-rw-r--r--src/core/common/CoreCommonUtil.h87
-rw-r--r--src/core/function/ArchiveFileOperator.cpp411
-rw-r--r--src/core/function/ArchiveFileOperator.h54
-rw-r--r--src/core/function/CacheManager.cpp311
-rw-r--r--src/core/function/CacheManager.h157
-rw-r--r--src/core/function/CharsetOperator.cpp133
-rw-r--r--src/core/function/CoreSignalStation.cpp15
-rw-r--r--src/core/function/CoreSignalStation.h31
-rw-r--r--src/core/function/DataObjectOperator.cpp178
-rw-r--r--src/core/function/DataObjectOperator.h40
-rw-r--r--src/core/function/FileOperator.cpp124
-rw-r--r--src/core/function/FileOperator.h92
-rw-r--r--src/core/function/GlobalSettingStation.cpp230
-rw-r--r--src/core/function/GlobalSettingStation.h181
-rw-r--r--src/core/function/KeyPackageOperator.cpp186
-rw-r--r--src/core/function/KeyPackageOperator.h44
-rw-r--r--src/core/function/LoggerManager.cpp155
-rw-r--r--src/core/function/LoggerManager.h65
-rw-r--r--src/core/function/PassphraseGenerator.cpp24
-rw-r--r--src/core/function/PassphraseGenerator.h32
-rw-r--r--src/core/function/SecureMemoryAllocator.cpp63
-rw-r--r--src/core/function/SecureMemoryAllocator.h60
-rw-r--r--src/core/function/basic/ChannelObject.cpp59
-rw-r--r--src/core/function/basic/ChannelObject.h98
-rw-r--r--src/core/function/basic/GpgFunctionObject.cpp105
-rw-r--r--src/core/function/basic/GpgFunctionObject.h194
-rw-r--r--src/core/function/basic/SingletonStorage.cpp133
-rw-r--r--src/core/function/basic/SingletonStorage.h90
-rw-r--r--src/core/function/basic/SingletonStorageCollection.cpp124
-rw-r--r--src/core/function/basic/SingletonStorageCollection.h79
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp311
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h47
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp458
-rw-r--r--src/core/function/gpg/GpgBasicOperator.h140
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp369
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h61
-rw-r--r--src/core/function/gpg/GpgContext.cpp339
-rw-r--r--src/core/function/gpg/GpgContext.h76
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp762
-rw-r--r--src/core/function/gpg/GpgFileOpera.h249
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp286
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h74
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp269
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h135
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp240
-rw-r--r--src/core/function/gpg/GpgKeyManager.h60
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp604
-rw-r--r--src/core/function/gpg/GpgKeyOpera.h79
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp62
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h23
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp115
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.h22
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp64
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.h20
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.cpp14
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.h33
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.cpp132
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.h13
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp244
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.h22
-rw-r--r--src/core/log/QtLoggerFmt.h64
-rw-r--r--src/core/model/CommonStruct.h (renamed from src/core/thread/CtxCheckTask.h)47
-rw-r--r--src/core/model/DataObject.cpp83
-rw-r--r--src/core/model/DataObject.h104
-rw-r--r--src/core/model/GFBuffer.cpp59
-rw-r--r--src/core/model/GFBuffer.h64
-rw-r--r--src/core/model/GFDataExchanger.cpp89
-rw-r--r--src/core/model/GFDataExchanger.h53
-rw-r--r--src/core/model/GpgData.cpp120
-rw-r--r--src/core/model/GpgData.h67
-rw-r--r--src/core/model/GpgDecryptResult.cpp65
-rw-r--r--src/core/model/GpgDecryptResult.h54
-rw-r--r--src/core/model/GpgEncryptResult.cpp66
-rw-r--r--src/core/model/GpgEncryptResult.h53
-rw-r--r--src/core/model/GpgGenKeyInfo.cpp485
-rw-r--r--src/core/model/GpgGenKeyInfo.h (renamed from src/core/GpgGenKeyInfo.h)214
-rw-r--r--src/core/model/GpgGenerateKeyResult.cpp59
-rw-r--r--src/core/model/GpgGenerateKeyResult.h59
-rw-r--r--src/core/model/GpgImportInformation.cpp54
-rw-r--r--src/core/model/GpgImportInformation.h80
-rw-r--r--src/core/model/GpgKey.cpp196
-rw-r--r--src/core/model/GpgKey.h145
-rw-r--r--src/core/model/GpgKeySignature.cpp66
-rw-r--r--src/core/model/GpgKeySignature.h60
-rw-r--r--src/core/model/GpgPassphraseContext.cpp60
-rw-r--r--src/core/model/GpgPassphraseContext.h63
-rw-r--r--src/core/model/GpgRecipient.cpp40
-rw-r--r--src/core/model/GpgRecipient.h51
-rw-r--r--src/core/model/GpgSignResult.cpp65
-rw-r--r--src/core/model/GpgSignResult.h53
-rw-r--r--src/core/model/GpgSignature.cpp55
-rw-r--r--src/core/model/GpgSignature.h44
-rw-r--r--src/core/model/GpgSubKey.cpp88
-rw-r--r--src/core/model/GpgSubKey.h71
-rw-r--r--src/core/model/GpgTOFUInfo.cpp59
-rw-r--r--src/core/model/GpgTOFUInfo.h35
-rw-r--r--src/core/model/GpgUID.cpp39
-rw-r--r--src/core/model/GpgUID.h40
-rw-r--r--src/core/model/GpgVerifyResult.cpp62
-rw-r--r--src/core/model/GpgVerifyResult.h53
-rw-r--r--src/core/module/Event.cpp139
-rw-r--r--src/core/module/Event.h95
-rw-r--r--src/core/module/GlobalModuleContext.cpp377
-rw-r--r--src/core/module/GlobalModuleContext.h88
-rw-r--r--src/core/module/GlobalRegisterTable.cpp167
-rw-r--r--src/core/module/GlobalRegisterTable.h66
-rw-r--r--src/core/module/GpgFrontendModuleSystem.h34
-rw-r--r--src/core/module/Module.cpp106
-rw-r--r--src/core/module/Module.h80
-rw-r--r--src/core/module/ModuleManager.cpp184
-rw-r--r--src/core/module/ModuleManager.h179
-rw-r--r--src/core/thread/CtxCheckTask.cpp54
-rw-r--r--src/core/thread/FileReadTask.cpp60
-rw-r--r--src/core/thread/FileReadTask.h22
-rw-r--r--src/core/thread/Task.cpp370
-rw-r--r--src/core/thread/Task.h223
-rw-r--r--src/core/thread/TaskRunner.cpp212
-rw-r--r--src/core/thread/TaskRunner.h83
-rw-r--r--src/core/thread/TaskRunnerGetter.cpp44
-rw-r--r--src/core/thread/TaskRunnerGetter.h32
-rw-r--r--src/core/thread/ThreadingModel.h9
-rw-r--r--src/core/typedef/CoreTypedef.h49
-rw-r--r--src/core/typedef/GpgTypedef.h76
-rw-r--r--src/core/utils/AsyncUtils.cpp154
-rw-r--r--src/core/utils/AsyncUtils.h88
-rw-r--r--src/core/utils/CacheUtils.cpp47
-rw-r--r--src/core/utils/CacheUtils.h54
-rw-r--r--src/core/utils/CommonUtils.cpp74
-rw-r--r--src/core/utils/CommonUtils.h54
-rw-r--r--src/core/utils/FilesystemUtils.cpp104
-rw-r--r--src/core/utils/FilesystemUtils.h78
-rw-r--r--src/core/utils/GpgUtils.cpp167
-rw-r--r--src/core/utils/GpgUtils.h108
-rw-r--r--src/core/utils/IOUtils.cpp178
-rw-r--r--src/core/utils/IOUtils.h139
-rw-r--r--src/core/utils/LocalizedUtils.cpp (renamed from src/core/function/CharsetOperator.h)23
-rw-r--r--src/core/utils/LocalizedUtils.h35
-rw-r--r--src/core/utils/LogUtils.cpp59
-rw-r--r--src/core/utils/LogUtils.h112
-rw-r--r--src/core/utils/MemoryUtils.cpp42
-rw-r--r--src/core/utils/MemoryUtils.h179
-rw-r--r--src/core/utils/aes/aes_ssl.h (renamed from src/core/function/aes/aes_ssl.h)9
-rw-r--r--src/core/utils/aes/aes_ssl_cbc.cpp (renamed from src/core/function/aes/aes_ssl_cbc.cpp)0
158 files changed, 12485 insertions, 7031 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 22a0b88a..ed12ad01 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2021 Saturneric
+# Copyright (C) 2021 Saturneric <[email protected]>
#
# This file is part of GpgFrontend.
#
@@ -20,31 +19,41 @@
# the gpg4usb project, which is under GPL-3.0-or-later.
#
# All the source code of GpgFrontend was modified and released by
-# Saturneric<[email protected]> starting on May 12, 2021.
+# Saturneric <[email protected]> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
-aux_source_directory(./function/result_analyse GPG_SOURCE)
-aux_source_directory(./function/gpg GPG_SOURCE)
-aux_source_directory(./function/aes GPG_SOURCE)
-aux_source_directory(./function GPG_SOURCE)
-aux_source_directory(./thread GPG_SOURCE)
-aux_source_directory(./model GPG_SOURCE)
-aux_source_directory(./common GPG_SOURCE)
-aux_source_directory(. GPG_SOURCE)
+
+aux_source_directory(./function/result_analyse CORE_SOURCE)
+aux_source_directory(./function/basic CORE_SOURCE)
+aux_source_directory(./function/gpg CORE_SOURCE)
+aux_source_directory(./function/secure_memory CORE_SOURCE)
+aux_source_directory(./function CORE_SOURCE)
+aux_source_directory(./thread CORE_SOURCE)
+aux_source_directory(./model CORE_SOURCE)
+aux_source_directory(./common CORE_SOURCE)
+aux_source_directory(./module CORE_SOURCE)
+aux_source_directory(./utils/aes CORE_SOURCE)
+aux_source_directory(./utils CORE_SOURCE)
+aux_source_directory(. CORE_SOURCE)
# define libgpgfrontend_core
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
-add_library(gpgfrontend_core SHARED ${GPG_SOURCE})
+add_library(gpgfrontend_core SHARED ${CORE_SOURCE})
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendCoreExport.h")
generate_export_header(gpgfrontend_core EXPORT_FILE_NAME "${_export_file}")
-# link third-party libraries
-target_link_libraries(gpgfrontend_core PUBLIC config++)
-if (NOT LINUX)
- target_link_libraries(gpgfrontend_core PUBLIC config++ intl)
-endif ()
+if(NOT APPLE)
+ target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
+ if(MINGW)
+ set_target_properties(mimalloc
+ PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
+ )
+ endif()
+endif()
# qt-aes
target_sources(gpgfrontend_core PRIVATE
@@ -54,24 +63,10 @@ target_sources(gpgfrontend_core PRIVATE
aux_source_directory(${CMAKE_SOURCE_DIR}/third_party/encoding-detect ENCODING_DETECT_SOURCE_CODE)
target_sources(gpgfrontend_core PUBLIC ${ENCODING_DETECT_SOURCE_CODE})
-# icu
-if (APPLE)
- target_include_directories(gpgfrontend_core PRIVATE /usr/local/opt/icu4c/include)
- target_link_directories(gpgfrontend_core PRIVATE /usr/local/opt/icu4c/lib)
- target_link_libraries(gpgfrontend_core PRIVATE icui18n icuuc icudata)
-else ()
- find_package(ICU 60.0 REQUIRED COMPONENTS i18n uc data)
- message("ICU version: ${ICU_VERSION}")
- message("ICU libraries: ${ICU_LIBRARIES}")
- target_link_libraries(gpgfrontend_core PRIVATE ${ICU_LIBRARIES})
-endif ()
-
# link gnupg libraries
-target_link_libraries(gpgfrontend_core PRIVATE gpgme assuan gpg-error)
+target_link_libraries(gpgfrontend_core PUBLIC gpgme assuan gpg-error)
# link openssl
target_link_libraries(gpgfrontend_core PUBLIC OpenSSL::SSL OpenSSL::Crypto)
-# link boost libraries
-target_link_libraries(gpgfrontend_core PUBLIC ${Boost_LIBRARIES})
if (MINGW)
# for uuid ability in mingw
target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
@@ -81,17 +76,15 @@ endif ()
target_link_libraries(gpgfrontend_core PRIVATE spdlog)
# link libarchive
+if(APPLE)
+ set(LibArchive_INCLUDE_DIR "/usr/local/opt/libarchive/include")
+endif()
+find_package(LibArchive REQUIRED)
+target_include_directories(gpgfrontend_core PRIVATE ${LibArchive_INCLUDE_DIR})
target_link_libraries(gpgfrontend_core PRIVATE archive)
-
-# link json
-target_link_libraries(gpgfrontend_core
- PUBLIC nlohmann_json::nlohmann_json)
+
# link Qt core
-if(Qt6_DIR)
- target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
-else()
- target_link_libraries(gpgfrontend_core PUBLIC Qt5::Core)
-endif()
+target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
# set up pch
target_precompile_headers(gpgfrontend_core
diff --git a/src/core/GpgConstants.cpp b/src/core/GpgConstants.cpp
index 35e485d4..ade003a8 100644
--- a/src/core/GpgConstants.cpp
+++ b/src/core/GpgConstants.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,177 +28,5 @@
#include "core/GpgConstants.h"
-#include <boost/algorithm/string/predicate.hpp>
-
-#include "function/FileOperator.h"
-
-const char* GpgFrontend::GpgConstants::PGP_CRYPT_BEGIN =
- "-----BEGIN PGP MESSAGE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_CRYPT_END =
- "-----END PGP MESSAGE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN =
- "-----BEGIN PGP SIGNED MESSAGE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_SIGNED_END =
- "-----END PGP SIGNATURE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN =
- "-----BEGIN PGP SIGNATURE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_END =
- "-----END PGP SIGNATURE-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_PUBLIC_KEY_BEGIN =
- "-----BEGIN PGP PUBLIC KEY BLOCK-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_PRIVATE_KEY_BEGIN =
- "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
-const char* GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD =
- "GpgF_Scpt://"; ///<
-
-gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) {
- if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("[error: {}] source: {} description: {}", gpg_err_code(err),
- gpgme_strsource(err), gpgme_strerror(err));
- }
- return err;
-}
-
-gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err,
- gpgme_error_t predict) {
- auto err_code = gpg_err_code(err);
- if (err_code != gpg_err_code(predict)) {
- if (err_code == GPG_ERR_NO_ERROR)
- SPDLOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- else
- SPDLOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- }
- return err_code;
-}
-
-gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err,
- const std::string& comment) {
- if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- SPDLOG_WARN("[Error {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- }
- return err;
-}
-
-std::string GpgFrontend::beautify_fingerprint(
- GpgFrontend::BypeArrayConstRef fingerprint) {
- auto len = fingerprint.size();
- std::stringstream out;
- decltype(len) count = 0;
- while (count < len) {
- if (count && !(count % 5)) out << " ";
- out << fingerprint[count];
- count++;
- }
- return out.str();
-}
-
-static inline void ltrim(std::string& s) {
- s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
- return !std::isspace(ch);
- }));
-}
-
-static inline void rtrim(std::string& s) {
- s.erase(std::find_if(s.rbegin(), s.rend(),
- [](unsigned char ch) { return !std::isspace(ch); })
- .base(),
- s.end());
-}
-
-static inline std::string trim(std::string& s) {
- ltrim(s);
- rtrim(s);
- return s;
-}
-
-std::string GpgFrontend::read_all_data_in_file(const std::string& utf8_path) {
- std::string data;
- FileOperator::ReadFileStd(utf8_path, data);
- return data;
-}
-
-bool GpgFrontend::write_buffer_to_file(const std::string& utf8_path,
- const std::string& out_buffer) {
- return FileOperator::WriteFileStd(utf8_path, out_buffer);
-}
-
-std::string GpgFrontend::get_file_extension(const std::string& path) {
- // Create a path object from given string
- std::filesystem::path path_obj(path);
-
- // Check if file name in the path object has extension
- if (path_obj.has_extension()) {
- // Fetch the extension from path object and return
- return path_obj.extension().u8string();
- }
- // In case of no extension return empty string
- return {};
-}
-
-std::string GpgFrontend::get_only_file_name_with_path(const std::string& path) {
- // Create a path object from given string
- std::filesystem::path path_obj(path);
- // Check if file name in the path object has extension
- if (path_obj.has_filename()) {
- // Fetch the extension from path object and return
- return (path_obj.parent_path() / path_obj.stem()).u8string();
- }
- // In case of no extension return empty string
- return {};
-}
-
-int GpgFrontend::text_is_signed(GpgFrontend::BypeArrayRef text) {
- using boost::algorithm::ends_with;
- using boost::algorithm::starts_with;
-
- auto trim_text = trim(text);
- if (starts_with(trim_text, GpgConstants::PGP_SIGNED_BEGIN) &&
- ends_with(trim_text, GpgConstants::PGP_SIGNED_END))
- return 2;
- else if (text.find(GpgConstants::PGP_SIGNED_BEGIN) != std::string::npos &&
- text.find(GpgConstants::PGP_SIGNED_END) != std::string::npos)
- return 1;
- else
- return 0;
-}
-
-GpgFrontend::GpgEncrResult GpgFrontend::_new_result(
- gpgme_encrypt_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgDecrResult GpgFrontend::_new_result(
- gpgme_decrypt_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgSignResult GpgFrontend::_new_result(
- gpgme_sign_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgVerifyResult GpgFrontend::_new_result(
- gpgme_verify_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgGenKeyResult GpgFrontend::_new_result(
- gpgme_genkey_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-void GpgFrontend::_result_ref_deletor::operator()(void* _result) {
- SPDLOG_TRACE("gpgme unref {}", _result);
- if (_result != nullptr) gpgme_result_unref(_result);
-}
+namespace GpgFrontend {
+} // namespace GpgFrontend
diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h
index a8a87835..c2125650 100644
--- a/src/core/GpgConstants.h
+++ b/src/core/GpgConstants.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,200 +20,35 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPG_CONSTANTS_H
-#define GPG_CONSTANTS_H
-
-#include "GpgFrontendCore.h"
-
-const int RESTART_CODE = 1000; ///< only refresh ui
-const int DEEP_RESTART_CODE = 1001; // refresh core and ui
+#pragma once
namespace GpgFrontend {
-using ByteArray = std::string; ///<
-using ByteArrayPtr = std::unique_ptr<ByteArray>; ///<
-using StdBypeArrayPtr = std::unique_ptr<ByteArray>; ///<
-using BypeArrayRef = ByteArray&; ///<
-using BypeArrayConstRef = const ByteArray&; ///<
-using StringArgsPtr = std::unique_ptr<std::vector<std::string>>; ///<
-using StringArgsRef = std::vector<std::string>&; ///<
-
-using GpgError = gpgme_error_t;
-
-/**
- * @brief Result Deleter
- *
- */
-struct _result_ref_deletor {
- void operator()(void* _result);
-};
-
-using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; ///<
-using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; ///<
-using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; ///<
-using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; ///<
-using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; ///<
-// Convert from gpgme_xxx_result to GpgXXXResult
-
-/**
- * @brief
- *
- * @param result
- * @return GpgEncrResult
- */
-GPGFRONTEND_CORE_EXPORT GpgEncrResult
-_new_result(gpgme_encrypt_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgDecrResult
- */
-GPGFRONTEND_CORE_EXPORT GpgDecrResult
-_new_result(gpgme_decrypt_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgSignResult
- */
-GPGFRONTEND_CORE_EXPORT GpgSignResult _new_result(gpgme_sign_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgVerifyResult
- */
-GPGFRONTEND_CORE_EXPORT GpgVerifyResult
-_new_result(gpgme_verify_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgGenKeyResult
- */
-GPGFRONTEND_CORE_EXPORT GpgGenKeyResult
-_new_result(gpgme_genkey_result_t&& result);
-
-// Error Info Printer
-
-/**
- * @brief
- *
- * @param err
- * @return GpgError
- */
-GPGFRONTEND_CORE_EXPORT GpgError check_gpg_error(GpgError err);
-
-/**
- * @brief
- *
- * @param gpgmeError
- * @param comment
- * @return GpgError
- */
-GPGFRONTEND_CORE_EXPORT GpgError check_gpg_error(GpgError gpgmeError,
- const std::string& comment);
-
-/**
- * @brief
- *
- * @param err
- * @param predict
- * @return gpg_err_code_t
- */
-GPGFRONTEND_CORE_EXPORT gpg_err_code_t check_gpg_error_2_err_code(
- gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR);
-
-// Fingerprint
-
-/**
- * @brief
- *
- * @param fingerprint
- * @return std::string
- */
-GPGFRONTEND_CORE_EXPORT std::string beautify_fingerprint(
- BypeArrayConstRef fingerprint);
-
-// File Operation
-
-/**
- * @brief
- *
- * @param path
- * @return std::string
- */
-std::string read_all_data_in_file(const std::string& path);
-
-/**
- * @brief
- *
- * @param path
- * @param out_buffer
- * @return true
- * @return false
- */
-GPGFRONTEND_CORE_EXPORT bool write_buffer_to_file(
- const std::string& path, const std::string& out_buffer);
-
-/**
- * @brief Get the file extension object
- *
- * @param path
- * @return std::string
- */
-std::string get_file_extension(const std::string& path);
-
-/**
- * @brief Get the only file name with path object
- *
- * @param path
- * @return std::string
- */
-std::string get_only_file_name_with_path(const std::string& path);
-
-// Check
-
-/**
- * @brief
- *
- * @param text
- * @return int
- */
-int text_is_signed(BypeArrayRef text);
+constexpr int kRestartCode = 1000; ///< only refresh ui
+constexpr int kDeepRestartCode = 1001; // refresh core and ui
// Channels
-const int GPGFRONTEND_DEFAULT_CHANNEL = 0; ///<
-const int GPGFRONTEND_NON_ASCII_CHANNEL = 2; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgConstants {
- public:
- static const char* PGP_CRYPT_BEGIN; ///<
- static const char* PGP_CRYPT_END; ///<
- static const char* PGP_SIGNED_BEGIN; ///<
- static const char* PGP_SIGNED_END; ///<
- static const char* PGP_SIGNATURE_BEGIN; ///<
- static const char* PGP_SIGNATURE_END; ///<
- static const char* PGP_PUBLIC_KEY_BEGIN; ///<
- static const char* PGP_PRIVATE_KEY_BEGIN; ///<
- static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD; ///<
-};
+constexpr int kGpgFrontendDefaultChannel = 0; ///<
+constexpr int kGpgFrontendNonAsciiChannel = 2; ///<
+
+// HEADER
+constexpr const char* PGP_CRYPT_BEGIN = "-----BEGIN PGP MESSAGE-----"; ///<
+constexpr const char* PGP_CRYPT_END = "-----END PGP MESSAGE-----"; ///<
+constexpr const char* PGP_SIGNED_BEGIN =
+ "-----BEGIN PGP SIGNED MESSAGE-----"; ///<
+constexpr const char* PGP_SIGNED_END = "-----END PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_SIGNATURE_BEGIN =
+ "-----BEGIN PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_SIGNATURE_END = "-----END PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_PUBLIC_KEY_BEGIN =
+ "-----BEGIN PGP PUBLIC KEY BLOCK-----"; ///<
+constexpr const char* PGP_PRIVATE_KEY_BEGIN =
+ "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
} // namespace GpgFrontend
-
-#endif // GPG_CONSTANTS_H
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp
deleted file mode 100644
index 7d98004d..00000000
--- a/src/core/GpgContext.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgContext.h"
-
-#include <gpg-error.h>
-#include <gpgme.h>
-#include <spdlog/spdlog.h>
-#include <unistd.h>
-
-#include <mutex>
-#include <shared_mutex>
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/common/CoreCommonUtil.h"
-#include "core/function/CoreSignalStation.h"
-#include "core/function/gpg/GpgCommandExecutor.h"
-#include "core/thread/Task.h"
-#include "core/thread/TaskRunnerGetter.h"
-#include "function/gpg/GpgKeyGetter.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-namespace GpgFrontend {
-
-GpgContext::GpgContext(int channel)
- : SingletonFunctionObject<GpgContext>(channel) {}
-
-/**
- * Constructor
- * Set up gpgme-context, set paths to app-run path
- */
-GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
- gpgme_ctx_t _p_ctx;
-
- // get gpgme library version
- info_.GpgMEVersion = gpgme_check_version(nullptr);
-
- // create a new context
- check_gpg_error(gpgme_new(&_p_ctx));
- _ctx_ref = CtxRefHandler(_p_ctx);
-
- if (args.gpg_alone) {
- info_.AppPath = args.gpg_path;
- auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
- info_.AppPath.c_str(),
- info_.DatabasePath.c_str());
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- if (args.custom_gpgconf && !args.custom_gpgconf_path.empty()) {
- SPDLOG_DEBUG("set custom gpgconf path: {}", args.custom_gpgconf_path);
- auto err =
- gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_GPGCONF,
- args.custom_gpgconf_path.c_str(), nullptr);
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- // set context offline mode
- SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
- gpgme_set_offline(_ctx_ref.get(), args_.offline_mode ? 1 : 0);
-
- // set option auto import missing key
- // invalid at offline mode
- SPDLOG_DEBUG("gpg context auto import missing key: {}", args_.offline_mode);
- if (!args.offline_mode && args.auto_import_missing_key)
- check_gpg_error(gpgme_set_ctx_flag(_ctx_ref.get(), "auto-key-import", "1"));
-
- // get engine info
- auto engine_info = gpgme_ctx_get_engine_info(*this);
- // Check ENV before running
- bool check_passed = false, find_openpgp = false, find_gpgconf = false,
- find_cms = false;
-
- while (engine_info != nullptr) {
- if (!strcmp(engine_info->version, "1.0.0")) {
- engine_info = engine_info->next;
- continue;
- }
-
- SPDLOG_DEBUG(
- "gpg context engine info: {} {} {} {}",
- gpgme_get_protocol_name(engine_info->protocol),
- std::string(engine_info->file_name == nullptr ? "null"
- : engine_info->file_name),
- std::string(engine_info->home_dir == nullptr ? "null"
- : engine_info->home_dir),
- std::string(engine_info->version ? "null" : engine_info->version));
-
- switch (engine_info->protocol) {
- case GPGME_PROTOCOL_OpenPGP:
- find_openpgp = true;
- info_.AppPath = engine_info->file_name;
- info_.GnupgVersion = engine_info->version;
- info_.DatabasePath = std::string(engine_info->home_dir == nullptr
- ? "default"
- : engine_info->home_dir);
- break;
- case GPGME_PROTOCOL_CMS:
- find_cms = true;
- info_.CMSPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_GPGCONF:
- find_gpgconf = true;
- info_.GpgConfPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_ASSUAN:
- info_.AssuanPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_G13:
- break;
- case GPGME_PROTOCOL_UISERVER:
- break;
- case GPGME_PROTOCOL_SPAWN:
- break;
- case GPGME_PROTOCOL_DEFAULT:
- break;
- case GPGME_PROTOCOL_UNKNOWN:
- break;
- }
- engine_info = engine_info->next;
- }
-
- // set custom key db path
- if (!args.db_path.empty()) {
- info_.DatabasePath = args.db_path;
- auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
- info_.AppPath.c_str(),
- info_.DatabasePath.c_str());
- SPDLOG_DEBUG("ctx set custom key db path: {}", info_.DatabasePath);
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- // conditional check
- if ((info_.GnupgVersion >= "2.0.0" && find_gpgconf && find_openpgp &&
- find_cms) ||
- (info_.GnupgVersion > "1.0.0" && find_gpgconf))
- check_passed = true;
-
- if (!check_passed) {
- this->good_ = false;
- SPDLOG_ERROR("env check failed");
- return;
- } else {
- // speed up loading process
- gpgme_set_offline(*this, 1);
-
- // set keylist mode
- if (info_.GnupgVersion >= "2.0.0") {
- check_gpg_error(gpgme_set_keylist_mode(
- *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
- GPGME_KEYLIST_MODE_SIGS |
- GPGME_KEYLIST_MODE_SIG_NOTATIONS |
- GPGME_KEYLIST_MODE_WITH_TOFU));
- } else {
- check_gpg_error(gpgme_set_keylist_mode(
- *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS |
- GPGME_KEYLIST_MODE_SIG_NOTATIONS |
- GPGME_KEYLIST_MODE_WITH_TOFU));
- }
-
- // async, init context
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(new Thread::Task(
- [=](Thread::Task::DataObjectPtr) -> int {
- post_init_ctx();
- return 0;
- },
- "post_init_ctx"));
-
- good_ = true;
- }
-}
-
-void GpgContext::post_init_ctx() {
- // Set Independent Database
- if (info_.GnupgVersion <= "2.0.0" && args_.independent_database) {
- info_.DatabasePath = args_.db_path;
- SPDLOG_DEBUG("custom key db path {}", info_.DatabasePath);
- auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
- info_.AppPath.c_str(),
- info_.DatabasePath.c_str());
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- } else {
- info_.DatabasePath = "default";
- }
-
- if (args_.ascii) {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 1);
- } else {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 0);
- }
-
- // for unit test
- if (args_.test_mode) {
- if (info_.GnupgVersion >= "2.1.0") SetPassphraseCb(test_passphrase_cb);
- gpgme_set_status_cb(*this, test_status_cb, nullptr);
- }
-
- // preload info
- auto &info = GetInfo();
-
- // use custom qt dialog to replace pinentry
- if (!args_.use_pinentry) {
- SetPassphraseCb(custom_passphrase_cb);
- }
-
- connect(this, &GpgContext::SignalNeedUserInputPassphrase,
- CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalNeedUserInputPassphrase);
-}
-
-bool GpgContext::good() const { return good_; }
-
-void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t cb) const {
- if (info_.GnupgVersion >= "2.1.0") {
- if (gpgme_get_pinentry_mode(*this) != GPGME_PINENTRY_MODE_LOOPBACK) {
- gpgme_set_pinentry_mode(*this, GPGME_PINENTRY_MODE_LOOPBACK);
- }
- gpgme_set_passphrase_cb(*this, cb, nullptr);
- } else {
- SPDLOG_ERROR("not supported for gnupg version: {}", info_.GnupgVersion);
- }
-}
-
-gpgme_error_t GpgContext::test_passphrase_cb(void *opaque, const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- size_t res;
- std::string pass = "abcdefg\n";
- auto pass_len = pass.size();
-
- size_t off = 0;
-
- do {
- res = gpgme_io_write(fd, &pass[off], pass_len - off);
- if (res > 0) off += res;
- } while (res > 0 && off != pass_len);
-
- return off == pass_len ? 0 : gpgme_error_from_errno(errno);
-}
-
-gpgme_error_t GpgContext::custom_passphrase_cb(void *opaque,
- const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- SPDLOG_DEBUG("custom passphrase cb called, bad times: {}", last_was_bad);
-
- if (last_was_bad > 3) {
- SPDLOG_WARN("failure_counts is over three times");
- return gpgme_error_from_errno(GPG_ERR_CANCELED);
- }
-
- std::string passphrase =
- CoreCommonUtil::GetInstance()->GetTempCacheValue("__key_passphrase");
- // no pawword is an error situation
- if (passphrase.empty()) {
- // user input passphrase
- SPDLOG_DEBUG("might need user to input passparase");
- passphrase = GpgContext::GetInstance().need_user_input_passphrase();
- if (passphrase.empty()) {
- gpgme_io_write(fd, "\n", 1);
- return gpgme_error_from_errno(GPG_ERR_CANCELED);
- }
- }
-
- // the user must at least write a newline character before returning from the
- // callback.
- passphrase = passphrase.append("\n");
- auto passpahrase_size = passphrase.size();
-
- size_t off = 0, res = 0;
- do {
- res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
- if (res > 0) off += res;
- } while (res > 0 && off != passpahrase_size);
-
- return off == passpahrase_size ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
-}
-
-gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword,
- const char *args) {
- SPDLOG_DEBUG("keyword {}", keyword);
- return GPG_ERR_NO_ERROR;
-}
-
-std::string GpgContext::need_user_input_passphrase() {
- emit SignalNeedUserInputPassphrase();
-
- std::string final_passphrase;
- bool input_done = false;
- SPDLOG_DEBUG("loop start to wait from user");
- auto connection =
- connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalUserInputPassphraseDone, this,
- [&](QString passphrase) {
- SPDLOG_DEBUG("SignalUserInputPassphraseDone emitted");
- final_passphrase = passphrase.toStdString();
- input_done = true;
- });
- while (!input_done) {
- QCoreApplication::processEvents(QEventLoop::AllEvents, 800);
- }
- disconnect(connection);
-
- SPDLOG_DEBUG("lopper end");
- return final_passphrase;
-}
-
-const GpgInfo &GpgContext::GetInfo(bool refresh) {
- if (!extend_info_loaded_ || refresh) {
- // try lock
- std::unique_lock lock(preload_lock_);
-
- // check twice
- if (extend_info_loaded_ && !refresh) return info_;
-
- SPDLOG_DEBUG("start to load extra info");
-
- // get all components
- GpgCommandExecutor::GetInstance().Execute(
- info_.GpgConfPath, {"--list-components"},
- [=](int exit_code, const std::string &p_out, const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf components exit_code: {} process stdout size: {}",
- exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {} ,process stdout: "
- "{}",
- p_err, p_out);
- return;
- }
-
- auto &components_info = info_.ComponentsInfo;
- components_info["gpgme"] = {"GPG Made Easy", info_.GpgMEVersion,
- _("Embedded In"), "/"};
-
- auto gpgconf_binary_checksum =
- check_binary_chacksum(info_.GpgConfPath);
- components_info["gpgconf"] = {"GPG Configure", "/", info_.GpgConfPath,
- gpgconf_binary_checksum.has_value()
- ? gpgconf_binary_checksum.value()
- : "/"};
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- if (info_split_list.size() != 3) continue;
-
- auto component_name = info_split_list[0];
- auto component_desc = info_split_list[1];
- auto component_path = info_split_list[2];
-
- boost::algorithm::trim(component_name);
- boost::algorithm::trim(component_desc);
- boost::algorithm::trim(component_path);
-
-#ifdef WINDOWS
- // replace some special substrings on windows platform
- boost::replace_all(component_path, "%3a", ":");
-#endif
-
- auto binary_checksum = check_binary_chacksum(component_path);
-
- SPDLOG_DEBUG(
- "gnupg component name: {} desc: {} checksum: {} path: {} ",
- component_name, component_desc,
- binary_checksum.has_value() ? binary_checksum.value() : "/",
- component_path);
-
- std::string version = "/";
-
- if (component_name == "gpg") {
- version = info_.GnupgVersion;
- }
- if (component_name == "gpg-agent") {
- info_.GpgAgentPath = component_path;
- }
- if (component_name == "dirmngr") {
- info_.DirmngrPath = component_path;
- }
- if (component_name == "keyboxd") {
- info_.KeyboxdPath = component_path;
- }
-
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- // add component info to list
- components_info[component_name] = {
- component_desc, version, component_path,
- binary_checksum.has_value() ? binary_checksum.value() : "/"};
- }
- }
- });
-
- SPDLOG_DEBUG("start to get dirs info");
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--list-dirs"},
- [=](int exit_code, const std::string &p_out, const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf configurations exit_code: {} process stdout size: {}",
- exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {} process stdout: "
- "{}",
- p_err, p_out);
- return;
- }
-
- auto &configurations_info = info_.ConfigurationsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
- SPDLOG_DEBUG("gpgconf info line: {} info size: {}", line,
- info_split_list.size());
-
- if (info_split_list.size() != 2) continue;
-
- auto configuration_name = info_split_list[0];
- auto configuration_value = info_split_list[1];
- boost::algorithm::trim(configuration_name);
- boost::algorithm::trim(configuration_value);
-
-#ifdef WINDOWS
- // replace some special substrings on windows platform
- boost::replace_all(configuration_value, "%3a", ":");
-#endif
-
- // record gnupg home path
- if (configuration_name == "homedir") {
- info_.GnuPGHomePath = info_split_list[1];
- }
-
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- configurations_info[configuration_name] = {configuration_value};
- }
- }
- });
-
- SPDLOG_DEBUG("start to get components info");
-
- for (const auto &component : info_.ComponentsInfo) {
- SPDLOG_DEBUG("gpgconf check options ready", "component", component.first);
-
- if (component.first == "gpgme" || component.first == "gpgconf") continue;
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--check-options", component.first},
- [=](int exit_code, const std::string &p_out,
- const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf {} options exit_code: {} process stdout "
- "size: {} ",
- component.first, exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf {} options execute error, process "
- "stderr: {} , process stdout:",
- component.first, p_err, p_out);
- return;
- }
-
- auto &options_info = info_.OptionsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- SPDLOG_DEBUG("component {} options line: {} info size: {}",
- component.first, line, info_split_list.size());
-
- if (info_split_list.size() != 6) continue;
-
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- options_info[configuration_name] = {
- info_split_list[1], info_split_list[2], info_split_list[3],
- info_split_list[4], info_split_list[5]};
-
- boost::algorithm::trim(options_info[configuration_name][0]);
- boost::algorithm::trim(options_info[configuration_name][1]);
- boost::algorithm::trim(options_info[configuration_name][2]);
- boost::algorithm::trim(options_info[configuration_name][3]);
- boost::algorithm::trim(options_info[configuration_name][4]);
- }
- }
- });
- }
-
- SPDLOG_DEBUG("start to get avaliable component options info");
-
- for (const auto &component : info_.ComponentsInfo) {
- SPDLOG_DEBUG("gpgconf list options ready", "component", component.first);
-
- if (component.first == "gpgme" || component.first == "gpgconf") continue;
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--list-options", component.first},
- [=](int exit_code, const std::string &p_out,
- const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf {} avaliable options exit_code: {} process stdout "
- "size: {} ",
- component.first, exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf {} avaliable options execute error, process stderr: "
- "{} , process stdout:",
- component.first, p_err, p_out);
- return;
- }
-
- auto &available_options_info = info_.AvailableOptionsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- SPDLOG_DEBUG(
- "component {} avaliable options line: {} info size: {}",
- component.first, line, info_split_list.size());
-
- if (info_split_list.size() != 10) continue;
-
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- available_options_info[configuration_name] = {
- info_split_list[1], info_split_list[2], info_split_list[3],
- info_split_list[4], info_split_list[5], info_split_list[6],
- info_split_list[7], info_split_list[8], info_split_list[9]};
-
- boost::algorithm::trim(
- available_options_info[configuration_name][0]);
- boost::algorithm::trim(
- available_options_info[configuration_name][1]);
- boost::algorithm::trim(
- available_options_info[configuration_name][2]);
- boost::algorithm::trim(
- available_options_info[configuration_name][3]);
- boost::algorithm::trim(
- available_options_info[configuration_name][4]);
- boost::algorithm::trim(
- available_options_info[configuration_name][5]);
- boost::algorithm::trim(
- available_options_info[configuration_name][6]);
- boost::algorithm::trim(
- available_options_info[configuration_name][7]);
- boost::algorithm::trim(
- available_options_info[configuration_name][8]);
- }
- }
- });
- }
- extend_info_loaded_ = true;
- }
-
- // ensure nothing is changing now
- std::shared_lock lock(preload_lock_);
- return info_;
-}
-
-std::optional<std::string> GpgContext::check_binary_chacksum(
- std::filesystem::path path) {
- // check file info and access rights
- QFileInfo info(QString::fromStdString(path.u8string()));
- if (!info.exists() || !info.isFile() || !info.isReadable()) {
- SPDLOG_ERROR("get info for file {} error, exists: {}",
- info.filePath().toStdString(), info.exists());
- return {};
- }
-
- // open and read file
- QFile f(info.filePath());
- if (!f.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("open {} to calculate check sum error: {}", path.u8string(),
- f.errorString().toStdString());
- return {};
- }
-
- // read all data from file
- auto buffer = f.readAll();
- f.close();
-
- auto hash_sha = QCryptographicHash(QCryptographicHash::Sha256);
- // md5
- hash_sha.addData(buffer);
- auto sha = hash_sha.result().toHex().toStdString();
- SPDLOG_DEBUG("checksum for file {} is {}", path.u8string(), sha);
-
- return sha.substr(0, 6);
-}
-
-void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) {
- if (_ctx != nullptr) gpgme_release(_ctx);
-}
-
-} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h
deleted file mode 100644
index 474530c6..00000000
--- a/src/core/GpgContext.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef __SGPGMEPP_CONTEXT_H__
-#define __SGPGMEPP_CONTEXT_H__
-
-#include <optional>
-#include <string>
-
-#include "GpgFunctionObject.h"
-#include "GpgInfo.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief
- *
- */
-struct GpgContextInitArgs {
- // make no sense for gpg2
- bool independent_database = false; ///<
- std::string db_path = {};
-
- bool gpg_alone = false;
- std::string gpg_path = {};
-
- bool test_mode = false;
- bool ascii = true;
- bool offline_mode = false;
- bool auto_import_missing_key = false;
-
- bool custom_gpgconf = false;
- std::string custom_gpgconf_path;
-
- bool use_pinentry = false;
-
- GpgContextInitArgs() = default;
-};
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgContext
- : public QObject,
- public SingletonFunctionObject<GpgContext> {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Gpg Context object
- *
- * @param args
- */
- explicit GpgContext(const GpgContextInitArgs& args = {});
-
- /**
- * @brief Construct a new Gpg Context object
- *
- * @param channel
- */
- explicit GpgContext(int channel);
-
- /**
- * @brief Destroy the Gpg Context object
- *
- */
- ~GpgContext() override = default;
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] bool good() const;
-
- /**
- * @brief Get the Info object
- *
- * @return const GpgInfo&
- */
- [[nodiscard]] const GpgInfo& GetInfo(bool refresh = false);
-
- /**
- * @brief
- *
- * @return gpgme_ctx_t
- */
- operator gpgme_ctx_t() const { return _ctx_ref.get(); }
-
- private:
- GpgInfo info_{}; ///<
- GpgContextInitArgs args_{}; ///<
- bool extend_info_loaded_ = false;
- std::shared_mutex preload_lock_{};
-
- /**
- * @brief
- *
- */
- void post_init_ctx();
-
- /**
- * @brief
- *
- * @return std::string
- */
- std::string need_user_input_passphrase();
-
- /**
- * @brief Construct a new std::check component existence object
- *
- */
- std::optional<std::string> check_binary_chacksum(std::filesystem::path);
-
- /**
- * @brief
- *
- */
- struct _ctx_ref_deleter {
- void operator()(gpgme_ctx_t _ctx);
- };
-
- using CtxRefHandler =
- std::unique_ptr<struct gpgme_context, _ctx_ref_deleter>; ///<
- CtxRefHandler _ctx_ref = nullptr; ///<
- bool good_ = true; ///<
-
- signals:
- /**
- * @brief
- *
- */
- void SignalNeedUserInputPassphrase();
-
- public:
- /**
- * @brief
- *
- * @param opaque
- * @param uid_hint
- * @param passphrase_info
- * @param last_was_bad
- * @param fd
- * @return gpgme_error_t
- */
- static gpgme_error_t test_passphrase_cb(void* opaque, const char* uid_hint,
- const char* passphrase_info,
- int last_was_bad, int fd);
-
- /**
- * @brief
- *
- * @param opaque
- * @param uid_hint
- * @param passphrase_info
- * @param last_was_bad
- * @param fd
- * @return gpgme_error_t
- */
- static gpgme_error_t custom_passphrase_cb(void* opaque, const char* uid_hint,
- const char* passphrase_info,
- int last_was_bad, int fd);
-
- /**
- * @brief
- *
- * @param hook
- * @param keyword
- * @param args
- * @return gpgme_error_t
- */
- static gpgme_error_t test_status_cb(void* hook, const char* keyword,
- const char* args);
-
- /**
- * @brief Set the Passphrase Cb object
- *
- * @param func
- */
- void SetPassphraseCb(gpgme_passphrase_cb_t func) const;
-};
-} // namespace GpgFrontend
-
-#endif // __SGPGMEPP_CONTEXT_H__ \ No newline at end of file
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 6d782439..f231056f 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,236 +20,445 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCoreInit.h"
-#include <spdlog/async.h>
-#include <spdlog/common.h>
-#include <spdlog/sinks/rotating_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
+#include <gpgme.h>
-#include <filesystem>
-#include <string>
-
-#include "GpgFunctionObject.h"
-#include "core/GpgContext.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
-#include "function/gpg/GpgAdvancedOperator.h"
-#include "spdlog/spdlog.h"
-#include "thread/Task.h"
-#include "thread/TaskRunner.h"
-#include "thread/TaskRunnerGetter.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/function/gpg/GpgAdvancedOperator.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/module/ModuleManager.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunner.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
namespace GpgFrontend {
-/**
- * @brief setup logging system and do proper initialization
- *
- */
-void InitCoreLoggingSystem() {
- using namespace boost::posix_time;
- using namespace boost::gregorian;
-
- // get the log directory
- auto logfile_path =
- (GlobalSettingStation::GetInstance().GetLogDir() / "core");
- logfile_path.replace_extension(".log");
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
- sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
- logfile_path.u8string(), 1048576 * 32, 8));
-
- // thread pool
- spdlog::init_thread_pool(1024, 2);
-
- // logger
- auto core_logger = std::make_shared<spdlog::async_logger>(
- "core", begin(sinks), end(sinks), spdlog::thread_pool());
- core_logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
-#ifdef DEBUG
- core_logger->set_level(spdlog::level::trace);
-#else
- core_logger->set_level(spdlog::level::info);
-#endif
+void DestroyGpgFrontendCore() { SingletonStorageCollection::Destroy(); }
- // flush policy
- core_logger->flush_on(spdlog::level::err);
- spdlog::flush_every(std::chrono::seconds(5));
+auto VerifyGpgconfPath(const QFileInfo& gnupg_install_fs_path) -> bool {
+ return gnupg_install_fs_path.isAbsolute() && gnupg_install_fs_path.exists() &&
+ gnupg_install_fs_path.isFile();
+}
- // register it as default logger
- spdlog::set_default_logger(core_logger);
+auto VerifyKeyDatabasePath(const QFileInfo& key_database_fs_path) -> bool {
+ return key_database_fs_path.isAbsolute() && key_database_fs_path.exists() &&
+ key_database_fs_path.isDir();
}
-void ShutdownCoreLoggingSystem() {
-#ifdef WINDOWS
- // Under VisualStudio, this must be called before main finishes to workaround
- // a known VS issue
- spdlog::drop_all();
- spdlog::shutdown();
-#endif
+auto SearchGpgconfPath(const QList<QString>& candidate_paths) -> QString {
+ for (const auto& path : candidate_paths) {
+ if (VerifyGpgconfPath(QFileInfo(path))) {
+ return path;
+ }
+ }
+ return {};
}
-void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
+auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString {
+ for (const auto& path : candidate_paths) {
+ GF_CORE_LOG_DEBUG("searh for candidate key database path: {}", path);
+ if (VerifyKeyDatabasePath(QFileInfo(path))) {
+ return path;
+ }
+ }
+ return {};
+}
+
+auto InitGpgME(const QString& gnupg_path) -> bool {
+ // init gpgme subsystem and get gpgme library version
+ Module::UpsertRTValue("core", "gpgme.version",
+ QString(gpgme_check_version(nullptr)));
-void init_gpgfrontend_core() {
- /* Initialize the locale environment. */
- SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
- // init gpgme subsystem
- gpgme_check_version(nullptr);
gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
#ifdef LC_MESSAGES
gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
#endif
- // read settings
- bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
+ if (!gnupg_path.isEmpty()) {
+ GF_CORE_LOG_DEBUG("gpgme set engine info, gnupg path: {}", gnupg_path);
+ CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_OPENPGP,
+ gnupg_path.toUtf8(), nullptr));
+ }
+
+ gpgme_ctx_t p_ctx;
+ CheckGpgError(gpgme_new(&p_ctx));
+
+ // get engine info
+ auto* engine_info = gpgme_ctx_get_engine_info(p_ctx);
+ // Check ENV before running
+ bool find_openpgp = false;
+ bool find_gpgconf = false;
+ bool find_cms = false;
+
+ while (engine_info != nullptr) {
+ if (strcmp(engine_info->version, "1.0.0") == 0) {
+ engine_info = engine_info->next;
+ continue;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "gpg context engine info: {} {} {} {}",
+ gpgme_get_protocol_name(engine_info->protocol),
+ QString(engine_info->file_name == nullptr ? "null"
+ : engine_info->file_name),
+ QString(engine_info->home_dir == nullptr ? "null"
+ : engine_info->home_dir),
+ QString(engine_info->version ? "null" : engine_info->version));
+
+ switch (engine_info->protocol) {
+ case GPGME_PROTOCOL_OpenPGP:
+ find_openpgp = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.openpgp", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.app_path",
+ QString(engine_info->file_name));
+ Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
+ QString(engine_info->version));
+ Module::UpsertRTValue(
+ "core", "gpgme.ctx.database_path",
+ QString(engine_info->home_dir == nullptr ? ""
+ : engine_info->home_dir));
+ break;
+ case GPGME_PROTOCOL_CMS:
+ find_cms = true;
+ Module::UpsertRTValue("core", "gpgme.engine.cms", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
+ QString(engine_info->file_name));
+
+ break;
+ case GPGME_PROTOCOL_GPGCONF:
+ find_gpgconf = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.gpgconf", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
+ QString(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_ASSUAN:
+
+ Module::UpsertRTValue("core", "gpgme.engine.assuan", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
+ QString(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_G13:
+ break;
+ case GPGME_PROTOCOL_UISERVER:
+ break;
+ case GPGME_PROTOCOL_SPAWN:
+ break;
+ case GPGME_PROTOCOL_DEFAULT:
+ break;
+ case GPGME_PROTOCOL_UNKNOWN:
+ break;
+ }
+ engine_info = engine_info->next;
+ }
+
+ // release gpgme context
+ gpgme_release(p_ctx);
+
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
- bool auto_import_missing_key =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.auto_import_missing_key", false);
+ // conditional check: only support gpg 2.1.x now
+ if (!(CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
+ find_openpgp && find_cms)) {
+ GF_CORE_LOG_ERROR("gpgme env check failed, abort");
+ return false;
+ }
+
+ Module::UpsertRTValue("core", "env.state.gpgme", 1);
+ return true;
+}
- bool use_custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_key_database_path", false);
+auto GetGnuPGPathByGpgConf(const QString& gnupg_install_fs_path) -> QString {
+ auto* process = new QProcess();
+ process->setProgram(gnupg_install_fs_path);
+ process->start();
+ process->waitForFinished(1000);
+ auto output_buffer = process->readAllStandardOutput();
+ process->deleteLater();
- std::string custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_key_database_path", std::string{});
+ if (output_buffer.isEmpty()) return {};
- bool use_custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_gnupg_install_path", false);
+ auto line_split_list = QString(output_buffer).split("\n");
+ for (const auto& line : line_split_list) {
+ auto info_split_list = line.split(":");
- std::string custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_gnupg_install_path", std::string{});
+ if (info_split_list.size() != 3) continue;
- bool use_pinentry_as_password_input_dialog =
- GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_pinentry_as_password_input_dialog", false);
+ auto component_name = info_split_list[0].trimmed();
+ auto component_desc = info_split_list[1].trimmed();
+ auto component_path = info_split_list[2].trimmed();
- SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
- use_custom_key_database_path);
- SPDLOG_DEBUG("core loaded custom key databse path: {}",
- custom_key_database_path);
+ if (component_name.toLower() == "gpg") {
+#ifdef WINDOWS
+ // replace some special substrings on windows platform
+ component_path.replace("%3a", ":");
+#endif
+ QFileInfo file_info(component_path);
+ if (file_info.exists() && file_info.isFile()) {
+ return file_info.absoluteFilePath();
+ }
+ return {};
+ }
+ }
+ return "";
+}
- // check gpgconf path
- std::filesystem::path custom_gnupg_install_fs_path =
- custom_gnupg_install_path;
+auto DetectGnuPGPath() -> QString {
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ auto use_custom_gnupg_install_path =
+ settings.value("basic/use_custom_gnupg_install_path", false).toBool();
+ auto custom_gnupg_install_path =
+ settings.value("basic/custom_gnupg_install_path", QString{}).toString();
+
+ QString gnupg_install_fs_path;
+ // user defined
+ if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) {
+ // check gpgconf path
+ gnupg_install_fs_path = custom_gnupg_install_path;
#ifdef WINDOWS
- custom_gnupg_install_fs_path /= "gpgconf.exe";
+ gnupg_install_fs_path += "/gpgconf.exe";
#else
- custom_gnupg_install_fs_path /= "gpgconf";
+ gnupg_install_fs_path += "/gpgconf";
#endif
- if (!custom_gnupg_install_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_gnupg_install_fs_path) ||
- !std::filesystem::is_regular_file(custom_gnupg_install_fs_path)) {
- use_custom_gnupg_install_path = false;
- SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
- custom_gnupg_install_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
- custom_gnupg_install_fs_path.u8string());
+ if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) {
+ GF_CORE_LOG_ERROR("core loaded custom gpgconf path is illegal: {}",
+ gnupg_install_fs_path);
+ gnupg_install_fs_path = "";
+ }
}
- // check key database path
- std::filesystem::path custom_key_database_fs_path = custom_key_database_path;
- if (!custom_key_database_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_key_database_fs_path) ||
- !std::filesystem::is_directory(custom_key_database_fs_path)) {
- use_custom_key_database_path = false;
- SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
- custom_key_database_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
- custom_key_database_fs_path.u8string());
+ // fallback to default path
+ if (gnupg_install_fs_path.isEmpty()) {
+#ifdef MACOS
+ gnupg_install_fs_path = SearchGpgconfPath(
+ {"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"});
+ GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
+ gnupg_install_fs_path);
+#endif
+
+#ifdef WINDOWS
+ gnupg_install_fs_path =
+ SearchGpgconfPath({"C:/Program Files (x86)/gnupg/bin"});
+ GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
+ gnupg_install_fs_path);
+#endif
}
- // init default channel
- auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_DEFAULT_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
+ if (!gnupg_install_fs_path.isEmpty()) {
+ return GetGnuPGPathByGpgConf(
+ QFileInfo(gnupg_install_fs_path).absoluteFilePath());
+ }
+ return "";
+}
- // set key database path
- if (use_custom_key_database_path && !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
- }
+void InitGpgFrontendCore(CoreInitArgs args) {
+ // initialize global register table
+ Module::UpsertRTValue("core", "env.state.gpgme", 0);
+ Module::UpsertRTValue("core", "env.state.ctx", 0);
+ Module::UpsertRTValue("core", "env.state.gnupg", 0);
+ Module::UpsertRTValue("core", "env.state.basic", 0);
+ Module::UpsertRTValue("core", "env.state.all", 0);
+
+ // initialize locale environment
+ GF_CORE_LOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
+
+ auto gnupg_install_fs_path = DetectGnuPGPath();
+ GF_CORE_LOG_INFO("detected gnupg path: {}", gnupg_install_fs_path);
+
+ // initialize library gpgme
+ if (!InitGpgME(gnupg_install_fs_path)) {
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("GpgME inilization failed"));
+ return;
+ }
- if (use_custom_gnupg_install_path) {
- args.custom_gpgconf = true;
- args.custom_gpgconf_path = custom_gnupg_install_fs_path.u8string();
+ auto* task = new Thread::Task(
+ [args, gnupg_install_fs_path](const DataObjectPtr&) -> int {
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ // read settings from config file
+ auto forbid_all_gnupg_connection =
+ settings.value("network/forbid_all_gnupg_connection", false)
+ .toBool();
+
+ auto auto_import_missing_key =
+ settings.value("network/auto_import_missing_key", false).toBool();
+
+ auto use_custom_key_database_path =
+ settings.value("basic/use_custom_key_database_path", false)
+ .toBool();
+
+ auto custom_key_database_path =
+ settings.value("basic/custom_key_database_path", QString{})
+ .toString();
+
+ auto custom_gnupg_install_path =
+ settings.value("basic/custom_gnupg_install_path", QString{})
+ .toString();
+
+ auto use_pinentry_as_password_input_dialog =
+ settings.value("basic/use_pinentry_as_password_input_dialog", false)
+ .toBool();
+
+ GF_CORE_LOG_DEBUG("core loaded if use custom key databse path: {}",
+ use_custom_key_database_path);
+ GF_CORE_LOG_DEBUG("core loaded custom key databse path: {}",
+ custom_key_database_path);
+
+ // check key database path
+ QString key_database_fs_path;
+ // user defined
+ if (use_custom_key_database_path &&
+ !custom_key_database_path.isEmpty()) {
+ key_database_fs_path = custom_key_database_path;
+ if (VerifyKeyDatabasePath(QFileInfo(key_database_fs_path))) {
+ GF_CORE_LOG_ERROR(
+ "core loaded custom gpg key database is illegal: {}",
+ key_database_fs_path);
+ } else {
+ use_custom_key_database_path = true;
+ GF_CORE_LOG_DEBUG("core loaded custom gpg key database path: {}",
+ key_database_fs_path);
+ }
+ } else {
+#if defined(LINUX) || defined(MACOS)
+ use_custom_key_database_path = true;
+ key_database_fs_path =
+ SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"});
+ GF_CORE_LOG_DEBUG("core loaded searched key database path: {}",
+ key_database_fs_path);
+#endif
}
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
-
- // exit if failed
- if (!default_ctx.good()) {
- SPDLOG_ERROR("default gnupg context init error");
- };
-
- // async init no-ascii channel
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(
- new Thread::Task([=](Thread::Task::DataObjectPtr data_obj) -> int {
- // init non-ascii channel
- auto& ctx = GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_NON_ASCII_CHANNEL,
- [=]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
- args.ascii = false;
-
- // set key database path
- if (use_custom_key_database_path &&
- !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
+ if (args.load_default_gpg_context) {
+ // init ctx, also checking the basical env
+ auto& ctx = GpgFrontend::GpgContext::CreateInstance(
+ kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr {
+ GpgFrontend::GpgContextInitArgs args;
+
+ // set key database path
+ if (use_custom_key_database_path &&
+ !key_database_fs_path.isEmpty()) {
+ QFileInfo dir_info(key_database_fs_path);
+ if (dir_info.exists() && dir_info.isDir() &&
+ dir_info.isReadable() && dir_info.isWritable()) {
+ args.db_path = dir_info.absoluteFilePath();
+ GF_CORE_LOG_INFO("using key database path: {}",
+ args.db_path);
+ } else {
+ GF_CORE_LOG_ERROR(
+ "custom key database path: {}, is not point to "
+ "an accessible directory",
+ key_database_fs_path);
}
+ }
+
+ // set custom gnupg path
+ if (!gnupg_install_fs_path.isEmpty()) {
+ args.custom_gpgconf = true;
+ args.custom_gpgconf_path = gnupg_install_fs_path;
+ }
+
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
+ args.use_pinentry = use_pinentry_as_password_input_dialog;
+
+ return ConvertToChannelObjectPtr<>(
+ SecureCreateUniqueObject<GpgContext>(
+ args, kGpgFrontendDefaultChannel));
+ });
+
+ // exit if failed
+ if (!ctx.Good()) {
+ GF_CORE_LOG_ERROR("default gnupg context init error, abort");
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("GpgME Context inilization failed"));
+ return -1;
+ }
+ Module::UpsertRTValue("core", "env.state.ctx", 1);
+ }
- if (use_custom_gnupg_install_path) {
- args.custom_gpgconf = true;
- args.custom_gpgconf_path =
- custom_gnupg_install_fs_path.u8string();
- }
-
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
-
- if (!ctx.good()) SPDLOG_ERROR("no-ascii channel init error");
- return ctx.good() ? 0 : -1;
- }));
+ if (args.load_default_gpg_context) {
+ if (!GpgKeyGetter::GetInstance().FlushKeyCache()) {
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("Gpg Key Detabase inilization failed"));
+ };
+ }
+ GF_CORE_LOG_DEBUG(
+ "basic env checking finished, "
+ "including gpgme, ctx, and key infos");
+ Module::UpsertRTValue("core", "env.state.basic", 1);
+ CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
+
+ // if gnupg-info-gathering module activated
+ if (args.gather_external_gnupg_info &&
+ Module::IsModuleAcivate("com.bktus.gpgfrontend.module."
+ "integrated.gnupg-info-gathering")) {
+ GF_CORE_LOG_DEBUG(
+ "module gnupg-info-gathering is activated, "
+ "loading external gnupg info...");
+
+ // gather external gnupg info
+ Module::TriggerEvent(
+ "GPGFRONTEND_CORE_INITLIZED",
+ [](const Module::EventIdentifier& /*e*/,
+ const Module::Event::ListenerIdentifier& l_id,
+ DataObjectPtr o) {
+ GF_CORE_LOG_DEBUG(
+ "received event GPGFRONTEND_CORE_INITLIZED callback "
+ "from module: {}",
+ l_id);
+
+ if (l_id ==
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-"
+ "gathering") {
+ GF_CORE_LOG_DEBUG(
+ "received callback from gnupg-info-gathering ");
+
+ // try to restart all components
+ GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
+ Module::UpsertRTValue("core", "env.state.gnupg", 1);
+
+ // announce that all checkings were finished
+ GF_CORE_LOG_INFO(
+ "all env checking finished, including gpgme, "
+ "ctx and gnupg");
+ Module::UpsertRTValue("core", "env.state.all", 1);
+ }
+ });
+ } else {
+ GF_CORE_LOG_DEBUG("gnupg-info-gathering is not activated");
+ Module::UpsertRTValue("core", "env.state.all", 1);
+ }
+ return 0;
+ },
+ "core_init_task");
- // try to restart all components
- GpgFrontend::GpgAdvancedOperator::GetInstance().RestartGpgComponents();
-}
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, []() {
-void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); }
+ });
-void new_default_settings_channel(int channel) {
- GpgFrontend::GpgContext::CreateInstance(
- channel, [&]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
+ // start the thread to check ctx and gnupg state
+ // it may take a few seconds or minutes
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(task);
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h
index 41e04d60..15f0254d 100644
--- a/src/core/GpgCoreInit.h
+++ b/src/core/GpgCoreInit.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,57 +20,33 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGCOREINIT_H
-#define GPGFRONTEND_GPGCOREINIT_H
+#pragma once
#include "GpgConstants.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT InitCoreLoggingSystem();
-
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT ShutdownCoreLoggingSystem();
-
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
-
-/**
- * @brief
- *
- */
-void init_gpgfrontend_core();
+struct CoreInitArgs {
+ bool gather_external_gnupg_info;
+ bool load_default_gpg_context;
+};
/**
* @brief
*
*/
-void reset_gpgfrontend_core();
+void GPGFRONTEND_CORE_EXPORT DestroyGpgFrontendCore();
/**
* @brief
*
- * @param channel
*/
-void new_default_settings_channel(
- int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL);
+void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore(CoreInitArgs);
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGCOREINIT_H
diff --git a/src/core/GpgInfo.cpp b/src/core/GpgFrontendCore.cpp
index a77f0ed4..82ed09f4 100644
--- a/src/core/GpgInfo.cpp
+++ b/src/core/GpgFrontendCore.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,10 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "core/GpgInfo.h"
+#include "core/GpgFrontendCore.h"
diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h
index 0b433b96..14b1f878 100644
--- a/src/core/GpgFrontendCore.h
+++ b/src/core/GpgFrontendCore.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,56 +20,33 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFRONTENDCORE_H
-#define GPGFRONTEND_GPGFRONTENDCORE_H
+#pragma once
-#include "GpgFrontend.h"
-
-// gnupg
-#include <gpgme.h>
+// Qt
+#include <QtCore>
-// std includes
-#include <cassert>
-#include <filesystem>
-#include <functional>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <random>
-#include <shared_mutex>
-#include <stdexcept>
-#include <string>
-#include <typeinfo>
-#include <utility>
+// std
+#include <cstdint>
#include <vector>
-// boost includes
-#include <boost/date_time.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/format.hpp>
+// spdlog library configuration
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
+#include <spdlog/spdlog.h>
-// Qt includes
-#include <QtCore>
+// logger fmt
+#include "log/QtLoggerFmt.h"
-// libconfig includes
-#include <libconfig.h++>
-
-// libarchive includes
-#include <libarchive/libarchive/archive.h>
-#include <libarchive/libarchive/archive_entry.h>
+// gpgme library
+#include <gpgme.h>
-// json includes
-#include <nlohmann/json.hpp>
+// logbal includes or macroes
+#include "GpgFrontend.h"
-// dll export macro
+// dll export macroes
#include "GpgFrontendCoreExport.h"
-
-#endif // GPGFRONTEND_GPGFRONTENDCORE_H
diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp
deleted file mode 100644
index 0ddc290c..00000000
--- a/src/core/GpgFunctionObject.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgFunctionObject.h"
-
-#include <cassert>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <shared_mutex>
-
-void GpgFrontend::ChannelObject::SetChannel(int channel) {
- this->channel_ = channel;
-}
-
-int GpgFrontend::ChannelObject::GetChannel() const { return channel_; }
-
-int GpgFrontend::ChannelObject::GetDefaultChannel() { return _default_channel; }
-
-void GpgFrontend::SingletonStorage::ReleaseChannel(int channel) {
- decltype(instances_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(instances_mutex_);
- _it = instances_map_.find(channel);
- }
- if (_it != instances_map_.end()) instances_map_.erase(_it);
-}
-
-GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::FindObjectInChannel(
- int channel) {
- // read instances_map_
- decltype(instances_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(instances_mutex_);
- _it = instances_map_.find(channel);
- if (_it == instances_map_.end()) {
- return nullptr;
- } else {
- return _it->second.get();
- }
- }
-}
-
-std::vector<int> GpgFrontend::SingletonStorage::GetAllChannelId() {
- std::vector<int> _channels;
- for (const auto& [key, value] : instances_map_) {
- _channels.push_back(key);
- }
- return _channels;
-}
-
-GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::SetObjectInChannel(
- int channel, std::unique_ptr<ChannelObject> p_obj) {
- {
- SPDLOG_TRACE("set channel: {} instance address: {}", channel,
- static_cast<void*>(&instances_map_));
-
- assert(p_obj != nullptr);
- if (p_obj == nullptr) return nullptr;
-
- auto raw_obj = p_obj.get();
- p_obj->SetChannel(channel);
- {
- std::unique_lock<std::shared_mutex> lock(instances_mutex_);
- instances_map_.insert({channel, std::move(p_obj)});
- }
- return raw_obj;
- }
-}
-
-GpgFrontend::SingletonStorage*
-GpgFrontend::SingletonStorageCollection::GetSingletonStorage(
- const std::type_info& type_id) {
- const auto hash = type_id.hash_code();
-
- while (true) {
- decltype(storages_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(storages_mutex_);
- _it = storages_map_.find(hash);
- }
- if (_it == storages_map_.end()) {
- {
- std::unique_lock<std::shared_mutex> lock(storages_mutex_);
- storages_map_.insert({hash, std::make_unique<SingletonStorage>()});
- }
- SPDLOG_TRACE("hash: {} created, storage address: {} type_name: {}", hash,
- static_cast<void*>(&storages_map_), type_id.name());
- continue;
- } else {
- return _it->second.get();
- }
- }
-}
-
-GpgFrontend::SingletonStorageCollection*
-GpgFrontend::SingletonStorageCollection::GetInstance(
- bool force_refresh = false) {
- static SingletonStorageCollection* instance = nullptr;
-
- if (force_refresh || instance == nullptr) {
- instance = new SingletonStorageCollection();
- SPDLOG_DEBUG("new single storage collection created: {}",
- static_cast<void*>(instance));
- }
-
- return instance;
-}
-
-GpgFrontend::ChannelObject::ChannelObject() noexcept = default;
-
-GpgFrontend::ChannelObject::ChannelObject(int channel) : channel_(channel) {}
diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h
deleted file mode 100644
index 9b8c2aa3..00000000
--- a/src/core/GpgFunctionObject.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
-#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
-
-#include <mutex>
-
-#include "GpgConstants.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief object which in channel system
- *
- */
-class GPGFRONTEND_CORE_EXPORT ChannelObject {
- public:
- /**
- * @brief Construct a new Default Channel Object object
- *
- */
- ChannelObject() noexcept;
-
- /**
- * @brief Construct a new Channel Object object
- *
- * @param channel
- */
- ChannelObject(int channel);
-
- /**
- * @brief Get the Default Channel object
- *
- * @return int
- */
- static int GetDefaultChannel();
-
- /**
- * @brief Get the Channel object
- *
- * @return int
- */
- [[nodiscard]] int GetChannel() const;
-
- /**
- * @brief Set the Channel object
- *
- * @param channel
- */
- void SetChannel(int channel);
-
- private:
- int channel_ = _default_channel; ///< The channel id
- static constexpr int _default_channel = 0; ///< The default channel id
-};
-
-class GPGFRONTEND_CORE_EXPORT SingletonStorage {
- public:
- /**
- * @brief
- *
- * @param channel
- */
- void ReleaseChannel(int channel);
-
- /**
- * @brief
- *
- * @param channel
- * @return T*
- */
- ChannelObject* FindObjectInChannel(int channel);
-
- /**
- * @brief Get all the channel ids
- *
- * @return std::vector<int>
- */
- std::vector<int> GetAllChannelId();
-
- /**
- * @brief Set a new object in channel object
- *
- * @param channel
- * @param p_obj
- * @return T*
- */
- ChannelObject* SetObjectInChannel(int channel,
- std::unique_ptr<ChannelObject> p_obj);
-
- private:
- std::shared_mutex instances_mutex_; ///< mutex for _instances_map
- std::map<int, std::unique_ptr<ChannelObject>>
- instances_map_; ///< map of singleton instances
-};
-
-class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
- public:
- /**
- * @brief Get the Instance object
- *
- * @return SingletonStorageCollection*
- */
- static SingletonStorageCollection* GetInstance(bool force_refresh);
-
- /**
- * @brief Get the Singleton Storage object
- *
- * @param singleton_function_object
- * @return SingletonStorage*
- */
- SingletonStorage* GetSingletonStorage(const std::type_info&);
-
- private:
- std::shared_mutex storages_mutex_; ///< mutex for storages_map_
- std::map<size_t, std::unique_ptr<SingletonStorage>> storages_map_;
-};
-/**
- * @brief
- *
- * @tparam T
- */
-template <typename T>
-class SingletonFunctionObject : public ChannelObject {
- public:
- /**
- * @brief prohibit copy
- *
- */
- SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
-
- /**
- * @brief prohibit copy
- *
- * @return SingletonFunctionObject&
- */
- SingletonFunctionObject& operator=(const SingletonFunctionObject<T>&) =
- delete;
-
- /**
- * @brief Get the Instance object
- *
- * @param channel
- * @return T&
- */
- static T& GetInstance(
- int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
- static std::mutex g_channel_mutex_map_lock;
- static std::map<int, std::mutex> g_channel_mutex_map;
-
- {
- std::lock_guard<std::mutex> guard(g_channel_mutex_map_lock);
- if (g_channel_mutex_map.find(channel) == g_channel_mutex_map.end()) {
- g_channel_mutex_map[channel];
- }
- }
-
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
- "T not derived from SingletonFunctionObject<T>");
-
- auto* p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
- auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
-
- if (_p_pbj == nullptr) {
- // lock this channel
- std::lock_guard<std::mutex> guard(g_channel_mutex_map[channel]);
-
- // double check
- if ((_p_pbj = (T*)(p_storage->FindObjectInChannel(channel))) != nullptr)
- return *_p_pbj;
-
- // do create object of this channel
- auto new_obj = std::unique_ptr<ChannelObject>(new T(channel));
- return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj)));
- } else {
- return *_p_pbj;
- }
- }
-
- /**
- * @brief Create a Instance object
- *
- * @param channel
- * @param factory
- * @return T&
- */
- static T& CreateInstance(
- int channel,
- std::function<std::unique_ptr<ChannelObject>(void)> factory) {
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
- "T not derived from SingletonFunctionObject<T>");
-
- auto p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
-
- auto _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
-
- if (_p_pbj == nullptr) {
- return *(
- T*)(p_storage->SetObjectInChannel(channel, std::move(factory())));
- } else
- return *_p_pbj;
- }
-
- /**
- * @brief
- *
- * @param channel
- * @return T&
- */
- static void ReleaseChannel(int channel) {
- SingletonStorageCollection::GetInstance(false)
- ->GetSingletonStorage(typeid(T))
- ->ReleaseChannel(channel);
- }
-
- /**
- * @brief Get the Default Channel object
- *
- * @return int
- */
- static int GetDefaultChannel() { return ChannelObject::GetDefaultChannel(); }
-
- /**
- * @brief Get the Channel object
- *
- * @return int
- */
- [[nodiscard]] int GetChannel() const { return ChannelObject::GetChannel(); }
-
- /**
- * @brief Get all the channel ids
- *
- * @return std::vector<int>
- */
- static std::vector<int> GetAllChannelId() {
- return SingletonStorageCollection::GetInstance(false)
- ->GetSingletonStorage(typeid(T))
- ->GetAllChannelId();
- }
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject(T&&) = delete;
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject(const T&) = delete;
-
- /**
- * @brief
- *
- */
- void operator=(const T&) = delete;
-
- protected:
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject() = default;
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- * @param channel
- */
- explicit SingletonFunctionObject(int channel) : ChannelObject(channel) {}
-
- /**
- * @brief Destroy the Singleton Function Object object
- *
- */
- virtual ~SingletonFunctionObject() = default;
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
diff --git a/src/core/GpgGenKeyInfo.cpp b/src/core/GpgGenKeyInfo.cpp
deleted file mode 100644
index 290c93c2..00000000
--- a/src/core/GpgGenKeyInfo.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgGenKeyInfo.h"
-
-#include <algorithm>
-#include <boost/date_time/gregorian/greg_date.hpp>
-#include <boost/date_time/gregorian/greg_duration.hpp>
-#include <boost/date_time/gregorian/gregorian_types.hpp>
-#include <cassert>
-#include <string>
-#include <vector>
-
-void GpgFrontend::GenKeyInfo::SetAlgo(
- const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo) {
- SPDLOG_DEBUG("set algo name: {}", m_algo.first);
- // Check algo if supported
- std::string algo_args = m_algo.second;
- if (standalone_) {
- if (!subkey_) {
- auto support_algo = GetSupportedKeyAlgoStandalone();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- } else {
- auto support_algo = GetSupportedSubkeyAlgoStandalone();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- }
- } else {
- if (!subkey_) {
- auto support_algo = GetSupportedKeyAlgo();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- } else {
- auto support_algo = GetSupportedSubkeyAlgo();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- }
- }
-
- // reset all options
- reset_options();
-
- if (!this->subkey_) {
- this->SetAllowCertification(true);
- } else {
- this->SetAllowCertification(false);
- }
-
- this->allow_change_certification_ = false;
-
- if (!standalone_) boost::algorithm::to_lower(algo_args);
-
- if (algo_args == "rsa") {
- /**
- * RSA is the world’s premier asymmetric cryptographic algorithm,
- * and is built on the difficulty of factoring extremely large composites.
- * GnuPG supports RSA with key sizes of between 1024 and 4096 bits.
- */
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 4096;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
-
- } else if (algo_args == "dsa") {
- /**
- * Algorithm (DSA) as a government standard for digital signatures.
- * Originally, it supported key lengths between 512 and 1024 bits.
- * Recently, NIST has declared 512-bit keys obsolete:
- * now, DSA is available in 1024, 2048 and 3072-bit lengths.
- */
- SetAllowEncryption(false);
- allow_change_encryption_ = false;
-
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 3072;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
-
- } else if (algo_args == "ed25519") {
- /**
- * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
- * ranging from 1024 to 4096 bits.
- */
- SetAllowEncryption(false);
- allow_change_encryption_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- } else if (algo_args == "cv25519") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 4096;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
- } else if (algo_args == "nistp256" || algo_args == "nistp384" ||
- algo_args == "nistp521") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- } else if (algo_args == "brainpoolp256r1") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- }
-
- this->algo_ = algo_args;
-}
-
-void GpgFrontend::GenKeyInfo::reset_options() {
- allow_change_encryption_ = true;
- SetAllowEncryption(true);
-
- allow_change_certification_ = true;
- SetAllowCertification(true);
-
- allow_change_signing_ = true;
- SetAllowSigning(true);
-
- allow_change_authentication_ = true;
- SetAllowAuthentication(true);
-
- passphrase_.clear();
-}
-
-std::string GpgFrontend::GenKeyInfo::GetKeySizeStr() const {
- if (key_size_ > 0) {
- return std::to_string(key_size_);
- } else {
- return {};
- }
-}
-
-void GpgFrontend::GenKeyInfo::SetKeyLength(int m_key_size) {
- if (m_key_size < suggest_min_key_size_ ||
- m_key_size > suggest_max_key_size_) {
- return;
- }
- GenKeyInfo::key_size_ = m_key_size;
-}
-
-void GpgFrontend::GenKeyInfo::SetExpireTime(
- const boost::posix_time::ptime &m_expired) {
- using namespace boost::gregorian;
- if (!IsNonExpired()) {
- GenKeyInfo::expired_ = m_expired;
- }
-}
-
-void GpgFrontend::GenKeyInfo::SetNonExpired(bool m_non_expired) {
- using namespace boost::posix_time;
- if (!m_non_expired) this->expired_ = from_time_t(0);
- GenKeyInfo::non_expired_ = m_non_expired;
-}
-
-void GpgFrontend::GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) {
- if (allow_change_encryption_)
- GenKeyInfo::allow_encryption_ = m_allow_encryption;
-}
-
-void GpgFrontend::GenKeyInfo::SetAllowCertification(
- bool m_allow_certification) {
- if (allow_change_certification_)
- GenKeyInfo::allow_certification_ = m_allow_certification;
-}
-
-GpgFrontend::GenKeyInfo::GenKeyInfo(bool m_is_sub_key, bool m_standalone)
- : standalone_(m_standalone), subkey_(m_is_sub_key) {
- assert(GetSupportedKeyAlgo().size() > 0);
- SetAlgo(GetSupportedKeyAlgo()[0]);
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgo() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_key_algo = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- {"ECDSA", "ED25519"},
- };
- return support_key_algo;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgo() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- {"ECDSA", "ED25519"},
- {"ECDH NIST P-256", "NISTP256"},
- {"ECDH NIST P-384", "NISTP384"},
- {"ECDH NIST P-521", "NISTP521"},
- // {"ECDH BrainPool P-256", "BRAINPOOlP256R1"}
- };
- return support_subkey_algo;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgoStandalone() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo_standalone = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- };
- return support_subkey_algo_standalone;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgoStandalone() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo_standalone = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- };
- return support_subkey_algo_standalone;
-}
diff --git a/src/core/GpgInfo.h b/src/core/GpgInfo.h
deleted file mode 100644
index f4415af1..00000000
--- a/src/core/GpgInfo.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H
-#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H
-
-#include <mutex>
-#include <string>
-
-namespace GpgFrontend {
-/**
- * @brief Use to record some info about gnupg
- *
- */
-class GpgInfo {
- public:
- std::string GnupgVersion; ///< version of gnupg
- std::string GpgMEVersion; ///<
-
- std::string AppPath; ///< executable binary path of gnupg
- std::string DatabasePath; ///< key database path
- std::string GpgConfPath; ///< executable binary path of gpgconf
- std::string AssuanPath; ///< executable binary path of assuan
- std::string CMSPath; ///< executable binary path of cms
- std::string GpgAgentPath; ///< executable binary path of gpg-agent
- std::string DirmngrPath; ///< executable binary path of dirmgr
- std::string KeyboxdPath; ///< executable binary path of keyboxd
-
- std::string GnuPGHomePath; ///< value of ---homedir
-
- std::map<std::string, std::vector<std::string>> ComponentsInfo; ///<
- std::map<std::string, std::vector<std::string>> ConfigurationsInfo; ///<
- std::map<std::string, std::vector<std::string>> OptionsInfo; ///<
- std::map<std::string, std::vector<std::string>> AvailableOptionsInfo; ///<
-
- std::shared_mutex Lock;
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H
diff --git a/src/core/GpgModel.h b/src/core/GpgModel.h
index d8d4e6fe..72574988 100644
--- a/src/core/GpgModel.h
+++ b/src/core/GpgModel.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,38 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
-#define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
+#pragma once
-#include "core/GpgConstants.h"
+//
+#include "core/typedef/GpgTypedef.h"
+
+//
#include "core/model/GpgData.h"
#include "core/model/GpgKey.h"
#include "core/model/GpgSignature.h"
-namespace GpgFrontend {
-
-using KeyId = std::string; ///<
-using SubkeyId = std::string; ///<
-using KeyIdArgsList = std::vector<KeyId>; ///<
-using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; ///<
-using UIDArgsList = std::vector<std::string>; ///<
-using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; ///<
-using SignIdArgsList = std::vector<std::pair<std::string, std::string>>; ///<
-using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; ///<
-using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; ///<
-using KeyArgsList = std::vector<GpgKey>; ///<
-using KeyListPtr = std::unique_ptr<KeyArgsList>; ///<
-using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; ///<
-using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///<
-using KeyPtr = std::unique_ptr<GpgKey>; ///<
-using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///<
-
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
+// namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.cpp b/src/core/common/CoreCommonUtil.cpp
deleted file mode 100644
index 93cad60a..00000000
--- a/src/core/common/CoreCommonUtil.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "CoreCommonUtil.h"
-
-#include <string>
-
-namespace GpgFrontend {
-
-std::unique_ptr<CoreCommonUtil> CoreCommonUtil::instance_ = nullptr; ///<
-
-CoreCommonUtil* CoreCommonUtil::GetInstance() {
- if (instance_ == nullptr) {
- instance_ = std::make_unique<CoreCommonUtil>();
- }
- return instance_.get();
-}
-
-void CoreCommonUtil::SetTempCacheValue(const std::string& key,
- const std::string& value) {
- temp_cache_[key] = value;
-}
-
-std::string CoreCommonUtil::GetTempCacheValue(const std::string& key) {
- std::string temp_cache_value;
- std::swap(temp_cache_value, temp_cache_[key]);
- return temp_cache_value;
-}
-
-void CoreCommonUtil::ResetTempCacheValue(const std::string& key) {
- std::string temp_cache_value;
- std::swap(temp_cache_value, temp_cache_[key]);
-}
-
-} // namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.h b/src/core/common/CoreCommonUtil.h
deleted file mode 100644
index 58bb4d40..00000000
--- a/src/core/common/CoreCommonUtil.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#ifndef GPGFRONTEND_CORECOMMONUTIL_H
-#define GPGFRONTEND_CORECOMMONUTIL_H
-
-#include <string>
-
-#include "core/GpgFrontendCore.h"
-
-namespace GpgFrontend {
-
-class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Core Common Util object
- *
- */
- static CoreCommonUtil *GetInstance();
-
- /**
- * @brief
- *
- */
- CoreCommonUtil() = default;
-
- /**
- * @brief set a temp cache under a certain key
- *
- */
- void SetTempCacheValue(const std::string &, const std::string &);
-
- /**
- * @brief after get the temp cache, its value will be imediately ease in
- * storage
- *
- * @return std::string
- */
- std::string GetTempCacheValue(const std::string &);
-
- /**
- * @brief imediately ease temp cache in storage
- *
- * @return std::string
- */
- void ResetTempCacheValue(const std::string &);
-
- signals:
-
- /**
- * @brief
- *
- */
- void SignalGnupgNotInstall();
-
- private:
- static std::unique_ptr<CoreCommonUtil> instance_; ///<
- std::map<std::string, std::string> temp_cache_; //<
-};
-
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CORECOMMONUTIL_H
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 8aad0500..f1345f87 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,7 +28,15 @@
#include "ArchiveFileOperator.h"
-int copy_data(struct archive *ar, struct archive *aw) {
+#include <archive.h>
+#include <archive_entry.h>
+#include <sys/fcntl.h>
+
+#include "core/utils/AsyncUtils.h"
+
+namespace GpgFrontend {
+
+auto CopyData(struct archive *ar, struct archive *aw) -> int {
int r;
const void *buff;
size_t size;
@@ -38,231 +46,218 @@ int copy_data(struct archive *ar, struct archive *aw) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_data_block() failed: {}",
- archive_error_string(ar));
+ GF_CORE_LOG_ERROR("archive_read_data_block() failed: {}",
+ archive_error_string(ar));
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_data_block() failed: {}",
- archive_error_string(aw));
+ GF_CORE_LOG_ERROR("archive_write_data_block() failed: {}",
+ archive_error_string(aw));
return (r);
}
}
}
-void GpgFrontend::ArchiveFileOperator::CreateArchive(
- const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path, int compress,
- const std::vector<std::filesystem::path> &files) {
- SPDLOG_DEBUG("CreateArchive: {}", archive_path.u8string());
-
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
-
- auto relative_archive_path =
- std::filesystem::relative(archive_path, base_path);
-
- std::vector<std::filesystem::path> relative_files;
- relative_files.reserve(files.size());
- for (const auto &file : files) {
- relative_files.push_back(std::filesystem::relative(file, base_path));
- }
-
- struct archive *a;
- struct archive_entry *entry;
- ssize_t len;
- int fd;
-
- SPDLOG_DEBUG("compress: {}", compress);
-
- a = archive_write_new();
- switch (compress) {
-#ifndef NO_BZIP2_CREATE
- case 'j':
- case 'y':
- archive_write_add_filter_bzip2(a);
- break;
-#endif
-#ifndef NO_COMPRESS_CREATE
- case 'Z':
- archive_write_add_filter_compress(a);
- break;
-#endif
-#ifndef NO_GZIP_CREATE
- case 'z':
- archive_write_add_filter_gzip(a);
- break;
-#endif
- default:
- archive_write_add_filter_none(a);
- break;
- }
- archive_write_set_format_ustar(a);
- archive_write_set_format_pax_restricted(a);
-
- auto u8_filename = relative_archive_path.u8string();
-
- if (!u8_filename.empty() && u8_filename == u8"-")
- throw std::runtime_error("cannot write to stdout");
-
-#ifdef WINDOWS
- archive_write_open_filename_w(a, relative_archive_path.wstring().c_str());
-#else
- archive_write_open_filename(a, u8_filename.c_str());
-#endif
-
- for (const auto &file : relative_files) {
- struct archive *disk = archive_read_disk_new();
-#ifndef NO_LOOKUP
- archive_read_disk_set_standard_lookup(disk);
-#endif
- int r;
-
- SPDLOG_DEBUG("reading file: {}", file.u8string());
-
-#ifdef WINDOWS
- r = archive_read_disk_open_w(disk, file.wstring().c_str());
-#else
- r = archive_read_disk_open(disk, file.u8string().c_str());
-#endif
-
- SPDLOG_DEBUG("read file done: {}", file.u8string());
-
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("{archive_read_disk_open() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_disk_open() failed");
- }
+struct ArchiveReadClientData {
+ GFDataExchanger *ex;
+ std::array<std::byte, 1024> buf;
+ const std::byte *p_buf = buf.data();
+};
+
+auto ArchiveReadCallback(struct archive *, void *client_data,
+ const void **buffer) -> ssize_t {
+ auto *rdata = static_cast<ArchiveReadClientData *>(client_data);
+ *buffer = reinterpret_cast<const void *>(rdata->p_buf);
+ return rdata->ex->Read(rdata->buf.data(), rdata->buf.size());
+}
- for (;;) {
- entry = archive_entry_new();
- r = archive_read_next_header2(disk, entry);
-
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header2() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_next_header2() failed");
- }
- archive_read_disk_descend(disk);
-
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry),
- archive_entry_size(entry), archive_entry_filetype(entry));
-
- r = archive_write_header(a, entry);
- if (r < ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_write_header() failed");
- }
- if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal");
- if (r > ARCHIVE_FAILED) {
- QByteArray buff;
-#ifdef WINDOWS
- FileOperator::ReadFile(
- QString::fromStdWString(archive_entry_sourcepath_w(entry)), buff);
-#else
- FileOperator::ReadFile(archive_entry_sourcepath(entry), buff);
-#endif
- archive_write_data(a, buff.data(), buff.size());
- }
- archive_entry_free(entry);
- }
- archive_read_close(disk);
- archive_read_free(disk);
- }
- archive_write_close(a);
- archive_write_free(a);
+auto ArchiveWriteCallback(struct archive *, void *client_data,
+ const void *buffer, size_t length) -> ssize_t {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ return ex->Write(static_cast<const std::byte *>(buffer), length);
+}
- QDir::setCurrent(current_base_path_backup);
+auto ArchiveCloseWriteCallback(struct archive *, void *client_data) -> int {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ ex->CloseWrite();
+ return 0;
}
-void GpgFrontend::ArchiveFileOperator::ExtractArchive(
- const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path) {
- SPDLOG_DEBUG("ExtractArchive: {}", archive_path.u8string());
+void ArchiveFileOperator::NewArchive2DataExchanger(
+ const QString &target_directory, std::shared_ptr<GFDataExchanger> exchanger,
+ const OperationCallback &cb) {
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ std::array<char, 1024> buff{};
+ auto ret = 0;
+ const auto base_path = QDir(QDir(target_directory).absolutePath());
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
+ auto *archive = archive_write_new();
+ archive_write_add_filter_none(archive);
+ archive_write_set_format_pax_restricted(archive);
- struct archive *a;
- struct archive *ext;
- struct archive_entry *entry;
+ archive_write_open(archive, exchanger.get(), nullptr,
+ ArchiveWriteCallback, ArchiveCloseWriteCallback);
- a = archive_read_new();
- ext = archive_write_disk_new();
- archive_write_disk_set_options(ext, 0);
-#ifndef NO_BZIP2_EXTRACT
- archive_read_support_filter_bzip2(a);
-#endif
-#ifndef NO_GZIP_EXTRACT
- archive_read_support_filter_gzip(a);
-#endif
-#ifndef NO_COMPRESS_EXTRACT
- archive_read_support_filter_compress(a);
-#endif
-#ifndef NO_TAR_EXTRACT
- archive_read_support_format_tar(a);
-#endif
-#ifndef NO_CPIO_EXTRACT
- archive_read_support_format_cpio(a);
-#endif
-#ifndef NO_LOOKUP
- archive_write_disk_set_standard_lookup(ext);
-#endif
+ auto *disk = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(disk);
- auto filename = archive_path.u8string();
-
- if (!filename.empty() && filename == u8"-") {
- SPDLOG_ERROR("cannot read from stdin");
- }
#ifdef WINDOWS
- if (archive_read_open_filename_w(a, archive_path.wstring().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open_w(
+ disk, target_directory.toStdWString().c_str());
#else
- if (archive_read_open_filename(a, archive_path.u8string().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open(disk, target_directory.toUtf8());
#endif
- SPDLOG_ERROR("archive_read_open_filename() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_open_filename() failed");
- }
-
- for (;;) {
- int r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_next_header() failed");
- }
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry), archive_entry_size(entry),
- archive_entry_filetype(entry));
- r = archive_write_header(ext, entry);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(ext));
- } else {
- r = copy_data(a, ext);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("copy_data() failed: {}", archive_error_string(ext));
- }
- }
- }
- archive_read_close(a);
- archive_read_free(a);
- archive_write_close(ext);
- archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
+ archive_error_string(disk));
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return -1;
+ }
+
+ for (;;) {
+ auto *entry = archive_entry_new();
+ r = archive_read_next_header2(disk, entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_next_header2() failed, ret: {}, explain: {}", r,
+ archive_error_string(disk));
+ ret = -1;
+ break;
+ }
+
+ archive_read_disk_descend(disk);
+
+ // turn absolute path to relative path
+ archive_entry_set_pathname(
+ entry,
+ base_path.relativeFilePath(QString(archive_entry_pathname(entry)))
+ .toUtf8());
+
+ r = archive_write_header(archive, entry);
+ if (r < ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {} ", r,
+ archive_error_string(archive));
+ continue;
+ }
+
+ if (r == ARCHIVE_FATAL) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {}, "
+ "abort ...",
+ r, archive_error_string(archive));
+ ret = -1;
+ break;
+ }
+
+ if (r > ARCHIVE_FAILED) {
+ auto fd = open(archive_entry_sourcepath(entry), O_RDONLY);
+ auto len = read(fd, buff.data(), buff.size());
+ while (len > 0) {
+ archive_write_data(archive, buff.data(), len);
+ len = read(fd, buff.data(), buff.size());
+ }
+ close(fd);
+ }
+ archive_entry_free(entry);
+ }
+
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return ret;
+ },
+ cb, "archive_write_new");
+}
- QDir::setCurrent(current_base_path_backup);
+void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> ex, const QString &target_path,
+ const OperationCallback &cb) {
+ GF_CORE_LOG_INFO("target path: {}", target_path);
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ auto *archive = archive_read_new();
+ auto *ext = archive_write_disk_new();
+
+ auto r = archive_read_support_filter_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_filter_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_read_support_format_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_format_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ auto rdata = ArchiveReadClientData{};
+ rdata.ex = ex.get();
+
+ r = archive_read_open(archive, &rdata, nullptr, ArchiveReadCallback,
+ nullptr);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_write_disk_set_options(ext, 0);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_disk_set_options(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ for (;;) {
+ struct archive_entry *entry;
+ r = archive_read_next_header(archive, &entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_next_header(), ret: {}, reason: {}",
+ r, archive_error_string(archive));
+ break;
+ }
+
+ archive_entry_set_pathname(
+ entry,
+ (target_path + "/" + archive_entry_pathname(entry)).toUtf8());
+
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ } else {
+ r = CopyData(archive, ext);
+ }
+ }
+
+ r = archive_read_free(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+ r = archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+
+ return 0;
+ },
+ cb, "archive_read_new");
}
-void GpgFrontend::ArchiveFileOperator::ListArchive(
- const std::filesystem::path &archive_path) {
+void ArchiveFileOperator::ListArchive(const QString &archive_path) {
struct archive *a;
struct archive_entry *entry;
int r;
@@ -270,14 +265,16 @@ void GpgFrontend::ArchiveFileOperator::ListArchive(
a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
- r = archive_read_open_filename(a, archive_path.u8string().c_str(),
+ r = archive_read_open_filename(a, archive_path.toUtf8(),
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
- SPDLOG_DEBUG("File: {}", archive_entry_pathname(entry));
- SPDLOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
archive_read_data_skip(a); // Note 2
}
r = archive_read_free(a); // Note 3
if (r != ARCHIVE_OK) return;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h
index 4db5af5f..bfeec0c4 100644
--- a/src/core/function/ArchiveFileOperator.h
+++ b/src/core/function/ArchiveFileOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,40 +20,50 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ARCHIVEFILEOPERATOR_H
-#define GPGFRONTEND_ARCHIVEFILEOPERATOR_H
+#pragma once
#include "core/GpgFrontendCore.h"
-#include "core/function/FileOperator.h"
+#include "core/model/GFDataExchanger.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-struct ArchiveStruct {
- struct archive *archive;
- struct archive_entry *entry;
- int fd;
- bool is_open;
- std::string name;
-};
-
class GPGFRONTEND_CORE_EXPORT ArchiveFileOperator {
public:
- static void ListArchive(const std::filesystem::path &archive_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ */
+ static void ListArchive(const QString &archive_path);
- static void CreateArchive(const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path,
- int compress,
- const std::vector<std::filesystem::path> &files);
+ /**
+ * @brief Create a Archive object
+ *
+ * @param base_path
+ * @param archive_path
+ * @param compress
+ * @param files
+ */
+ static void NewArchive2DataExchanger(const QString &target_directory,
+ std::shared_ptr<GFDataExchanger>,
+ const OperationCallback &cb);
- static void ExtractArchive(const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ * @param base_path
+ */
+ static void ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> fd, const QString &target_path,
+ const OperationCallback &cb);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ARCHIVEFILEOPERATOR_H
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp
index d9aead66..719c962d 100644
--- a/src/core/function/CacheManager.cpp
+++ b/src/core/function/CacheManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,119 +29,256 @@
#include "CacheManager.h"
#include <algorithm>
-#include <boost/format.hpp>
-#include <string>
+#include <shared_mutex>
+#include <utility>
-#include "function/DataObjectOperator.h"
-#include "spdlog/spdlog.h"
+#include "core/function/DataObjectOperator.h"
+#include "core/utils/MemoryUtils.h"
-GpgFrontend::CacheManager::CacheManager(int channel)
- : m_timer_(new QTimer(this)),
- SingletonFunctionObject<CacheManager>(channel) {
- connect(m_timer_, &QTimer::timeout, this, &CacheManager::flush_cache_storage);
- m_timer_->start(15000);
+namespace GpgFrontend {
- load_all_cache_storage();
-}
+template <typename Key, typename Value>
+class ThreadSafeMap {
+ public:
+ using MapType = std::map<Key, Value>;
+ using IteratorType = typename MapType::iterator;
-void GpgFrontend::CacheManager::SaveCache(std::string key,
- const nlohmann::json& value,
- bool flush) {
- auto data_object_key = get_data_object_key(key);
- cache_storage_.insert(key, value);
+ void insert(const Key& key, const Value& value) {
+ std::unique_lock lock(mutex_);
+ (*map_)[key] = value;
+ }
- if (std::find(key_storage_.begin(), key_storage_.end(), key) ==
- key_storage_.end()) {
- SPDLOG_DEBUG("register new key of cache", key);
- key_storage_.push_back(key);
+ auto get(const Key& key) -> std::optional<Value> {
+ std::shared_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ return it->second;
+ }
+ return std::nullopt;
}
- if (flush) {
- flush_cache_storage();
+ auto exists(const Key& key) -> bool {
+ std::shared_lock lock(mutex_);
+ return map_->count(key) > 0;
}
-}
-nlohmann::json GpgFrontend::CacheManager::LoadCache(std::string key) {
- auto data_object_key = get_data_object_key(key);
+ auto begin() -> IteratorType { return map_mirror_->begin(); }
+
+ auto end() -> IteratorType { return map_mirror_->end(); }
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, {}));
+ auto mirror() -> ThreadSafeMap& {
+ std::shared_lock lock(mutex_);
+ *map_mirror_ = *map_;
+ return *this;
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ auto remove(QString key) -> bool {
+ std::unique_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ map_->erase(it);
+ return true;
+ }
+ return false;
+ }
-nlohmann::json GpgFrontend::CacheManager::LoadCache(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, default_value));
+ private:
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_mirror_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ mutable std::shared_mutex mutex_;
+};
+
+class CacheManager::Impl : public QObject {
+ Q_OBJECT
+ public:
+ Impl() : flush_timer_(new QTimer(this)) {
+ connect(flush_timer_, &QTimer::timeout, this,
+ &Impl::slot_flush_cache_storage);
+ flush_timer_->start(15000);
+
+ // load data from storage
+ load_all_cache_storage();
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ void SaveDurableCache(QString key, const QJsonDocument& value, bool flush) {
+ auto data_object_key = get_data_object_key(key);
+ durable_cache_storage_.insert(key, value);
-std::string GpgFrontend::CacheManager::get_data_object_key(std::string key) {
- return (boost::format("__cache_data_%1%") % key).str();
-}
+ if (!key_storage_.contains(key)) {
+ GF_CORE_LOG_DEBUG("register new key of cache", key);
+ key_storage_.push_back(key);
+ }
-nlohmann::json GpgFrontend::CacheManager::load_cache_storage(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
- data_object_key);
+ if (flush) slot_flush_cache_storage();
+ }
- if (stored_data.has_value()) {
- return stored_data.value();
- } else {
- return default_value;
+ auto LoadDurableCache(const QString& key) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(key, load_cache_storage(key, {}));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
-}
-void GpgFrontend::CacheManager::flush_cache_storage() {
- for (auto cache : cache_storage_.mirror()) {
- auto key = get_data_object_key(cache.first);
- SPDLOG_DEBUG("save cache into filesystem, key {}, value size: {}", key,
- cache.second.size());
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(key,
- cache.second);
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(
+ key, load_cache_storage(key, std::move(default_value)));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_,
- key_storage_);
-}
-void GpgFrontend::CacheManager::register_cache_key(std::string key) {}
+ auto ResetDurableCache(const QString& key) -> bool {
+ auto data_object_key = get_data_object_key(key);
+ return durable_cache_storage_.remove(key);
+ }
+
+ void FlushCacheStorage() { this->slot_flush_cache_storage(); }
-void GpgFrontend::CacheManager::load_all_cache_storage() {
- SPDLOG_DEBUG("start to load all cache from file system");
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+ void SaveCache(const QString& key, QString value) {
+ runtime_cache_storage_.insert(key, new QString(std::move(value)));
+ }
- // get cache data list from file system
- nlohmann::json registered_key_list;
- if (stored_data.has_value()) {
- registered_key_list = std::move(stored_data.value());
+ auto LoadCache(const QString& key) -> QString {
+ auto* value = runtime_cache_storage_.object(key);
+ if (value == nullptr) return {};
+ return *value;
}
- if (!registered_key_list.is_array()) {
+ void ResetCache(const QString& key) { runtime_cache_storage_.remove(key); }
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_flush_cache_storage() {
+ for (const auto& cache : durable_cache_storage_.mirror()) {
+ auto key = get_data_object_key(cache.first);
+ GF_CORE_LOG_TRACE("save cache into filesystem, key {}", key);
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ key, QJsonDocument(cache.second));
+ }
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
- drk_key_, nlohmann::json::array());
- SPDLOG_ERROR("drk_key_ is not an array, abort.");
- return;
+ drk_key_, QJsonDocument(key_storage_));
}
- for (auto key : registered_key_list) {
- load_cache_storage(key, {});
+ private:
+ QCache<QString, QString> runtime_cache_storage_;
+ ThreadSafeMap<QString, QJsonDocument> durable_cache_storage_;
+ QJsonArray key_storage_;
+ QTimer* flush_timer_;
+ const QString drk_key_ = "__cache_manage_data_register_key_list";
+
+ /**
+ * @brief Get the data object key object
+ *
+ * @param key
+ * @return QString
+ */
+ static auto get_data_object_key(const QString& key) -> QString {
+ return QString("__cache_data_%1").arg(key);
}
- key_storage_ = registered_key_list;
-} \ No newline at end of file
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonObject
+ */
+ static auto load_cache_storage(const QString& key,
+ QJsonDocument default_value) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
+ data_object_key);
+
+ if (stored_data.has_value()) return stored_data.value();
+ return default_value;
+ }
+
+ /**
+ * @brief
+ *
+ */
+ void load_all_cache_storage() {
+ GF_CORE_LOG_DEBUG("start to load all cache from file system");
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+
+ // get cache data list from file system
+ QJsonArray registered_key_list;
+ if (stored_data->isArray()) {
+ registered_key_list = stored_data->array();
+ } else {
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ drk_key_, QJsonDocument(QJsonArray()));
+ }
+
+ for (const auto& key : registered_key_list) {
+ load_cache_storage(key.toString(), {});
+ }
+
+ key_storage_ = registered_key_list;
+ }
+
+ /**
+ * @brief
+ *
+ * @param key
+ */
+ void register_cache_key(const QString& key) {}
+};
+
+CacheManager::CacheManager(int channel)
+ : SingletonFunctionObject<CacheManager>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+CacheManager::~CacheManager() { p_->FlushCacheStorage(); }
+
+void CacheManager::SaveDurableCache(const QString& key,
+ const QJsonDocument& value, bool flush) {
+ p_->SaveDurableCache(key, value, flush);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key) -> QJsonDocument {
+ return p_->LoadDurableCache(key);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key,
+ QJsonDocument default_value)
+ -> QJsonDocument {
+ return p_->LoadDurableCache(key, std::move(default_value));
+}
+
+auto CacheManager::ResetDurableCache(const QString& key) -> bool {
+ return p_->ResetDurableCache(key);
+}
+
+void CacheManager::SaveCache(const QString& key, QString value) {
+ p_->SaveCache(key, std::move(value));
+}
+
+auto CacheManager::LoadCache(const QString& key) -> QString {
+ return p_->LoadCache(key);
+}
+
+void CacheManager::ResetCache(const QString& key) {
+ return p_->ResetCache(key);
+}
+} // namespace GpgFrontend
+
+#include "CacheManager.moc" \ No newline at end of file
diff --git a/src/core/function/CacheManager.h b/src/core/function/CacheManager.h
index 8234de2a..67e7fd75 100644
--- a/src/core/function/CacheManager.h
+++ b/src/core/function/CacheManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,94 +20,99 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CACHEMANAGER_H
-#define GPGFRONTEND_CACHEMANAGER_H
+#pragma once
-#include <string>
-
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
-template <typename Key, typename Value>
-class ThreadSafeMap {
- public:
- using MapType = std::map<Key, Value>;
- using IteratorType = typename MapType::iterator;
-
- void insert(const Key& key, const Value& value) {
- std::unique_lock lock(mutex_);
- map_[key] = value;
- }
-
- std::optional<Value> get(const Key& key) {
- std::shared_lock lock(mutex_);
- auto it = map_.find(key);
- if (it != map_.end()) {
- return it->second;
- }
- return std::nullopt;
- }
-
- bool exists(const Key& key) {
- std::shared_lock lock(mutex_);
- return map_.count(key) > 0;
- }
-
- IteratorType begin() { return map_mirror_.begin(); }
-
- IteratorType end() { return map_mirror_.end(); }
-
- ThreadSafeMap& mirror() {
- std::shared_lock lock(mutex_);
- map_mirror_ = map_;
- return *this;
- }
-
- private:
- MapType map_mirror_;
- MapType map_;
- mutable std::shared_mutex mutex_;
-};
-
class GPGFRONTEND_CORE_EXPORT CacheManager
- : public QObject,
- public SingletonFunctionObject<CacheManager> {
- Q_OBJECT
+ : public SingletonFunctionObject<CacheManager> {
public:
- CacheManager(int channel = SingletonFunctionObject::GetDefaultChannel());
-
- void SaveCache(std::string key, const nlohmann::json& value,
- bool flush = false);
-
- nlohmann::json LoadCache(std::string key);
-
- nlohmann::json LoadCache(std::string key, nlohmann::json default_value);
+ /**
+ * @brief Construct a new Cache Manager object
+ *
+ * @param channel
+ */
+ explicit CacheManager(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ /**
+ * @brief Destroy the Cache Manager object
+ *
+ */
+ ~CacheManager() override;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ void SaveCache(const QString& key, QString value);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ * @param flush
+ */
+ void SaveDurableCache(const QString& key, const QJsonDocument& value,
+ bool flush = false);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ auto LoadCache(const QString& key) -> QString;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key) -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return auto
+ */
+ void ResetCache(const QString& key);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return true
+ * @return false
+ */
+ auto ResetDurableCache(const QString& key) -> bool;
private:
- std::string get_data_object_key(std::string key);
-
- nlohmann::json load_cache_storage(std::string key,
- nlohmann::json default_value);
-
- void load_all_cache_storage();
-
- void flush_cache_storage();
-
- void register_cache_key(std::string key);
-
- ThreadSafeMap<std::string, nlohmann::json> cache_storage_;
- nlohmann::json key_storage_;
- QTimer* m_timer_;
- const std::string drk_key_ = "__cache_manage_data_register_key_list";
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif
diff --git a/src/core/function/CharsetOperator.cpp b/src/core/function/CharsetOperator.cpp
deleted file mode 100644
index 72c5e72b..00000000
--- a/src/core/function/CharsetOperator.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/function/CharsetOperator.h"
-
-#include <spdlog/spdlog.h>
-#include <unicode/ucnv.h>
-#include <unicode/ucsdet.h>
-#include <unicode/ustring.h>
-#include <unicode/utypes.h>
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
- const std::string &buffer) {
- const UCharsetMatch *ucm;
- UErrorCode status = U_ZERO_ERROR;
- UCharsetDetector *csd = ucsdet_open(&status);
-
- status = U_ZERO_ERROR;
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open charset detector: {}", u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- SPDLOG_DEBUG("detecting charset buffer: {} bytes", buffer.size());
-
- status = U_ZERO_ERROR;
- ucsdet_setText(csd, buffer.data(), buffer.size(), &status);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to set text to charset detector: {}",
- u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- status = U_ZERO_ERROR;
- ucm = ucsdet_detect(csd, &status);
-
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *name = ucsdet_getName(ucm, &status);
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- int confidence = ucsdet_getConfidence(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *language = ucsdet_getLanguage(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", confidence};
-
- SPDLOG_DEBUG("Detected charset: {} {} {}", name, language, confidence);
- return {name, language, confidence};
-}
-
-bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
- std::string &out_buffer,
- std::string from_charset_name) {
- UErrorCode status = U_ZERO_ERROR;
- const auto from_encode = std::string("utf-8");
- const auto to_encode = from_charset_name;
-
- SPDLOG_DEBUG("Converting buffer: {}", buffer.size());
-
- // test if the charset is supported
- UConverter *conv = ucnv_open(from_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, from encode: {}",
- u_errorName(status), from_encode);
- return false;
- }
-
- // test if the charset is supported
- conv = ucnv_open(to_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, to encode: {}",
- u_errorName(status), to_encode);
- return false;
- }
-
- status = U_ZERO_ERROR;
- int32_t target_limit = 0, target_capacity = 0;
-
- target_capacity =
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), nullptr,
- target_limit, buffer.data(), buffer.size(), &status);
-
- if (status == U_BUFFER_OVERFLOW_ERROR) {
- status = U_ZERO_ERROR;
- out_buffer.clear();
- out_buffer.resize(target_capacity);
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), out_buffer.data(),
- out_buffer.size(), buffer.data(), buffer.size(), &status);
- }
-
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to convert to utf-8: {}", u_errorName(status));
- return false;
- }
-
- SPDLOG_DEBUG("converted buffer: {} bytes", out_buffer.size());
- return true;
-} \ No newline at end of file
diff --git a/src/core/function/CoreSignalStation.cpp b/src/core/function/CoreSignalStation.cpp
index f78d417b..8cb84743 100644
--- a/src/core/function/CoreSignalStation.cpp
+++ b/src/core/function/CoreSignalStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,11 +29,12 @@
#include "core/function/CoreSignalStation.h"
std::unique_ptr<GpgFrontend::CoreSignalStation>
- GpgFrontend::CoreSignalStation::_instance = nullptr;
+ GpgFrontend::CoreSignalStation::instance = nullptr;
-GpgFrontend::CoreSignalStation* GpgFrontend::CoreSignalStation::GetInstance() {
- if (_instance == nullptr) {
- _instance = std::make_unique<CoreSignalStation>();
+auto GpgFrontend::CoreSignalStation::GetInstance()
+ -> GpgFrontend::CoreSignalStation* {
+ if (instance == nullptr) {
+ instance = std::make_unique<CoreSignalStation>();
}
- return _instance.get();
+ return instance.get();
}
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
index 7497cab7..e0a11fa3 100644
--- a/src/core/function/CoreSignalStation.h
+++ b/src/core/function/CoreSignalStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,27 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CORESIGNALSTATION_H
-#define GPGFRONTEND_CORESIGNALSTATION_H
+#pragma once
#include "core/GpgFrontendCore.h"
namespace GpgFrontend {
+class GpgPassphraseContext;
+
/**
* @brief
*
*/
class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
Q_OBJECT
- static std::unique_ptr<CoreSignalStation> _instance;
+ static std::unique_ptr<CoreSignalStation> instance;
public:
/**
@@ -47,7 +48,7 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
*
* @return SignalStation*
*/
- static CoreSignalStation* GetInstance();
+ static auto GetInstance() -> CoreSignalStation*;
signals:
@@ -55,15 +56,25 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
* @brief
*
*/
- void SignalUserInputPassphraseDone(QString passparase);
+ void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
- void SignalNeedUserInputPassphrase();
+ void SignalBadGnupgEnv(QString);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalGoodGnupgEnv();
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CORESIGNALSTATION_H
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
index 180cef30..cbf21f8e 100644
--- a/src/core/function/DataObjectOperator.cpp
+++ b/src/core/function/DataObjectOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,143 +30,131 @@
#include <qt-aes/qaesencryption.h>
-#include <boost/date_time.hpp>
-
-#include "core/function/FileOperator.h"
#include "core/function/PassphraseGenerator.h"
+#include "core/utils/IOUtils.h"
+
+namespace GpgFrontend {
-void GpgFrontend::DataObjectOperator::init_app_secure_key() {
- SPDLOG_DEBUG("initializing application secure key");
- FileOperator::WriteFileStd(app_secure_key_path_,
- PassphraseGenerator::GetInstance().Generate(256));
- std::filesystem::permissions(
- app_secure_key_path_,
- std::filesystem::perms::owner_read | std::filesystem::perms::owner_write);
+void DataObjectOperator::init_app_secure_key() {
+ GF_CORE_LOG_INFO("initializing application secure key...");
+ WriteFile(app_secure_key_path_,
+ PassphraseGenerator::GetInstance().Generate(256).toUtf8());
+ QFile::setPermissions(app_secure_key_path_,
+ QFileDevice::ReadOwner | QFileDevice::WriteOwner);
}
-GpgFrontend::DataObjectOperator::DataObjectOperator(int channel)
+DataObjectOperator::DataObjectOperator(int channel)
: SingletonFunctionObject<DataObjectOperator>(channel) {
- if (!is_directory(app_secure_path_)) create_directory(app_secure_path_);
-
- if (!exists(app_secure_key_path_)) {
- init_app_secure_key();
+ if (!QDir(app_secure_path_).exists()) QDir(app_secure_path_).mkpath(".");
+ if (!QFileInfo(app_secure_key_path_).exists()) init_app_secure_key();
+
+ QByteArray key;
+ if (!ReadFile(app_secure_key_path_, key)) {
+ GF_CORE_LOG_ERROR("failed to read app secure key file: {}",
+ app_secure_key_path_);
+ // unsafe mode
+ key = {};
}
- std::string key;
- if (!FileOperator::ReadFileStd(app_secure_key_path_.u8string(), key)) {
- SPDLOG_ERROR("failed to read app secure key file: {}",
- app_secure_key_path_.u8string());
- throw std::runtime_error("failed to read app secure key file");
- }
- hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key),
- QCryptographicHash::Sha256);
- SPDLOG_DEBUG("app secure key loaded {} bytes", hash_key_.size());
+ hash_key_ = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_);
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
}
-std::string GpgFrontend::DataObjectOperator::SaveDataObj(
- const std::string& _key, const nlohmann::json& value) {
- std::string _hash_obj_key = {};
- if (_key.empty()) {
- _hash_obj_key =
+auto DataObjectOperator::SaveDataObj(const QString& key,
+ const QJsonDocument& value) -> QString {
+ QByteArray hash_obj_key;
+ if (key.isEmpty()) {
+ hash_obj_key =
QCryptographicHash::hash(
- hash_key_ + QByteArray::fromStdString(
- PassphraseGenerator::GetInstance().Generate(32) +
- to_iso_extended_string(
- boost::posix_time::second_clock::local_time())),
+ hash_key_ +
+ PassphraseGenerator::GetInstance().Generate(32).toUtf8() +
+ QDateTime::currentDateTime().toString().toUtf8(),
QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ .toHex();
} else {
- _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
}
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded =
- encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_);
-
- SPDLOG_DEBUG("saving data object {} to {} , size: {} bytes", _hash_obj_key,
- obj_path.u8string(), encoded.size());
-
- FileOperator::WriteFileStd(obj_path.u8string(), encoded.toStdString());
+ const auto target_obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ auto encoded_data =
+ QAESEncryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO)
+ .encode(value.toJson(), hash_key_);
+ GF_CORE_LOG_TRACE("saving data object {} to disk {} , size: {} bytes",
+ hash_obj_key, target_obj_path, encoded_data.size());
+
+ // recreate if not exists
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
- return _key.empty() ? _hash_obj_key : std::string();
+ if (!WriteFile(target_obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to write data object to disk: {}", key);
+ }
+ return key.isEmpty() ? hash_obj_key : QString();
}
-std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
- const std::string& _key) {
+auto DataObjectOperator::GetDataObject(const QString& key)
+ -> std::optional<QJsonDocument> {
try {
- SPDLOG_DEBUG("get data object {}", _key);
- auto _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
-
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- if (!std::filesystem::exists(obj_path)) {
- SPDLOG_ERROR("data object not found :{}", _key);
+ GF_CORE_LOG_TRACE("try to get data object from disk, key: {}", key);
+ auto hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
+
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ if (!QFileInfo(obj_path).exists()) {
+ GF_CORE_LOG_WARN("data object not found from disk, key: {}", key);
return {};
}
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) {
- SPDLOG_ERROR("failed to read data object: {}", _key);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to read data object from disk, key: {}", key);
return {};
}
- SPDLOG_DEBUG("data object found {}", _key);
-
- auto encoded = QByteArray::fromStdString(buffer);
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- SPDLOG_DEBUG("decrypting data object {} , hash key size: {}",
- encoded.size(), hash_key_.size());
-
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
-
- SPDLOG_DEBUG("data object decoded: {}", _key);
-
- return nlohmann::json::parse(decoded.toStdString());
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
+ GF_CORE_LOG_TRACE("data object has been decoded, key: {}, data: {}", key,
+ decoded_data);
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
- SPDLOG_ERROR("failed to get data object: {}", _key);
+ GF_CORE_LOG_ERROR("failed to get data object, caught exception: {}", key);
return {};
}
}
-std::optional<nlohmann::json>
-GpgFrontend::DataObjectOperator::GetDataObjectByRef(const std::string& _ref) {
+auto DataObjectOperator::GetDataObjectByRef(const QString& _ref)
+ -> std::optional<QJsonDocument> {
if (_ref.size() != 64) return {};
try {
- const auto& _hash_obj_key = _ref;
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+ const auto& hash_obj_key = _ref;
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
- if (!std::filesystem::exists(obj_path)) return {};
+ if (!QFileInfo(obj_path).exists()) return {};
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) return {};
- auto encoded = QByteArray::fromStdString(buffer);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) return {};
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
- return nlohmann::json::parse(decoded.toStdString());
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
return {};
}
}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h
index ae5dc62c..fedbd905 100644
--- a/src/core/function/DataObjectOperator.h
+++ b/src/core/function/DataObjectOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H
-#define GPGFRONTEND_DATAOBJECTOPERATOR_H
+#pragma once
+
+#include <optional>
-#include "core/GpgFunctionObject.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -45,11 +46,11 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
explicit DataObjectOperator(
int channel = SingletonFunctionObject::GetDefaultChannel());
- std::string SaveDataObj(const std::string &_key, const nlohmann::json &value);
+ auto SaveDataObj(const QString &_key, const QJsonDocument &value) -> QString;
- std::optional<nlohmann::json> GetDataObject(const std::string &_key);
+ auto GetDataObject(const QString &_key) -> std::optional<QJsonDocument>;
- std::optional<nlohmann::json> GetDataObjectByRef(const std::string &_ref);
+ auto GetDataObjectByRef(const QString &_ref) -> std::optional<QJsonDocument>;
private:
/**
@@ -60,21 +61,16 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
GlobalSettingStation &global_setting_station_ =
GlobalSettingStation::GetInstance(); ///< GlobalSettingStation
- std::filesystem::path app_secure_path_ =
- global_setting_station_.GetAppConfigPath() /
- "secure"; ///< Where sensitive information is stored
- std::filesystem::path app_secure_key_path_ =
- app_secure_path_ / "app.key"; ///< Where the key of data object is stored
- std::filesystem::path app_data_objs_path_ =
- global_setting_station_.GetAppDataPath() / "data_objs"; ///< Where data
- ///< object is
- ///< stored
+ QString app_secure_path_ =
+ global_setting_station_.GetAppDataPath() +
+ "/secure"; ///< Where sensitive information is stored
+ QString app_secure_key_path_ =
+ app_secure_path_ +
+ "/app.key"; ///< Where the key of data object is stored
+ QString app_data_objs_path_ =
+ global_setting_station_.GetAppDataPath() + "/data_objs";
- std::random_device rd_; ///< Random device
- std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
- QByteArray hash_key_; ///< Hash key
+ QByteArray hash_key_; ///< Hash key
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_DATAOBJECTOPERATOR_H
diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp
deleted file mode 100644
index 41552246..00000000
--- a/src/core/function/FileOperator.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "FileOperator.h"
-
-bool GpgFrontend::FileOperator::ReadFile(const QString& file_name,
- QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- data = file.readAll();
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::WriteFile(const QString& file_name,
- const QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::WriteOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- file.write(data);
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::ReadFileStd(
- const std::filesystem::path& file_name, std::string& data) {
- QByteArray byte_data;
-#ifdef WINDOWS
- bool res = ReadFile(QString::fromStdU16String(file_name.u16string()).toUtf8(),
- byte_data);
-#else
- bool res = ReadFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- byte_data);
-#endif
- data = byte_data.toStdString();
- return res;
-}
-
-bool GpgFrontend::FileOperator::WriteFileStd(
- const std::filesystem::path& file_name, const std::string& data) {
- return WriteFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- QByteArray::fromStdString(data));
-}
-
-std::string GpgFrontend::FileOperator::CalculateHash(
- const std::filesystem::path& file_path) {
- // Returns empty QByteArray() on failure.
- QFileInfo info(QString::fromStdString(file_path.string()));
- std::stringstream ss;
-
- if (info.isFile() && info.isReadable()) {
- ss << "[#] " << _("File Hash Information") << std::endl;
- ss << " " << _("filename") << _(": ")
- << file_path.filename().u8string().c_str() << std::endl;
-
- QFile f(info.filePath());
- if (f.open(QFile::ReadOnly)) {
- // read all data
- auto buffer = f.readAll();
- ss << " " << _("file size(bytes)") << _(": ") << buffer.size()
- << std::endl;
-
- // md5
- auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
- hash_md5.addData(buffer);
- auto md5 = hash_md5.result().toHex().toStdString();
- SPDLOG_DEBUG("md5 {}", md5);
- ss << " "
- << "md5" << _(": ") << md5 << std::endl;
-
- // sha1
- auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
- hash_sha1.addData(buffer);
- auto sha1 = hash_sha1.result().toHex().toStdString();
- SPDLOG_DEBUG("sha1 {}", sha1);
- ss << " "
- << "sha1" << _(": ") << sha1 << std::endl;
-
- // sha1
- auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
- hash_sha256.addData(buffer);
- auto sha256 = hash_sha256.result().toHex().toStdString();
- SPDLOG_DEBUG("sha256 {}", sha256);
- ss << " "
- << "sha256" << _(": ") << sha256 << std::endl;
-
- ss << std::endl;
- }
- } else {
- ss << "[#] " << _("Error in Calculating File Hash ") << std::endl;
- }
-
- return ss.str();
-}
diff --git a/src/core/function/FileOperator.h b/src/core/function/FileOperator.h
deleted file mode 100644
index a727b1de..00000000
--- a/src/core/function/FileOperator.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_FILEOPERATOR_H
-#define GPGFRONTEND_FILEOPERATOR_H
-
-#include "core/GpgFrontendCore.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief provides file operations
- *
- */
-class GPGFRONTEND_CORE_EXPORT FileOperator {
- public:
- /**
- * @brief read file content using std struct
- *
- *
- * @param file_name file name
- * @param data data read from file
- * @return
- */
- static bool ReadFileStd(const std::filesystem::path &file_name,
- std::string &data);
-
- /**
- * @brief write file content using std struct
- *
- * @param file_name file name
- * @param data data to write to file
- * @return
- */
- static bool WriteFileStd(const std::filesystem::path &file_name,
- const std::string &data);
-
- /**
- * @brief read file content
- *
- * @param file_name file name
- * @param data data read from file
- * @return true if success
- * @return false if failed
- */
- static bool ReadFile(const QString &file_name, QByteArray &data);
-
- /**
- * @brief write file content
- *
- * @param file_name file name
- * @param data data to write to file
- * @return true if success
- * @return false if failed
- */
- static bool WriteFile(const QString &file_name, const QByteArray &data);
-
- /**
- * calculate the hash of a file
- * @param file_path
- * @return
- */
- static std::string CalculateHash(const std::filesystem::path &file_path);
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_FILEOPERATOR_H
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
index 6b743268..6969c15a 100644
--- a/src/core/function/GlobalSettingStation.cpp
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,136 +28,148 @@
#include "GlobalSettingStation.h"
-#include "core/function/FileOperator.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/FilesystemUtils.h"
-void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept {
- using namespace libconfig;
- try {
- ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("updated ui configuration successfully written to {}",
- ui_config_path_.u8string());
+namespace GpgFrontend {
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while writing ui configuration file: {}",
- ui_config_path_.u8string());
- }
-}
+class GlobalSettingStation::Impl {
+ public:
+ /**
+ * @brief Construct a new Global Setting Station object
+ *
+ */
+ explicit Impl() noexcept {
+ GF_CORE_LOG_INFO("app path: {}", GetAppDir());
+ GF_CORE_LOG_INFO("app working path: {}", working_path_);
-GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
- : SingletonFunctionObject<GlobalSettingStation>(channel) {
- using namespace std::filesystem;
- using namespace libconfig;
-
- SPDLOG_INFO("app path: {}", app_path_.u8string());
- SPDLOG_INFO("app configure path: {}", app_configure_path_.u8string());
- SPDLOG_INFO("app data path: {}", app_data_path_.u8string());
- SPDLOG_INFO("app log path: {}", app_log_path_.u8string());
- SPDLOG_INFO("app locale path: {}", app_locale_path_.u8string());
- SPDLOG_INFO("app conf path: {}", ui_config_path_.u8string());
-
- SPDLOG_INFO("app log files total size: {}", GetLogFilesSize());
- SPDLOG_INFO("app data objects files total size: {}",
- GetDataObjectsFilesSize());
-
- if (!is_directory(app_configure_path_)) create_directory(app_configure_path_);
- if (!is_directory(app_data_path_)) create_directory(app_data_path_);
- if (!is_directory(app_log_path_)) create_directory(app_log_path_);
- if (!is_directory(ui_config_dir_path_)) create_directory(ui_config_dir_path_);
-
- if (!exists(ui_config_path_)) {
- try {
- this->ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully written to {}",
- ui_config_path_.u8string());
-
- } catch (const FileIOException &fioex) {
- SPDLOG_DEBUG(
- "i/o error while writing UserInterface configuration file {}",
- ui_config_path_.u8string());
- }
- } else {
- try {
- this->ui_cfg_.readFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully read from {}",
- ui_config_path_.u8string());
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while reading UserInterface configure file");
- } catch (const ParseException &pex) {
- SPDLOG_ERROR("parse error at {} : {} - {}", pex.getFile(), pex.getLine(),
- pex.getError());
+ auto portable_file_path = working_path_ + "/PORTABLE.txt";
+ if (QFileInfo(portable_file_path).exists()) {
+ GF_CORE_LOG_INFO(
+ "dectected portable mode, reconfiguring config and data path...");
+ Module::UpsertRTValue("core", "env.state.portable", 1);
+
+ app_data_path_ = working_path_;
+ app_log_path_ = app_data_path_ + "/logs";
+ app_data_objs_path_ = app_data_path_ + "/data_objs";
+
+ portable_mode_ = true;
}
+
+ GF_CORE_LOG_INFO("app data path: {}", app_data_path_);
+ GF_CORE_LOG_INFO("app log path: {}", app_log_path_);
+
+ GF_CORE_LOG_DEBUG("app log files total size: {}", GetLogFilesSize());
+ GF_CORE_LOG_DEBUG("app data objects files total size: {}",
+ GetDataObjectsFilesSize());
+
+ if (!QDir(app_data_path_).exists()) QDir(app_data_path_).mkpath(".");
+ if (!QDir(app_log_path_).exists()) QDir(app_log_path_).mkpath(".");
}
-}
-libconfig::Setting &
-GpgFrontend::GlobalSettingStation::GetUISettings() noexcept {
- return ui_cfg_.getRoot();
-}
+ [[nodiscard]] auto GetSettings() -> QSettings {
+ if (!portable_mode_) return QSettings();
+ return {app_portable_config_path_, QSettings::IniFormat};
+ }
-void GpgFrontend::GlobalSettingStation::init_app_secure_key() {}
+ [[nodiscard]] auto GetLogFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(GetFileSizeByPath(app_log_path_, "*.log"));
+ }
-int64_t GpgFrontend::GlobalSettingStation::get_files_size_at_path(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
- QFileInfoList fileList = dir.entryInfoList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
- qint64 totalSize = 0;
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(
+ GetFileSizeByPath(app_data_objs_path_, "*"));
+ }
- for (const QFileInfo &fileInfo : fileList) {
- totalSize += fileInfo.size();
+ void ClearAllLogFiles() const {
+ DeleteAllFilesByPattern(app_log_path_, "*.log");
+ }
+
+ void ClearAllDataObjects() const {
+ DeleteAllFilesByPattern(app_data_objs_path_, "*");
+ }
+
+ /**
+ * @brief Get the App Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDir() const -> QString {
+ return QCoreApplication::applicationDirPath();
}
- return totalSize;
-}
-std::string GpgFrontend::GlobalSettingStation::get_human_readable_size(
- int64_t size) const {
- double num = size;
- QStringList list;
- list << "KB"
- << "MB"
- << "GB"
- << "TB";
-
- QStringListIterator i(list);
- QString unit("bytes");
-
- while (num >= 1024.0 && i.hasNext()) {
- unit = i.next();
- num /= 1024.0;
+ /**
+ * @brief Get the App Data Path object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDataPath() const -> QString {
+ return app_data_path_;
}
- return (QString().setNum(num, 'f', 2) + " " + unit).toStdString();
+
+ /**
+ * @brief Get the Log Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetLogDir() const -> QString { return app_log_path_; }
+
+ private:
+ QString working_path_ = QDir::currentPath();
+
+ QString app_data_path_ = QString{QStandardPaths::writableLocation(
+ QStandardPaths::AppLocalDataLocation)}; ///< Program Data Location
+
+ QString app_log_path_ = app_data_path_ + "/logs"; ///< Program Data Location
+
+ QString app_data_objs_path_ =
+ app_data_path_ + "/data_objs"; ///< Object storage path
+
+ bool portable_mode_ = false; ///<
+ QString app_portable_config_path_ =
+ working_path_ + "/config.ini"; ///< take effect only in portable mode
+
+ /**
+ * @brief
+ *
+ */
+ void init_app_secure_key() {}
+};
+
+GlobalSettingStation::GlobalSettingStation(int channel) noexcept
+ : SingletonFunctionObject<GlobalSettingStation>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+
+auto GlobalSettingStation::GetSettings() const -> QSettings {
+ return p_->GetSettings();
}
-std::string GpgFrontend::GlobalSettingStation::GetLogFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_log_path_, "*.log"));
+auto GlobalSettingStation::GetAppDir() const -> QString {
+ return p_->GetAppDir();
}
-std::string GpgFrontend::GlobalSettingStation::GetDataObjectsFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_data_objs_path_, "*"));
+auto GlobalSettingStation::GetAppDataPath() const -> QString {
+ return p_->GetAppDataPath();
}
-void GpgFrontend::GlobalSettingStation::ClearAllLogFiles() const {
- delete_all_files(app_log_path_, "*.log");
+[[nodiscard]] auto GlobalSettingStation::GetLogDir() const -> QString {
+ return p_->GetLogDir();
}
-void GpgFrontend::GlobalSettingStation::ClearAllDataObjects() const {
- delete_all_files(app_data_objs_path_, "*");
+auto GlobalSettingStation::GetLogFilesSize() const -> QString {
+ return p_->GetLogFilesSize();
}
-void GpgFrontend::GlobalSettingStation::delete_all_files(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
+auto GlobalSettingStation::GetDataObjectsFilesSize() const -> QString {
+ return p_->GetDataObjectsFilesSize();
+}
- // 使用name filters来只选取以.log结尾的文件
- QStringList logFiles = dir.entryList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
+void GlobalSettingStation::ClearAllLogFiles() const { p_->ClearAllLogFiles(); }
- // 遍历并删除所有符合条件的文件
- for (const auto &file : logFiles) {
- QFile::remove(dir.absoluteFilePath(file));
- }
+void GlobalSettingStation::ClearAllDataObjects() const {
+ p_->ClearAllDataObjects();
}
-GpgFrontend::GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h
index 80780f4b..85ac57b4 100644
--- a/src/core/function/GlobalSettingStation.h
+++ b/src/core/function/GlobalSettingStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,24 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
-#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+#pragma once
-#include <filesystem>
-
-#include "GpgFrontendBuildInstallInfo.h"
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
/**
- * @brief
+ * @class GlobalSettingStation
+ * @brief Singleton class for managing global settings in the application.
*
+ * This class handles reading and writing of global settings, as well as
+ * managing application directories and resource paths.
*/
class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
: public SingletonFunctionObject<GlobalSettingStation> {
@@ -58,179 +56,60 @@ class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
~GlobalSettingStation() noexcept override;
/**
- * @brief
- *
- * @return libconfig::Setting&
- */
- libconfig::Setting &GetUISettings() noexcept;
-
- /**
- * @brief
+ * @brief Get the Settings object
*
- * @return libconfig::Setting&
+ * @return QSettings
*/
- template <typename T>
- T LookupSettings(std::string path, T default_value) noexcept {
- T value = default_value;
- try {
- value = static_cast<T>(GetUISettings().lookup(path));
- } catch (...) {
- SPDLOG_WARN("setting not found: {}", path);
- }
- return value;
- }
+ [[nodiscard]] auto GetSettings() const -> QSettings;
/**
* @brief Get the App Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetAppDir() const { return app_path_; }
-
- [[nodiscard]] std::filesystem::path GetAppDataPath() const {
- return app_data_path_;
- }
+ [[nodiscard]] auto GetAppDir() const -> QString;
/**
- * @brief Get the Log Dir object
- *
- * @return std::filesystem::path
+ * @brief Gets the application data directory.
+ * @return Path to the application data directory.
*/
- [[nodiscard]] std::filesystem::path GetLogDir() const {
- return app_log_path_;
- }
+ [[nodiscard]] auto GetAppDataPath() const -> QString;
/**
- * @brief Get the Standalone Database Dir object
- *
- * @return std::filesystem::path
- */
- [[nodiscard]] std::filesystem::path GetStandaloneDatabaseDir() const {
- auto db_path = app_configure_path_ / "db";
- if (!std::filesystem::exists(db_path)) {
- std::filesystem::create_directory(db_path);
- }
- return db_path;
- }
-
- [[nodiscard]] std::filesystem::path GetAppConfigPath() const {
- return app_configure_path_;
- }
-
- /**
- * @brief Get the Standalone Gpg Bin Dir object
+ * @brief Get the Log Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetStandaloneGpgBinDir() const {
- return app_resource_path_ / "gpg1.4" / "gpg";
- }
+ [[nodiscard]] auto GetLogDir() const -> QString;
/**
- * @brief Get the Locale Dir object
+ * @brief Get the Log Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetLocaleDir() const {
- return app_locale_path_;
- }
+ [[nodiscard]] auto GetLogFilesSize() const -> QString;
/**
- * @brief Get the Resource Dir object
+ * @brief Get the Data Objects Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetResourceDir() const {
- return app_resource_path_;
- }
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString;
/**
- * @brief Get the Certs Dir object
+ * @brief clear all log files
*
- * @return std::filesystem::path
*/
- [[nodiscard]] std::filesystem::path GetCertsDir() const {
- return app_resource_path_ / "certs";
- }
-
- [[nodiscard]] std::string GetLogFilesSize() const;
-
- [[nodiscard]] std::string GetDataObjectsFilesSize() const;
-
void ClearAllLogFiles() const;
- void ClearAllDataObjects() const;
-
/**
- * @brief sync the settings to the file
+ * @brief clear all data objects
*
*/
- void SyncSettings() noexcept;
+ void ClearAllDataObjects() const;
private:
- std::filesystem::path app_path_ = QCoreApplication::applicationDirPath()
- .toStdString(); ///< Program Location
- std::filesystem::path app_data_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
- .toStdString(); ///< Program Data Location
- std::filesystem::path app_log_path_ =
- app_data_path_ / "logs"; ///< Program Data Location
- std::filesystem::path app_data_objs_path_ =
- app_data_path_ / "data_objs"; ///< Object storage path
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_resource_path_ =
- std::filesystem::path(APP_LOCALSTATE_PATH) /
- "gpgfrontend"; ///< Program Data Location
-#else
- std::filesystem::path app_resource_path_ =
- RESOURCE_DIR_BOOST_PATH(app_path_); ///< Program Data Location
-#endif
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_locale_path_ =
- std::string(APP_LOCALE_PATH); ///< Program Data Location
-#else
- std::filesystem::path app_locale_path_ =
- app_resource_path_ / "locales"; ///< Program Data Location
-#endif
-
- std::filesystem::path app_configure_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
- .toStdString(); ///< Program Configure Location
- std::filesystem::path ui_config_dir_path_ =
- app_configure_path_ / "conf"; ///< Configure File Directory Location
- std::filesystem::path ui_config_path_ =
- ui_config_dir_path_ / "main.cfg"; ///< Main Configure File Location
-
- libconfig::Config ui_cfg_; ///< UI Configure File
-
- /**
- * @brief
- *
- */
- void init_app_secure_key();
-
- /**
- * @brief
- *
- */
- int64_t get_files_size_at_path(std::filesystem::path path,
- std::string filename_pattern) const;
-
- /**
- * @brief
- *
- */
- std::string get_human_readable_size(int64_t size) const;
-
- /**
- * @brief
- *
- */
- void delete_all_files(std::filesystem::path path,
- std::string filename_pattern) const;
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
index 5c917ab8..d185b0ef 100644
--- a/src/core/function/KeyPackageOperator.cpp
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,92 +28,124 @@
#include "KeyPackageOperator.h"
-#include "FileOperator.h"
-#include "function/PassphraseGenerator.h"
-#include "function/gpg/GpgKeyGetter.h"
-#include "function/gpg/GpgKeyImportExporter.h"
-#include "qt-aes/qaesencryption.h"
+#include <qt-aes/qaesencryption.h>
+
+#include "core/function/KeyPackageOperator.h"
+#include "core/function/PassphraseGenerator.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-bool KeyPackageOperator::GeneratePassphrase(
- const std::filesystem::path& phrase_path, std::string& phrase) {
+auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path,
+ QString& phrase) -> bool {
phrase = PassphraseGenerator::GetInstance().Generate(256);
- SPDLOG_DEBUG("generated passphrase: {} bytes", phrase.size());
- return FileOperator::WriteFileStd(phrase_path, phrase);
+ GF_CORE_LOG_DEBUG("generated passphrase: {} bytes", phrase.size());
+ return WriteFile(phrase_path, phrase.toUtf8());
}
-bool KeyPackageOperator::GenerateKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::string& key_package_name, KeyIdArgsListPtr& key_ids,
- std::string& phrase, bool secret) {
- SPDLOG_DEBUG("generating key package: {}", key_package_name);
-
- ByteArrayPtr key_export_data = nullptr;
- if (!GpgKeyImportExporter::GetInstance().ExportAllKeys(
- key_ids, key_export_data, secret)) {
- SPDLOG_ERROR("failed to export keys");
- return false;
- }
-
- auto key = QByteArray::fromStdString(phrase);
- auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64();
-
- auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded = encryption.encode(data, hash_key);
-
- SPDLOG_DEBUG("writing key package: {}", key_package_name);
- return FileOperator::WriteFileStd(key_package_path, encoded.toStdString());
+void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
+ const QString& key_package_name,
+ const KeyArgsList& keys,
+ QString& phrase, bool secret,
+ const OperationCallback& cb) {
+ GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);
+
+ GpgKeyImportExporter::GetInstance().ExportAllKeys(
+ keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) {
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_LOG_ERROR("export keys error, reason: {}",
+ DescribeGpgErrCode(err).second);
+ cb(-1, data_obj);
+ return;
+ }
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GFBuffer>()) {
+ cb(-1, data_obj);
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+
+ auto data = gf_buffer.ConvertToQByteArray().toBase64();
+ auto hash_key = QCryptographicHash::hash(phrase.toUtf8(),
+ QCryptographicHash::Sha256);
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+ auto encoded_data = encryption.encode(data, hash_key);
+ GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name);
+
+ cb(WriteFile(key_package_path, encoded_data) ? 0 : -1,
+ TransferParams());
+ return;
+ });
}
-bool KeyPackageOperator::ImportKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::filesystem::path& phrase_path,
- GpgFrontend::GpgImportInformation& import_info) {
- SPDLOG_DEBUG("importing key package: {]", key_package_path.u8string());
-
- std::string encrypted_data;
- FileOperator::ReadFileStd(key_package_path, encrypted_data);
-
- if (encrypted_data.empty()) {
- SPDLOG_ERROR("failed to read key package: {}", key_package_path.u8string());
- return false;
- };
-
- std::string passphrase;
- FileOperator::ReadFileStd(phrase_path, passphrase);
- SPDLOG_DEBUG("passphrase: {} bytes", passphrase.size());
- if (passphrase.size() != 256) {
- SPDLOG_ERROR("failed to read passphrase: {}", phrase_path.u8string());
- return false;
- }
-
- auto hash_key = QCryptographicHash::hash(
- QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256);
- auto encoded = QByteArray::fromStdString(encrypted_data);
-
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
-
- auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key));
- auto key_data = QByteArray::fromBase64(decoded);
-
- SPDLOG_DEBUG("key data size: {}", key_data.size());
- if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) &&
- !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) {
- return false;
- }
-
- auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString());
- import_info =
- GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr));
- return true;
+void KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
+ const QString& phrase_path,
+ const OperationCallback& cb) {
+ RunOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GFError {
+ GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);
+
+ QByteArray encrypted_data;
+ ReadFile(key_package_path, encrypted_data);
+
+ if (encrypted_data.isEmpty()) {
+ GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
+ return -1;
+ };
+
+ QByteArray passphrase;
+ ReadFile(phrase_path, passphrase);
+ if (passphrase.size() != 256) {
+ GF_CORE_LOG_ERROR("passphrase size mismatch: {}", phrase_path);
+ return -1;
+ }
+
+ auto hash_key =
+ QCryptographicHash::hash(passphrase, QCryptographicHash::Sha256);
+ auto encoded = encrypted_data;
+
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+
+ auto decoded =
+ encryption.removePadding(encryption.decode(encoded, hash_key));
+ auto key_data = QByteArray::fromBase64(decoded);
+ if (!key_data.startsWith(PGP_PUBLIC_KEY_BEGIN) &&
+ !key_data.startsWith(PGP_PRIVATE_KEY_BEGIN)) {
+ return -1;
+ }
+
+ auto import_info_ptr =
+ GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(key_data));
+ if (import_info_ptr == nullptr) return GPG_ERR_NO_DATA;
+
+ auto import_info = *import_info_ptr;
+ data_object->Swap({import_info});
+ return 0;
+ },
+ cb, "import_key_package");
}
-std::string KeyPackageOperator::GenerateKeyPackageName() {
+auto KeyPackageOperator::GenerateKeyPackageName() -> QString {
return generate_key_package_name();
}
+/**
+ * @brief generate key package name
+ *
+ * @return QString key package name
+ */
+auto KeyPackageOperator::generate_key_package_name() -> QString {
+ return QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+}
+
} // namespace GpgFrontend
diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h
index 00b0dbaa..252c7e00 100644
--- a/src/core/function/KeyPackageOperator.h
+++ b/src/core/function/KeyPackageOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPACKAGEOPERATOR_H
-#define GPGFRONTEND_KEYPACKAGEOPERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
@@ -48,15 +47,15 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if passphrase was generated and saved
* @return false if passphrase was not generated and saved
*/
- static bool GeneratePassphrase(const std::filesystem::path &phrase_path,
- std::string &phrase);
+ static auto GeneratePassphrase(const QString &phrase_path, QString &phrase)
+ -> bool;
/**
* @brief generate the name of the key package
*
- * @return std::string name of the key package
+ * @return QString name of the key package
*/
- static std::string GenerateKeyPackageName();
+ static auto GenerateKeyPackageName() -> QString;
/**
* @brief generate key package
@@ -69,10 +68,10 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was generated
* @return false if key package was not generated
*/
- static bool GenerateKeyPackage(const std::filesystem::path &key_package_path,
- const std::string &key_package_name,
- KeyIdArgsListPtr &key_ids, std::string &phrase,
- bool secret);
+ static void GenerateKeyPackage(const QString &key_package_path,
+ const QString &key_package_name,
+ const KeyArgsList &keys, QString &phrase,
+ bool secret, const OperationCallback &cb);
/**
* @brief import key package
@@ -83,25 +82,16 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was imported
* @return false if key package was not imported
*/
- static bool ImportKeyPackage(const std::filesystem::path &key_package_path,
- const std::filesystem::path &phrase_path,
- GpgFrontend::GpgImportInformation &import_info);
+ static void ImportKeyPackage(const QString &key_package_path,
+ const QString &phrase_path,
+ const OperationCallback &cb);
private:
/**
* @brief generate key package name
*
- * @return std::string key package name
+ * @return QString key package name
*/
- static std::string generate_key_package_name() {
- std::random_device rd_; ///< Random device
- auto mt_ = std::mt19937(rd_()); ///< Mersenne twister
-
- std::uniform_int_distribution<int> dist(999, 99999);
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- return file_string.str();
- }
+ static auto generate_key_package_name() -> QString;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_KEYPACKAGEOPERATOR_H
diff --git a/src/core/function/LoggerManager.cpp b/src/core/function/LoggerManager.cpp
new file mode 100644
index 00000000..c7088128
--- /dev/null
+++ b/src/core/function/LoggerManager.cpp
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "LoggerManager.h"
+
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend {
+
+std::shared_ptr<spdlog::logger> LoggerManager::default_logger = nullptr;
+spdlog::level::level_enum LoggerManager::default_log_level =
+ spdlog::level::debug;
+
+LoggerManager::LoggerManager(int channel)
+ : SingletonFunctionObject<LoggerManager>(channel) {
+ spdlog::init_thread_pool(1024, 2);
+ spdlog::flush_every(std::chrono::seconds(5));
+}
+
+LoggerManager::~LoggerManager() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
+
+ if (default_logger) default_logger = nullptr;
+}
+
+auto LoggerManager::GetLogger(const QString& id)
+ -> std::shared_ptr<spdlog::logger> {
+ auto m_it = logger_map_.find(id);
+ if (m_it == logger_map_.end()) return GetDefaultLogger();
+ return m_it->second;
+}
+
+auto LoggerManager::RegisterAsyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>(
+ id.toStdString(), begin(sinks), end(sinks), spdlog::thread_pool());
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ // flush policy
+#ifdef DEBUG
+ logger->flush_on(spdlog::level::trace);
+#else
+ logger->flush_on(spdlog::level::err);
+#endif
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::RegisterSyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ id.toStdString(), begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
+ if (default_logger == nullptr) {
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ "default", begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(default_log_level);
+ spdlog::set_default_logger(logger);
+ default_logger = logger;
+ }
+ return default_logger;
+}
+
+void LoggerManager::SetDefaultLogLevel(spdlog::level::level_enum level) {
+ default_log_level = level;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/LoggerManager.h b/src/core/function/LoggerManager.h
new file mode 100644
index 00000000..78fecc3c
--- /dev/null
+++ b/src/core/function/LoggerManager.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace spdlog {
+class logger;
+}
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT LoggerManager
+ : public SingletonFunctionObject<LoggerManager> {
+ public:
+ explicit LoggerManager(int channel);
+
+ ~LoggerManager() override;
+
+ auto RegisterAsyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto RegisterSyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger>;
+
+ static auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger>;
+
+ static void SetDefaultLogLevel(spdlog::level::level_enum);
+
+ private:
+ static spdlog::level::level_enum default_log_level;
+ static std::shared_ptr<spdlog::logger> default_logger;
+
+ std::map<QString, std::shared_ptr<spdlog::logger>> logger_map_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.cpp b/src/core/function/PassphraseGenerator.cpp
index de963fa1..b7f1e877 100644
--- a/src/core/function/PassphraseGenerator.cpp
+++ b/src/core/function/PassphraseGenerator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,10 +20,30 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "PassphraseGenerator.h"
+
+namespace GpgFrontend {
+
+auto PassphraseGenerator::Generate(int len) -> QString {
+ auto file_string = QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+ static const char kAlphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ QString tmp_str;
+ tmp_str.reserve(len);
+
+ for (int i = 0; i < len; ++i) {
+ tmp_str += kAlphanum[QRandomGenerator::global()->bounded(
+ static_cast<quint32>(sizeof(kAlphanum)))];
+ }
+ return tmp_str;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.h b/src/core/function/PassphraseGenerator.h
index a61356fe..2e5925b6 100644
--- a/src/core/function/PassphraseGenerator.h
+++ b/src/core/function/PassphraseGenerator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_PASSPHRASEGENERATOR_H
-#define GPGFRONTEND_PASSPHRASEGENERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -55,29 +53,13 @@ class GPGFRONTEND_CORE_EXPORT PassphraseGenerator
* @brief generate passphrase
*
* @param len length of the passphrase
- * @return std::string passphrase
+ * @return QString passphrase
*/
- std::string Generate(int len) {
- std::uniform_int_distribution<int> dist(999, 99999);
-
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz";
- std::string tmp_str;
- tmp_str.reserve(len);
-
- for (int i = 0; i < len; ++i) {
- tmp_str += alphanum[dist(mt_) % (sizeof(alphanum) - 1)];
- }
- return tmp_str;
- }
+ auto Generate(int len) -> QString;
+ private:
std::random_device rd_; ///< Random device
std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_PASSPHRASEGENERATOR_H
diff --git a/src/core/function/SecureMemoryAllocator.cpp b/src/core/function/SecureMemoryAllocator.cpp
new file mode 100644
index 00000000..692c36c5
--- /dev/null
+++ b/src/core/function/SecureMemoryAllocator.cpp
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SecureMemoryAllocator.h"
+
+#ifndef MACOS
+#include <mimalloc.h>
+#endif
+
+namespace GpgFrontend {
+
+auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_malloc(size);
+#else
+ auto* addr = malloc(size);
+#endif
+ return addr;
+}
+
+auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_realloc(ptr, size);
+#else
+ auto* addr = realloc(ptr, size);
+#endif
+ return addr;
+}
+
+void SecureMemoryAllocator::Deallocate(void* p) {
+#ifndef MACOS
+ mi_free(p);
+#else
+ free(p);
+#endif
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/SecureMemoryAllocator.h b/src/core/function/SecureMemoryAllocator.h
new file mode 100644
index 00000000..e9f1c1c3
--- /dev/null
+++ b/src/core/function/SecureMemoryAllocator.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT SecureMemoryAllocator {
+ public:
+ static auto Allocate(std::size_t) -> void *;
+
+ static auto Reallocate(void *, std::size_t) -> void *;
+
+ static void Deallocate(void *);
+};
+
+template <typename T>
+struct SecureObjectDeleter {
+ void operator()(T *ptr) {
+ if (ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ }
+ }
+};
+
+template <typename T>
+using SecureUniquePtr = std::unique_ptr<T, SecureObjectDeleter<T>>;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/ChannelObject.cpp b/src/core/function/basic/ChannelObject.cpp
new file mode 100644
index 00000000..18449ddb
--- /dev/null
+++ b/src/core/function/basic/ChannelObject.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "ChannelObject.h"
+
+#include <iostream>
+
+namespace GpgFrontend {
+
+ChannelObject::ChannelObject() noexcept = default;
+
+ChannelObject::ChannelObject(int channel, QString type)
+ : channel_(channel), type_(std::move(type)) {}
+
+#ifdef DEBUG
+ChannelObject::~ChannelObject() noexcept {
+ // using iostream instead of spdlog bacause at this time spdlog may have
+ // already been destroyed.
+ QTextStream(stdout) << "releasing channel object: " << this->type_
+ << Qt::endl;
+}
+#else
+ChannelObject::~ChannelObject() noexcept = default;
+#endif
+
+void ChannelObject::SetChannel(int channel) { this->channel_ = channel; }
+
+auto ChannelObject::GetChannel() const -> int { return channel_; }
+
+auto ChannelObject::GetDefaultChannel() -> int {
+ return kGpgFrontendDefaultChannel;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/ChannelObject.h b/src/core/function/basic/ChannelObject.h
new file mode 100644
index 00000000..27be55c4
--- /dev/null
+++ b/src/core/function/basic/ChannelObject.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgConstants.h"
+#include "core/function/SecureMemoryAllocator.h"
+namespace GpgFrontend {
+
+/**
+ * @brief object which in channel system is called "channel"
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT ChannelObject {
+ public:
+ /**
+ * @brief Construct a new Default Channel Object object
+ *
+ */
+ ChannelObject() noexcept;
+
+ /**
+ * @brief Destroy the Channel Object object
+ *
+ */
+ virtual ~ChannelObject() noexcept;
+
+ /**
+ * @brief Construct a new Channel Object object
+ *
+ * @param channel
+ */
+ explicit ChannelObject(int channel, QString type);
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int;
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int;
+
+ /**
+ * @brief Set the Channel object
+ *
+ * @param channel
+ */
+ void SetChannel(int channel);
+
+ private:
+ int channel_ = kGpgFrontendDefaultChannel; ///< The channel id
+ QString type_;
+};
+
+template <typename Derived>
+auto ConvertToChannelObjectPtr(
+ std::unique_ptr<Derived, SecureObjectDeleter<Derived>> derivedPtr)
+ -> std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>> {
+ static_assert(std::is_base_of_v<ChannelObject, Derived>,
+ "Derived must be a subclass of ChannelObject");
+
+ ChannelObject* base_ptr = derivedPtr.release();
+ return std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>>(
+ base_ptr);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.cpp b/src/core/function/basic/GpgFunctionObject.cpp
new file mode 100644
index 00000000..e9e444f1
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFunctionObject.h"
+
+#include <map>
+#include <mutex>
+#include <typeinfo>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/ChannelObject.h"
+
+struct FunctionObjectTypeLockInfo {
+ std::map<int, std::mutex> channel_lock_map;
+ std::mutex type_lock;
+};
+
+std::mutex g_function_object_mutex_map_lock;
+std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
+
+namespace GpgFrontend {
+auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.channel_lock_map[channel];
+}
+
+auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.type_lock;
+}
+
+/**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+auto GetChannelObjectInstance(const std::type_info& type, int channel)
+ -> ChannelObject* {
+ GF_DEFAULT_LOG_TRACE("try to get instance of type: {} at channel: {}",
+ type.name(), channel);
+
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("get singleton storage result, p_storage: {}",
+ static_cast<void*>(p_storage));
+
+ auto* p_pbj =
+ static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
+ GF_DEFAULT_LOG_TRACE("find channel object result, channel {}, p_pbj: {}",
+ channel, static_cast<void*>(p_pbj));
+
+ return p_pbj;
+}
+
+auto CreateChannelObjectInstance(const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object)
+ -> ChannelObject* {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("create channel object, channel {}, type: {}", channel,
+ type.name());
+
+ // do create object of this channel
+ return p_storage->SetObjectInChannel(channel, std::move(channel_object));
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h
new file mode 100644
index 00000000..1ea352b6
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <mutex>
+#include <stdexcept>
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/function/basic/SingletonStorageCollection.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+auto GPGFRONTEND_CORE_EXPORT GetChannelObjectInstance(
+ const std::type_info& type, int channel) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT CreateChannelObjectInstance(
+ const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT
+GetGlobalFunctionObjectTypeLock(const std::type_info& type) -> std::mutex&;
+
+/**
+ * @brief
+ *
+ * @tparam T
+ */
+template <typename T>
+class SingletonFunctionObject : public ChannelObject {
+ public:
+ /**
+ * @brief prohibit copy
+ *
+ */
+ SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
+
+ /**
+ * @brief prohibit copy
+ *
+ * @return SingletonFunctionObject&
+ */
+ auto operator=(const SingletonFunctionObject<T>&)
+ -> SingletonFunctionObject& = delete;
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+ static auto GetInstance(int channel = GpgFrontend::kGpgFrontendDefaultChannel)
+ -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ auto* channel_object = GetChannelObjectInstance(type, channel);
+ if (channel_object == nullptr) {
+ channel_object = CreateChannelObjectInstance(
+ type, channel,
+ ConvertToChannelObjectPtr(SecureCreateUniqueObject<T>(channel)));
+ }
+ return *static_cast<T*>(channel_object);
+ }
+
+ /**
+ * @brief Create a Instance object
+ *
+ * @param channel
+ * @param factory
+ * @return T&
+ */
+ static auto CreateInstance(
+ int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ return *static_cast<T*>(
+ CreateChannelObjectInstance(type, channel, factory()));
+ }
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T&
+ */
+ static void ReleaseChannel(int channel) {
+ SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->ReleaseChannel(channel);
+ }
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int {
+ return ChannelObject::GetDefaultChannel();
+ }
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int {
+ return ChannelObject::GetChannel();
+ }
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ static auto GetAllChannelId() -> std::vector<int> {
+ return SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->GetAllChannelId();
+ }
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(T&&) = delete;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(const T&) = delete;
+
+ /**
+ * @brief
+ *
+ */
+ void operator=(const T&) = delete;
+
+ protected:
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject() = default;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ * @param channel
+ */
+ explicit SingletonFunctionObject(int channel)
+ : ChannelObject(channel, typeid(T).name()) {}
+
+ /**
+ * @brief Destroy the Singleton Function Object object
+ *
+ */
+ virtual ~SingletonFunctionObject() = default;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/basic/SingletonStorage.cpp b/src/core/function/basic/SingletonStorage.cpp
new file mode 100644
index 00000000..eab71e0f
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.cpp
@@ -0,0 +1,133 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorage.h"
+
+#include <shared_mutex>
+
+#include "core/function/basic/ChannelObject.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class SingletonStorage::Impl {
+ public:
+ void ReleaseChannel(int channel) {
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ }
+ if (ins_it != instances_map_.end()) instances_map_.erase(ins_it);
+ }
+
+ auto FindObjectInChannel(int channel) -> GpgFrontend::ChannelObject* {
+ // read instances_map_
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ if (ins_it == instances_map_.end()) {
+ GF_DEFAULT_LOG_TRACE("cannot find channel object, channel: {}",
+ channel);
+ return nullptr;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ auto GetAllChannelId() -> std::vector<int> {
+ std::vector<int> channels;
+ channels.reserve(instances_map_.size());
+ for (const auto& [key, value] : instances_map_) {
+ channels.push_back(key);
+ }
+ return channels;
+ }
+
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ GF_DEFAULT_LOG_TRACE(
+ "set channel object, type: {} in channel: {}, address: {}",
+ typeid(p_obj.get()).name(), channel, static_cast<void*>(p_obj.get()));
+
+ assert(p_obj != nullptr);
+ if (p_obj == nullptr) {
+ GF_DEFAULT_LOG_ERROR(
+ "cannot set a nullptr as a channel obejct of channel: {}", channel);
+ return nullptr;
+ }
+
+ p_obj->SetChannel(channel);
+ auto* raw_obj = p_obj.get();
+
+ {
+ GF_DEFAULT_LOG_TRACE(
+ "register channel object to instances map, "
+ "channel: {}, address: {}",
+ channel, static_cast<void*>(p_obj.get()));
+ std::unique_lock<std::shared_mutex> lock(instances_mutex_);
+ instances_map_[channel] = std::move(p_obj);
+ }
+
+ GF_DEFAULT_LOG_TRACE(
+ "set channel: {} success, current channel object address: {}", channel,
+ static_cast<void*>(raw_obj));
+ return raw_obj;
+ }
+
+ private:
+ std::shared_mutex instances_mutex_; ///< mutex for _instances_map
+ std::map<int, ChannelObjectPtr>
+ instances_map_; ///< map of singleton instances
+};
+
+SingletonStorage::SingletonStorage() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorage::~SingletonStorage() = default;
+
+void SingletonStorage::ReleaseChannel(int channel) {
+ p_->ReleaseChannel(channel);
+}
+
+auto SingletonStorage::FindObjectInChannel(int channel)
+ -> GpgFrontend::ChannelObject* {
+ return p_->FindObjectInChannel(channel);
+}
+
+auto SingletonStorage::GetAllChannelId() -> std::vector<int> {
+ return p_->GetAllChannelId();
+}
+
+auto SingletonStorage::SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ return p_->SetObjectInChannel(channel, std::move(p_obj));
+}
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorage.h b/src/core/function/basic/SingletonStorage.h
new file mode 100644
index 00000000..0ef47443
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+
+class ChannelObject;
+
+using ChannelObjectPtr = SecureUniquePtr<ChannelObject>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorage {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorage() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorage();
+
+ /**
+ * @brief
+ *
+ * @param channel
+ */
+ void ReleaseChannel(int channel);
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T*
+ */
+ auto FindObjectInChannel(int channel) -> ChannelObject*;
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ auto GetAllChannelId() -> std::vector<int>;
+
+ /**
+ * @brief Set a new object in channel object
+ *
+ * @param channel
+ * @param p_obj
+ * @return T*
+ */
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> ChannelObject*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.cpp b/src/core/function/basic/SingletonStorageCollection.cpp
new file mode 100644
index 00000000..c22b5242
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.cpp
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorageCollection.h"
+
+#include <memory>
+#include <shared_mutex>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+SecureUniquePtr<SingletonStorageCollection> global_instance = nullptr;
+
+class SingletonStorageCollection::Impl {
+ public:
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
+ if (force_refresh || global_instance == nullptr) {
+ global_instance = SecureCreateUniqueObject<SingletonStorageCollection>();
+ GF_DEFAULT_LOG_TRACE(
+ "a new global singleton storage collection created, address: {}",
+ static_cast<void*>(global_instance.get()));
+ }
+ return global_instance.get();
+ }
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static void Destroy() { global_instance = nullptr; }
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info& type_id) -> SingletonStorage* {
+ const auto hash = type_id.hash_code();
+
+ while (true) {
+ decltype(storages_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(storages_mutex_);
+ ins_it = storages_map_.find(hash);
+ }
+ if (ins_it == storages_map_.end()) {
+ auto storage = SecureCreateUniqueObject<SingletonStorage>();
+ GF_DEFAULT_LOG_TRACE(
+ "hash: {} created, singleton storage address: {} type_name: {}",
+ hash, static_cast<void*>(storage.get()), type_id.name());
+
+ {
+ std::unique_lock<std::shared_mutex> lock(storages_mutex_);
+ storages_map_.insert({hash, std::move(storage)});
+ }
+ continue;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ private:
+ std::shared_mutex storages_mutex_; ///< mutex for storages_map_
+ std::map<size_t, SingletonStoragePtr> storages_map_;
+};
+
+SingletonStorageCollection::SingletonStorageCollection() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorageCollection::~SingletonStorageCollection() = default;
+
+auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
+ -> GpgFrontend::SingletonStorageCollection* {
+ return Impl::GetInstance(force_refresh);
+}
+
+void SingletonStorageCollection::Destroy() {
+ GF_DEFAULT_LOG_TRACE(
+ "global singleton storage collection is about to destroy, address: {}",
+ static_cast<void*>(global_instance.get()));
+ return SingletonStorageCollection::Impl::Destroy();
+}
+
+auto SingletonStorageCollection::GetSingletonStorage(
+ const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
+ return p_->GetSingletonStorage(type_id);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.h b/src/core/function/basic/SingletonStorageCollection.h
new file mode 100644
index 00000000..38ced83b
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+class SingletonStorage;
+
+using SingletonStoragePtr =
+ std::unique_ptr<SingletonStorage, SecureObjectDeleter<SingletonStorage>>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorageCollection() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorageCollection();
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
+
+ /**
+ * @brief
+ *
+ */
+ static void Destroy();
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info&) -> SingletonStorage*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index 2a3bba42..3fc831ed 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * This file is part of GpgFrontend.
*
* GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
@@ -32,152 +33,182 @@
#include "GpgAdvancedOperator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
-#include "spdlog/spdlog.h"
-
-GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel)
- : SingletonFunctionObject(channel) {}
-
-bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- SPDLOG_DEBUG("gpgconf reload exit code: {}", exit_code);
- success = true;
- }
- });
- return success;
+#include "core/module/ModuleManager.h"
+
+void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--reload", "gpg-agent"},
+ [=](int exit_code, const QString & /*p_out*/,
+ const QString & /*p_err*/) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
- return success;
+void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--reload"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
- bool success = false;
-
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--verbose", "--kill", "all"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- return;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- if (!success) return false;
-
- success &= StartGpgAgent();
-
- success &= StartDirmngr();
-
- success &= StartKeyBoxd();
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--verbose", "--kill", "all"},
+ [=](int exit_code, const QString &p_out, const QString &p_err) {
+ GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
+ exit_code);
+ bool success = true;
+ if (exit_code != 0) {
+ success = false;
+ GF_CORE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+
+ GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ if (!success) {
+ GF_CORE_LOG_ERROR(
+ "restart all component after core initilized failed");
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", false);
+ return;
+ }
+
+ StartGpgAgent([](int err, DataObjectPtr) {
+ if (err >= 0) {
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", true);
+ return;
+ }
+ });
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--apply-defaults"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--apply-defaults"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartGpgAgent() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgAgentPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start gpg-agent successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("gpg-agent already started");
- } else {
- SPDLOG_ERROR(
- "gpg-agent execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
+ const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.gpg_agent_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (gpg_agent_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpg_agent_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartDirmngr() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().DirmngrPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start dirmngr successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("dirmngr already started");
- } else {
- SPDLOG_ERROR(
- "dirmngr execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
+ const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.dirmngr_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (dirmngr_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {dirmngr_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartKeyBoxd() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().KeyboxdPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start keyboxd successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("keyboxd already started");
- } else {
- SPDLOG_ERROR(
- "keyboxd execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
+ const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.keyboxd_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (keyboxd_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {keyboxd_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
index 5325020a..d6b57095 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.h
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * This file is part of GpgFrontend.
*
* GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,42 +20,31 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
// Created by eric on 07.01.2023.
//
-#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H
-#define GPGFRONTEND_GPGADVANCEDOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
- : public SingletonFunctionObject<GpgAdvancedOperator> {
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
public:
/**
- * @brief Construct a new Basic Operator object
- *
- * @param channel Channel corresponding to the context
- */
- explicit GpgAdvancedOperator(
- int channel = SingletonFunctionObject::GetDefaultChannel());
-
- /**
* @brief
*
* @return true
* @return false
*/
- bool ClearGpgPasswordCache();
+ static void ClearGpgPasswordCache(OperationCallback);
/**
* @brief
@@ -63,7 +52,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ReloadGpgComponents();
+ static void ReloadGpgComponents(OperationCallback);
/**
* @brief
@@ -71,7 +60,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool RestartGpgComponents();
+ static void RestartGpgComponents();
/**
* @brief
@@ -79,7 +68,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ResetConfigures();
+ static void ResetConfigures(OperationCallback);
/**
* @brief
@@ -87,7 +76,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartGpgAgent();
+ static void StartGpgAgent(OperationCallback);
/**
* @brief
@@ -95,7 +84,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartDirmngr();
+ static void StartDirmngr(OperationCallback);
/**
* @brief
@@ -103,13 +92,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartKeyBoxd();
-
- private:
- GpgContext& ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void StartKeyBoxd(OperationCallback);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 71f84907..8b62aad0 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,195 +28,389 @@
#include "GpgBasicOperator.h"
-#include <vector>
+#include <gpg-error.h>
-#include "GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel)
+namespace GpgFrontend {
+
+GpgBasicOperator::GpgBasicOperator(int channel)
: SingletonFunctionObject<GpgBasicOperator>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Encrypt(
- KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer,
- GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) {
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+void GpgBasicOperator::Encrypt(const KeyArgsList& keys,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // Last entry data_in array has to be nullptr
- recipients[keys->size()] = nullptr;
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+}
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
+auto GpgBasicOperator::EncryptSync(const KeyArgsList& keys,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- return err;
-}
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Decrypt(
- BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgDecrResult& result) {
- gpgme_error_t err;
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
- err = check_gpg_error(gpgme_op_decrypt(ctx_, data_in, data_out));
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- auto temp_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(result, temp_result);
+ return err;
+ },
+ "gpgme_op_encrypt", "2.1.0");
+}
- return err;
+void GpgBasicOperator::EncryptSymmetric(const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify(
- BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const {
- gpgme_error_t err;
+auto GpgBasicOperator::EncryptSymmetricSync(const GFBuffer& in_buffer,
+ bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
- GpgData data_in(in_buffer.data(), in_buffer.size());
- GpgData data_out;
+void GpgBasicOperator::Decrypt(const GFBuffer& in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
- if (sig_buffer != nullptr && sig_buffer->size() > 0) {
- GpgData sig_data(sig_buffer->data(), sig_buffer->size());
- err = check_gpg_error(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
- } else
- err = check_gpg_error(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
+auto GpgBasicOperator::DecryptSync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ "gpgme_op_decrypt", "2.1.0");
+}
- auto temp_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(result, temp_result);
+void GpgBasicOperator::Verify(const GFBuffer& in_buffer,
+ const GFBuffer& sig_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
+}
- return err;
+auto GpgBasicOperator::VerifySync(const GFBuffer& in_buffer,
+ const GFBuffer& sig_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_verify", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(
- KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- gpgme_sig_mode_t mode, GpgSignResult& result) {
- gpgme_error_t err;
+void GpgBasicOperator::Sign(const KeyArgsList& signers,
+ const GFBuffer& in_buffer, GpgSignMode mode,
+ bool ascii, const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- // Set Singers of this opera
- SetSigners(*signers);
+ GpgError err;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
- err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode));
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
- auto temp_result = _new_result(gpgme_op_sign_result(ctx_));
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
+}
- std::swap(result, temp_result);
+auto GpgBasicOperator::SignSync(const KeyArgsList& signers,
+ const GFBuffer& in_buffer, GpgSignMode mode,
+ bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- return err;
+ GpgError err;
+
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
+
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::DecryptVerify(
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) {
- gpgme_error_t err;
+void GpgBasicOperator::DecryptVerify(const GFBuffer& in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
- err = check_gpg_error(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
+auto GpgBasicOperator::DecryptVerifySync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(decrypt_result, temp_decr_result);
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
- auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(verify_result, temp_verify_result);
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ "gpgme_op_decrypt_verify", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
- KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
- GpgSignResult& sign_result) {
- gpgme_error_t err;
- SetSigners(*signers);
+void GpgBasicOperator::EncryptSign(const KeyArgsList& keys,
+ const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // set key for user
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- // Last entry dataIn array has to be nullptr
- recipients[keys->size()] = nullptr;
+ SetSigners(signers, ascii);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- // If the last parameter isnt 0, a private copy of data is made
- err = check_gpg_error(gpgme_op_encrypt_sign(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+auto GpgBasicOperator::EncryptSignSync(const KeyArgsList& keys,
+ const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
+
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_));
- swap(encr_result, temp_encr_result);
- auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_));
- swap(sign_result, temp_sign_result);
+ SetSigners(signers, ascii);
- return err;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ "gpgme_op_encrypt_sign", "2.1.0");
}
-void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
- gpgme_signers_clear(ctx_);
+void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ gpgme_signers_clear(ctx);
+
for (const GpgKey& key : signers) {
- SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
+ GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
- SPDLOG_DEBUG("signer");
- auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
- check_gpg_error(error);
+ GF_CORE_LOG_DEBUG("signer");
+ auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
+ CheckGpgError(error);
}
}
- if (signers.size() != gpgme_signers_count(ctx_))
- SPDLOG_DEBUG("not all signers added");
+ if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
+ GF_CORE_LOG_DEBUG("not all signers added");
}
-std::unique_ptr<GpgFrontend::KeyArgsList>
-GpgFrontend::GpgBasicOperator::GetSigners() {
- auto count = gpgme_signers_count(ctx_);
+auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ auto count = gpgme_signers_count(ctx);
auto signers = std::make_unique<std::vector<GpgKey>>();
- for (auto i = 0u; i < count; i++) {
- auto key = GpgKey(gpgme_signers_enum(ctx_, i));
+ for (auto i = 0U; i < count; i++) {
+ auto key = GpgKey(gpgme_signers_enum(ctx, i));
signers->push_back(GpgKey(std::move(key)));
}
return signers;
}
-
-gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric(
- GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgEncrResult& result) {
- // deepcopy from ByteArray to GpgData
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
-
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
-
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
-
- // TODO(Saturneric): maybe a bug of gpgme
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
- }
-
- return err;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h
index 696ac9dc..37defb45 100644
--- a/src/core/function/gpg/GpgBasicOperator.h
+++ b/src/core/function/gpg/GpgBasicOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -52,19 +53,18 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Call the interface provided by gpgme for encryption operation
+ * @brief
*
- * All incoming data pointers out_buffer will be replaced with new valid
- * values
+ */
+ void Encrypt(const KeyArgsList&, const GFBuffer&, bool,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
*
- * @param keys list of public keys
- * @param in_buffer data that needs to be encrypted
- * @param out_buffer encrypted data
- * @param result the result of the operation
- * @return error code
*/
- gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& result);
+ auto EncryptSync(const KeyArgsList&, const GFBuffer&, bool)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by GPGME to symmetrical encryption
@@ -72,10 +72,21 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param in_buffer Data for encryption
* @param out_buffer Encrypted data
* @param result Encrypted results
- * @return gpg_error_t
+ * @return GpgError
+ */
+ void EncryptSymmetric(const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ * @param ascii
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
*/
- gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& result);
+ auto EncryptSymmetricSync(const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
*
@@ -85,15 +96,25 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param keys List of public keys
* @param signers Private key for signatures
* @param in_buffer Data for operation
- * @param out_buffer Encrypted data
- * @param encr_result Encrypted results
- * @param sign_result Signature result
+ * @param ascii ascii mode
* @return
*/
- gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& encr_result,
- GpgSignResult& sign_result);
+ void EncryptSign(const KeyArgsList& keys, const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signers
+ * @param in_buffer
+ * @param ascii
+ * @param cb
+ */
+ auto EncryptSignSync(const KeyArgsList& keys, const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for decryption operation
@@ -103,8 +124,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& result);
+ void Decrypt(const GFBuffer& in_buffer, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ */
+ auto DecryptSync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme to perform decryption and
@@ -116,9 +144,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param verify_result the result of the verifying operation
* @return error code
*/
- gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result,
- GpgVerifyResult& verify_result);
+ void DecryptVerify(const GFBuffer& in_buffer, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ */
+ auto DecryptVerifySync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for verification operation
@@ -128,8 +162,19 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const;
+ void Verify(const GFBuffer& in_buffer, const GFBuffer& sig_buffer,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ * @param sig_buffer
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto VerifySync(const GFBuffer& in_buffer, const GFBuffer& sig_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for signing operation
@@ -151,9 +196,22 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
- GpgSignResult& result);
+ void Sign(const KeyArgsList& signers, const GFBuffer& in_buffer,
+ GpgSignMode mode, bool ascii, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param signers
+ * @param in_buffer
+ * @param mode
+ * @param ascii
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto SignSync(const KeyArgsList& signers, const GFBuffer& in_buffer,
+ GpgSignMode mode, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Set the private key for signatures, this operation is a global
@@ -161,19 +219,17 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
*
* @param keys
*/
- void SetSigners(KeyArgsList& signers);
+ void SetSigners(const KeyArgsList& signers, bool ascii);
/**
* @brief Get a global signature private keys that has been set.
*
* @return Intelligent pointer pointing to the private key list
*/
- std::unique_ptr<KeyArgsList> GetSigners();
+ auto GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList>;
private:
GpgContext& ctx_ = GpgContext::GetInstance(
SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 86c47c60..6d24f9bd 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,252 +20,231 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCommandExecutor.h"
-#include "GpgFunctionObject.h"
+#include "core/model/DataObject.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel)
- : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
+namespace GpgFrontend {
-void GpgFrontend::GpgCommandExecutor::Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
+auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
+ -> Thread::Task * {
+ const auto &cmd = context.cmd;
+ const auto &arguments = context.arguments;
+ const auto &interact_function = context.int_func;
+ const auto &cmd_executor_callback = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- SPDLOG_DEBUG("data object use count: {}", data_object.use_count());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ const QString joined_argument = QStringList::fromVector(arguments).join(" ");
+
+ GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
+ arguments.size());
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
+ Thread::Task::TaskCallback result_callback =
+ [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
+ GF_CORE_LOG_DEBUG(
+ "data object args count of cmd executor result callback: {}",
+ data_object->GetObjectSize());
+ if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return;
+ }
+
+ auto exit_code = ExtractParams<int>(data_object, 0);
+ auto process_stdout = ExtractParams<QString>(data_object, 1);
+ auto callback =
+ ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
// call callback
- callback(exit_code, process_stdout, process_stderr);
+ GF_CORE_LOG_DEBUG(
+ "calling custom callback from caller of cmd {} {}, "
+ "exit_code: {}",
+ cmd, joined_argument, exit_code);
+ callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
+ [joined_argument](const DataObjectPtr &data_object) -> int {
+ GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
+ GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return -1;
+ }
// get arguments
- auto cmd = data_object->PopObject<std::string>();
- SPDLOG_DEBUG("get cmd: {}", cmd);
- auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto cmd = ExtractParams<QString>(data_object, 0);
+ auto arguments = ExtractParams<QStringList>(data_object, 1);
auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
+ ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
+ auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ // create process
auto *cmd_process = new QProcess();
+ // move to current thread
+ //
+ cmd_process->moveToThread(QThread::currentThread());
+ // set process channel mode
+ // this is to make sure we can get all output from stdout and stderr
cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+ cmd_process->setProgram(cmd);
+
+ // set arguments
+ QStringList q_arguments;
+ for (const auto &argument : arguments) {
+ q_arguments.append(argument);
+ }
+ cmd_process->setArguments(q_arguments);
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Started ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
+ });
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
+ cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ GF_CORE_LOG_ERROR(
+ "caught error while executing command: {} {}, error: {}", cmd,
+ joined_argument, error);
});
- cmd_process->setProgram(QString::fromStdString(cmd));
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process execute ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Ready ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
cmd_process->start();
cmd_process->waitForFinished();
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
+ QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
+ GF_CORE_LOG_DEBUG(
+ "\n==== Process Execution Summary ====\n"
+ "Command: {}\n"
+ "Arguments: {}\n"
+ "Exit Code: {}\n"
+ "---- Standard Output ----\n"
+ "{}\n"
+ "===============================",
+ cmd, joined_argument, exit_code, process_stdout);
+
cmd_process->close();
cmd_process->deleteLater();
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
+ data_object->Swap({exit_code, process_stdout, callback});
return 0;
};
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- SPDLOG_DEBUG("executor append object");
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
- SPDLOG_DEBUG("executor append object done");
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("Execute/{}", cmd), data_object,
+ return new Thread::Task(
+ std::move(runner), QString("GpgCommamdExecutor(%1){%2}").arg(cmd),
+ TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
std::move(result_callback));
+}
+
+void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+ Thread::Task *task = BuildTaskFromExecCtx(context);
QEventLoop looper;
- QObject::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
&QEventLoop::quit);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ GF_CORE_LOG_TRACE("blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
}
-void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
-
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
-
- // call callback
- callback(exit_code, process_stdout, process_stderr);
- };
-
- Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
-
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- SPDLOG_DEBUG("runner pop object");
- // get arguments
- auto cmd = data_object->PopObject<std::string>();
- auto arguments = data_object->PopObject<std::vector<std::string>>();
- auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
- SPDLOG_DEBUG("runner pop object done");
-
- auto *cmd_process = new QProcess();
- cmd_process->setProcessChannelMode(QProcess::MergedChannels);
-
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
- QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
- });
-
- cmd_process->setProgram(QString::fromStdString(cmd));
- cmd_process->setProcessChannelMode(QProcess::SeparateChannels);
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process start ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
-
- cmd_process->start();
- cmd_process->waitForFinished();
-
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
- int exit_code = cmd_process->exitCode();
-
- cmd_process->close();
- cmd_process->deleteLater();
-
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
- return 0;
- };
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+}
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
+void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+ QEventLoop looper;
+ auto remaining_tasks = contexts.size();
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
+ --remaining_tasks;
+ GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
+ if (remaining_tasks <= 0) {
+ GF_CORE_LOG_DEBUG("no remaining task, quit");
+ looper.quit();
+ }
+ });
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+ }
+
+ GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
+}
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd),
- data_object, std::move(result_callback), false);
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QString cmd, QStringList arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInteractor int_func)
+ : cmd(std::move(cmd)),
+ arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index da0e7a8b..ac52b295 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,39 +20,43 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
-#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#pragma once
-#ifndef WINDOWS
-#include <boost/process.hpp>
-#endif
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/thread/Task.h"
+#include "core/module/Module.h"
namespace GpgFrontend {
+using GpgCommandExecutorCallback = std::function<void(int, QString, QString)>;
+using GpgCommandExecutorInteractor = std::function<void(QProcess *)>;
+
/**
* @brief Extra commands related to GPG
*
*/
-class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
- : public SingletonFunctionObject<GpgCommandExecutor> {
+class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor {
public:
- /**
- * @brief Construct a new Gpg Command Executor object
- *
- * @param channel Corresponding context
- */
- explicit GpgCommandExecutor(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ struct GPGFRONTEND_CORE_EXPORT ExecuteContext {
+ QString cmd;
+ QStringList arguments;
+ GpgCommandExecutorCallback cb_func;
+ GpgCommandExecutorInteractor int_func;
+ Module::TaskRunnerPtr task_runner = nullptr;
+
+ ExecuteContext(
+ QString cmd, QStringList arguments,
+ GpgCommandExecutorCallback callback = [](int, const QString &,
+ const QString &) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
+ GpgCommandExecutorInteractor int_func = [](QProcess *) {});
+ };
+
+ using ExecuteContexts = QList<ExecuteContext>;
/**
* @brief Excuting a command
@@ -60,22 +64,11 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- void Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback =
- [](int, std::string, std::string) {},
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteSync(ExecuteContext);
- void ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteConcurrentlyAsync(ExecuteContexts);
- private:
- GpgContext &ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void ExecuteConcurrentlySync(ExecuteContexts);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
new file mode 100644
index 00000000..6523386c
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -0,0 +1,339 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "core/function/gpg/GpgContext.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <cassert>
+#include <mutex>
+
+#include "core/function/CoreSignalStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/model/GpgPassphraseContext.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace GpgFrontend {
+
+class GpgContext::Impl {
+ public:
+ /**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+ Impl(GpgContext *parent, const GpgContextInitArgs &args)
+ : parent_(parent),
+ args_(args),
+ good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
+
+ ~Impl() {
+ if (ctx_ref_ != nullptr) {
+ gpgme_release(ctx_ref_);
+ }
+
+ if (binary_ctx_ref_ != nullptr) {
+ gpgme_release(binary_ctx_ref_);
+ }
+ }
+
+ [[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
+ return binary_ctx_ref_;
+ }
+
+ [[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t { return ctx_ref_; }
+
+ [[nodiscard]] auto Good() const -> bool { return good_; }
+
+ auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
+ -> bool {
+ if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ if (CheckGpgError(gpgme_set_pinentry_mode(
+ ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+ gpgme_set_passphrase_cb(ctx, cb, reinterpret_cast<void *>(parent_));
+ return true;
+ }
+
+ static auto TestPassphraseCb(void *opaque, const char *uid_hint,
+ const char *passphrase_info, int last_was_bad,
+ int fd) -> gpgme_error_t {
+ size_t res;
+ QString pass = "abcdefg\n";
+ auto passpahrase_size = pass.size();
+
+ size_t off = 0;
+
+ do {
+ res = gpgme_io_write(fd, &pass[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+
+ res += gpgme_io_write(fd, "\n", 1);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto CustomPassphraseCb(void *hook, const char *uid_hint,
+ const char *passphrase_info, int prev_was_bad,
+ int fd) -> gpgme_error_t {
+ auto context_cache = GetCacheValue("PinentryContext");
+ bool ask_for_new = context_cache == "NEW_PASSPHRASE";
+ auto context =
+ QSharedPointer<GpgPassphraseContext>(new GpgPassphraseContext(
+ uid_hint != nullptr ? uid_hint : "",
+ passphrase_info != nullptr ? passphrase_info : "",
+ prev_was_bad != 0, ask_for_new));
+
+ GF_CORE_LOG_DEBUG(
+ "custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
+ uid_hint == nullptr ? "<empty>" : QString{uid_hint},
+ passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
+ prev_was_bad);
+
+ QEventLoop looper;
+ QObject::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseCallback,
+ &looper, &QEventLoop::quit);
+
+ emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
+ context);
+ looper.exec();
+
+ ResetCacheValue("PinentryContext");
+ auto passphrase = context->GetPassphrase().toStdString();
+ auto passpahrase_size = passphrase.size();
+ GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
+ passpahrase_size);
+
+ size_t res = 0;
+ if (passpahrase_size > 0) {
+ size_t off = 0;
+ do {
+ res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+ }
+
+ res += gpgme_io_write(fd, "\n", 1);
+
+ GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto TestStatusCb(void *hook, const char *keyword, const char *args)
+ -> gpgme_error_t {
+ GF_CORE_LOG_DEBUG("keyword {}", keyword);
+ return GPG_ERR_NO_ERROR;
+ }
+
+ private:
+ GpgContext *parent_;
+ GpgContextInitArgs args_{}; ///<
+ gpgme_ctx_t ctx_ref_ = nullptr; ///<
+ gpgme_ctx_t binary_ctx_ref_ = nullptr; ///<
+ bool good_ = true;
+ std::mutex ctx_ref_lock_;
+ std::mutex binary_ctx_ref_lock_;
+
+ static auto set_ctx_key_list_mode(const gpgme_ctx_t &ctx) -> bool {
+ assert(ctx != nullptr);
+
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+
+ if (gpgme_get_keylist_mode(ctx) == 0) {
+ GF_CORE_LOG_ERROR(
+ "ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
+ return false;
+ }
+
+ // set keylist mode
+ return CheckGpgError(gpgme_set_keylist_mode(
+ ctx, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS |
+ GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
+ }
+
+ static auto set_ctx_openpgp_engine_info(gpgme_ctx_t ctx) -> bool {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.database_path", QString{});
+
+ GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
+ database_path, app_path);
+
+ auto app_path_buffer = app_path.toUtf8();
+ auto database_path_buffer = database_path.toUtf8();
+
+ auto err = gpgme_ctx_set_engine_info(
+ ctx, gpgme_get_protocol(ctx),
+ app_path.isEmpty() ? nullptr : app_path_buffer,
+ database_path.isEmpty() ? nullptr : database_path_buffer);
+
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
+
+ return true;
+ }
+
+ auto common_ctx_initialize(const gpgme_ctx_t &ctx,
+ const GpgContextInitArgs &args) -> bool {
+ assert(ctx != nullptr);
+
+ if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
+ args.custom_gpgconf_path);
+ auto err =
+ gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
+ args.custom_gpgconf_path.toUtf8(), nullptr);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ }
+
+ // set context offline mode
+ GF_CORE_LOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ GF_CORE_LOG_DEBUG("gpg context auto import missing key: {}",
+ args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key) {
+ if (CheckGpgError(gpgme_set_ctx_flag(ctx, "auto-key-import", "1")) !=
+ GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+
+ if (!set_ctx_key_list_mode(ctx)) {
+ GF_CORE_LOG_DEBUG("set ctx key list mode failed");
+ return false;
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
+ GF_CORE_LOG_ERROR("set passphrase cb failed, test");
+ return false;
+ };
+ } else if (!args_.use_pinentry) {
+ if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
+ GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
+ return false;
+ }
+ }
+
+ // set custom gpg key db path
+ if (!args_.db_path.isEmpty()) {
+ Module::UpsertRTValue("core", "gpgme.ctx.database_path", args_.db_path);
+ }
+
+ if (!set_ctx_openpgp_engine_info(ctx)) {
+ GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new gpg context error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ binary_ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(binary_ctx_ref_, args)) {
+ GF_CORE_LOG_ERROR("get new ctx failed, binary");
+ return false;
+ }
+
+ gpgme_set_armor(binary_ctx_ref_, 0);
+ return true;
+ }
+
+ auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new ctx failed, default");
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(ctx_ref_, args)) {
+ return false;
+ }
+
+ gpgme_set_armor(ctx_ref_, 1);
+ return true;
+ }
+};
+
+GpgContext::GpgContext(int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, GpgContextInitArgs{})) {}
+
+GpgContext::GpgContext(GpgContextInitArgs args, int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, args)) {}
+
+auto GpgContext::Good() const -> bool { return p_->Good(); }
+
+auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
+
+auto GpgContext::DefaultContext() -> gpgme_ctx_t {
+ return p_->DefaultContext();
+}
+
+GpgContext::~GpgContext() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
new file mode 100644
index 00000000..d473a341
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+struct GpgContextInitArgs {
+ QString db_path = {}; ///<
+
+ bool test_mode = false; ///<
+ bool offline_mode = false; ///<
+ bool auto_import_missing_key = false; ///<
+
+ bool custom_gpgconf = false; ///<
+ QString custom_gpgconf_path; ///<
+
+ bool use_pinentry = false; ///<
+};
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgContext
+ : public SingletonFunctionObject<GpgContext> {
+ public:
+ explicit GpgContext(int channel);
+
+ explicit GpgContext(GpgContextInitArgs args, int channel);
+
+ virtual ~GpgContext() override;
+
+ [[nodiscard]] auto Good() const -> bool;
+
+ auto BinaryContext() -> gpgme_ctx_t;
+
+ auto DefaultContext() -> gpgme_ctx_t;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 30678cf0..94a08c76 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,235 +20,553 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgFileOpera.h"
-#include <memory>
-#include <string>
+#include "core/function/ArchiveFileOperator.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/model/GpgData.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgKey.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgBasicOperator.h"
-#include "GpgConstants.h"
-#include "function/FileOperator.h"
+namespace GpgFrontend {
-GpgFrontend::GpgFileOpera::GpgFileOpera(int channel)
+constexpr ssize_t kDataExchangerSize = 8192;
+
+GpgFileOpera::GpgFileOpera(int channel)
: SingletonFunctionObject<GpgFileOpera>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
- KeyListPtr keys, const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Encrypt(
- std::move(keys), in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& result) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err =
- GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
-
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgSignResult& result,
- int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Sign(
- std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(
- const std::string& data_path, const std::string& sign_path,
- GpgVerifyResult& result, int _channel) {
-#ifdef WINDOWS
- auto data_path_std =
- std::filesystem::path(QString::fromStdString(data_path).toStdU16String());
- auto sign_path_std =
- std::filesystem::path(QString::fromStdString(sign_path).toStdU16String());
-#else
- auto data_path_std = std::filesystem::path(data_path);
- auto sign_path_std = std::filesystem::path(sign_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(data_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> sign_buffer = nullptr;
- if (!sign_path.empty()) {
- std::string sign_buffer_str;
- if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) {
- throw std::runtime_error("read file error");
- }
- sign_buffer = std::make_unique<std::string>(sign_buffer_str);
- }
- auto err = GpgBasicOperator::GetInstance(_channel).Verify(
- in_buffer, sign_buffer, result);
- return err;
-}
-
-gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
- KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path,
- const std::string& out_path, GpgEncrResult& encr_res,
- GpgSignResult& sign_res, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign(
- std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
- sign_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& decr_res, GpgVerifyResult& verify_res) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
- auto err = GpgBasicOperator::GetInstance().DecryptVerify(
- in_buffer, out_buffer, decr_res, verify_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write file error");
- };
-
- return err;
-}
-unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgFrontend::GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer;
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric(
- in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
+
+auto GpgFileOpera::EncryptFileSync(const KeyArgsList& keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ "gpgme_op_encrypt", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ GF_CORE_LOG_DEBUG("encrypt directory start");
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
+ err);
+ });
+}
+
+void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+auto GpgFileOpera::DecryptFileSync(const QString& in_path,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::DecryptArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG(
+ "extract archive from data exchanger operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::SignFile(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
+}
+
+auto GpgFileOpera::SignFileSync(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ "gpgme_op_sign", "2.1.0");
+}
+
+void GpgFileOpera::VerifyFile(const QString& data_path,
+ const QString& sign_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
+}
+
+auto GpgFileOpera::VerifyFileSync(const QString& data_path,
+ const QString& sign_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+auto GpgFileOpera::EncryptSignFileSync(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+}
+
+void GpgFileOpera::DecryptVerifyFile(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+auto GpgFileOpera::DecryptVerifyFileSync(const QString& in_path,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+auto GpgFileOpera::EncryptFileSymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+}
+
+auto GpgFileOpera::EncryptDerectorySymmetricSync(const QString& in_path,
+ bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
index dc81bc53..d7c2d44c 100644
--- a/src/core/function/gpg/GpgFileOpera.h
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,59 +20,123 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFILEOPERA_H
-#define GPGFRONTEND_GPGFILEOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
- * @brief Executive files related to the basic operations that are provided by
- * GpgBasicOperator
+ * @brief Executive files related to the basic operations of GPG
+ *
* @class class: GpgBasicOperator
*/
class GPGFRONTEND_CORE_EXPORT GpgFileOpera
: public SingletonFunctionObject<GpgFileOpera> {
public:
+ /**
+ * @brief Construct a new Gpg File Opera object
+ *
+ * @param channel
+ */
explicit GpgFileOpera(
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Encrypted file
+ * @brief Encrypted file with public key
*
* @param keys Used public key
* @param in_path The path where the enter file is located
* @param out_path The path where the output file is located
* @param result Encrypted results
- * @param _channel Channel in context
+ * @param channel Channel in context
* @return unsigned int error code
*/
- static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFile(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto EncryptFileSync(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDirectory(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
- * @brief 运用对称加密算法加密文件
+ * @brief Encrypted file symmetrically (with password)
*
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return unsigned int
*/
- static unsigned int EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ auto EncryptFileSymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ */
+ auto EncryptDerectorySymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -82,37 +146,77 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param result
* @return GpgError
*/
- static GpgError DecryptFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& result);
+ void DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
+ * @param in_path
+ * @param out_path
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto DecryptFileSync(const QString& in_path, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief Sign file with private key
+ *
* @param keys
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
+ * @return GpgError
+ */
+ void SignFile(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto SignFileSync(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief Verify file with public key
+ *
+ * @param data_path The path where the enter file is located
+ * @param sign_path The path where the signature file is located
+ * @param result Verify results
+ * @param channel Channel in context
* @return GpgError
*/
- static GpgError SignFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path, GpgSignResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void VerifyFile(const QString& data_path, const QString& sign_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
* @param data_path
* @param sign_path
- * @param result
- * @param _channel
- * @return GpgError
+ * @return std::tuple<GpgError, DataObjectPtr>
*/
- static GpgError VerifyFile(const std::string& data_path,
- const std::string& sign_path,
- GpgVerifyResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ auto VerifyFileSync(const QString& data_path, const QString& sign_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -120,18 +224,44 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param keys
* @param signer_keys
* @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignFile(const KeyArgsList& keys, const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
* @param out_path
- * @param encr_res
- * @param sign_res
- * @param _channel
- * @return GpgError
*/
- static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& encr_res,
- GpgSignResult& sign_res,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ auto EncryptSignFileSync(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignDirectory(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -142,12 +272,31 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param verify_res
* @return GpgError
*/
- static GpgError DecryptVerifyFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& decr_res,
- GpgVerifyResult& verify_res);
+ void DecryptVerifyFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ */
+ auto DecryptVerifyFileSync(const QString& in_path, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptVerifyArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index ee6d2b09..4a35d3cd 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -32,136 +32,220 @@
#include <mutex>
#include <shared_mutex>
-#include <utility>
-#include "GpgConstants.h"
-#include "model/GpgKey.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
- : SingletonFunctionObject<GpgKeyGetter>(channel) {
- SPDLOG_DEBUG("called channel: {}", channel);
-}
+namespace GpgFrontend {
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
+ public:
+ explicit Impl(int channel)
+ : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
- if (_p_key == nullptr) {
- SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
- return GetPubkey(fpr);
- } else {
- return GpgKey(std::move(_p_key));
- }
-}
+ auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
+ if (p_key == nullptr) {
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
+ return GetPubkey(fpr, true);
+ }
+ return GpgKey(std::move(p_key));
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
- if (_p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
- return GpgKey(std::move(_p_key));
-}
+ auto GetPubkey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
+ if (p_key == nullptr)
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
+ return GpgKey(std::move(p_key));
+ }
- auto keys_list = std::make_unique<GpgKeyLinkList>();
+ auto FetchKey() -> KeyLinkListPtr {
+ if (keys_search_cache_.empty()) {
+ FlushKeyCache();
+ }
- for (const auto& [key, value] : keys_cache_) {
- keys_list->push_back(value.Copy());
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ for (const auto& key : keys_cache_) {
+ keys_list->push_back(key);
+ }
+ }
+ return keys_list;
}
- return keys_list;
-}
-void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
- SPDLOG_DEBUG("called channel id: {}", GetChannel());
+ auto FlushKeyCache() -> bool {
+ GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
- // clear the keys cache
- keys_cache_.clear();
+ // clear the keys cache
+ keys_cache_.clear();
+ keys_search_cache_.clear();
- // init
- GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ // init
+ GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
- // for debug
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ // for debug
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
- // return when error
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return;
+ // return when error
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
- {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
- auto gpg_key = GpgKey(std::move(key));
-
- // detect if the key is in a smartcard
- // if so, try to get full information using gpgme_get_key()
- // this maybe a bug in gpgme
- if (gpg_key.IsHasCardKey()) {
- gpg_key = GetKey(gpg_key.GetId(), false);
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
+ GPG_ERR_NO_ERROR) {
+ auto gpg_key = GpgKey(std::move(key));
+
+ // detect if the key is in a smartcard
+ // if so, try to get full information using gpgme_get_key()
+ // this maybe a bug in gpgme
+ if (gpg_key.IsHasCardKey()) {
+ gpg_key = GetKey(gpg_key.GetId(), false);
+ }
+
+ keys_cache_.push_back(gpg_key);
+ keys_search_cache_.insert(gpg_key.GetId(), gpg_key);
+ keys_search_cache_.insert(gpg_key.GetFingerprint(), gpg_key);
}
+ }
+
+ GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
+ static_cast<void*>(&keys_search_cache_),
+ static_cast<void*>(this));
+
+ // for debug
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx_.DefaultContext());
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
+ GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
+ return true;
+ }
+
+ auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& key_id : *ids) keys->emplace_back(GetKey(key_id, true));
+ return keys;
+ }
+
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<GpgKeyLinkList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<KeyArgsList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ private:
+ /**
+ * @brief Get the gpgme context object
+ *
+ */
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex ctx_mutex_;
+
+ /**
+ * @brief cache the keys with key id
+ *
+ */
+ QMap<QString, GpgKey> keys_search_cache_;
+
+ /**
+ * @brief
+ *
+ */
+ QList<GpgKey> keys_cache_;
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex keys_cache_mutex_;
+
+ /**
+ * @brief Get the Key object
+ *
+ * @param id
+ * @return GpgKey
+ */
+ auto get_key_in_cache(const QString& key_id) -> GpgKey {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_search_cache_.find(key_id) != keys_search_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ // return a copy of the key in cache
+ return keys_search_cache_[key_id];
}
+
+ // return a bad key
+ return {};
}
+};
- SPDLOG_DEBUG("cache address: {} object address: {}",
- static_cast<void*>(&keys_cache_), static_cast<void*>(this));
+GpgKeyGetter::GpgKeyGetter(int channel)
+ : SingletonFunctionObject<GpgKeyGetter>(channel),
+ p_(SecureCreateUniqueObject<Impl>(channel)) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
+}
- // for debug
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+GpgKeyGetter::~GpgKeyGetter() = default;
- err = gpgme_op_keylist_end(ctx_);
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+auto GpgKeyGetter::GetKey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetKey(key_id, use_cache);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
- const KeyIdArgsListPtr& ids) {
- auto keys = std::make_unique<KeyArgsList>();
- for (const auto& id : *ids) keys->emplace_back(GetKey(id));
- return keys;
+auto GpgKeyGetter::GetPubkey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetPubkey(key_id, use_cache);
}
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyLinkListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<GpgKeyLinkList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::FlushKeyCache() -> bool { return p_->FlushKeyCache(); }
+
+auto GpgKeyGetter::GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ return p_->GetKeys(ids);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<KeyArgsList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ return p_->GetKeysCopy(keys);
}
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::get_key_in_cache(
- const std::string& id) {
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- if (keys_cache_.find(id) != keys_cache_.end()) {
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- // return a copy of the key in cache
- return keys_cache_[id].Copy();
- }
- // return a bad key
- return GpgKey();
+auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ return p_->GetKeysCopy(keys);
}
+
+auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index c96dbea7..91138623 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#pragma once
-#include <mutex>
-#include <vector>
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -50,8 +45,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*
* @param channel
*/
- explicit GpgKeyGetter(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit GpgKeyGetter(int channel = kGpgFrontendDefaultChannel);
+
+ /**
+ * @brief Destroy the Gpg Key Getter object
+ *
+ */
+ ~GpgKeyGetter();
/**
* @brief Get the Key object
@@ -59,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetKey(const std::string& id, bool use_cache = true);
+ auto GetKey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get the Keys object
@@ -67,7 +67,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param ids
* @return KeyListPtr
*/
- KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+ auto GetKeys(const KeyIdArgsListPtr& key_ids) -> KeyListPtr;
/**
* @brief Get the Pubkey object
@@ -75,20 +75,20 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetPubkey(const std::string& id, bool use_cache = true);
+ auto GetPubkey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get all the keys by receiving a linked list
*
* @return KeyLinkListPtr
*/
- KeyLinkListPtr FetchKey();
+ auto FetchKey() -> KeyLinkListPtr;
/**
* @brief flush the keys in the cache
*
*/
- void FlushKeyCache();
+ auto FlushKeyCache() -> bool;
/**
* @brief Get the Keys Copy object
@@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyListPtr
*/
- KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr;
/**
* @brief Get the Keys Copy object
@@ -104,42 +104,10 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyLinkListPtr
*/
- KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
private:
- /**
- * @brief Get the gpgme context object
- *
- */
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex ctx_mutex_;
-
- /**
- * @brief cache the keys with key id
- *
- */
- std::map<std::string, GpgKey> keys_cache_;
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex keys_cache_mutex_;
-
- /**
- * @brief Get the Key object
- *
- * @param id
- * @return GpgKey
- */
- GpgKey get_key_in_cache(const std::string& id);
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index 01349c94..ef8cb112 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,79 +28,75 @@
#include "GpgKeyImportExporter.h"
-#include <memory>
+#include "core/GpgModel.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgConstants.h"
-#include "GpgKeyGetter.h"
+namespace GpgFrontend {
-GpgFrontend::GpgKeyImportExporter::GpgKeyImportExporter(int channel)
- : SingletonFunctionObject<GpgKeyImportExporter>(channel) {}
+GpgKeyImportExporter::GpgKeyImportExporter(int channel)
+ : SingletonFunctionObject<GpgKeyImportExporter>(channel),
+ ctx_(GpgContext::GetInstance(SingletonFunctionObject::GetChannel())) {}
/**
* Import key pair
* @param inBuffer input byte array
* @return Import information
*/
-GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey(
- StdBypeArrayPtr in_buffer) {
- if (in_buffer->empty()) return {};
+auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
+ -> std::shared_ptr<GpgImportInformation> {
+ if (in_buffer.Empty()) return {};
- GpgData data_in(in_buffer->data(), in_buffer->size());
- auto err = check_gpg_error(gpgme_op_import(ctx_, data_in));
+ GpgData data_in(in_buffer);
+ auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_);
+ result = gpgme_op_import_result(ctx_.DefaultContext());
gpgme_import_status_t status = result->imports;
- auto import_info = std::make_unique<GpgImportInformation>(result);
+ auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
- GpgImportedKey key;
+ GpgImportInformation::GpgImportedKey key;
key.import_status = static_cast<int>(status->status);
key.fpr = status->fpr;
- import_info->importedKeys.emplace_back(key);
+ import_info->imported_keys.emplace_back(key);
status = status->next;
}
-
- return *import_info;
+ return import_info;
}
/**
- * Export Key
- * @param uid_list key ids
- * @param out_buffer output byte array
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- if (uid_list->empty()) return false;
+auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode) const
+ -> std::tuple<GpgError, GFBuffer> {
+ if (!key.IsGood()) return {GPG_ERR_CANCELED, {}};
- int _mode = 0;
- if (secret) _mode |= GPGME_EXPORT_MODE_SECRET;
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
- auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list);
- auto keys_array = new gpgme_key_t[keys->size() + 1];
+ std::vector<gpgme_key_t> keys_array;
- int index = 0;
- for (const auto& key : *keys) {
- keys_array[index++] = gpgme_key_t(key);
- }
- keys_array[index] = nullptr;
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(key);
+ keys_array.emplace_back(nullptr);
GpgData data_out;
- auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
-
- delete[] keys_array;
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
-
- swap(temp_out_buffer, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
- return true;
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
+ gpgme_data_seek(data_out, 0, SEEK_END));
+ return {err, data_out.Read2GFBuffer()};
}
/**
@@ -109,114 +105,87 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
* @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
- for (const auto& key : keys) key_ids->push_back(key.GetId());
- return ExportKeys(key_ids, out_buffer, secret);
+void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
+ bool ascii, bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
+
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+
+ data_object->Swap({data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
/**
- * Export all the keys both private and public keys
- * @param uid_list key ids
- * @param out_buffer output byte array
- * @return if success
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportAllKeys(
- KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret) const {
- bool result = true;
- result = ExportKeys(uid_list, out_buffer, false) & result;
-
- ByteArrayPtr temp_buffer;
- if (secret) {
- result = ExportKeys(uid_list, temp_buffer, true) & result;
- }
- out_buffer->append(*temp_buffer);
- return result;
-}
-
-/**
- * Export the secret key of a key pair(including subkeys)
- * @param key target key pair
+ * Export keys
+ * @param keys keys used
* @param outBuffer output byte array
- * @return if successful
+ * @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
- const GpgKey& key, ByteArrayPtr& out_buffer) const {
- SPDLOG_DEBUG("export secret key: {}", key.GetId().c_str());
-
- gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
-
- GpgData data_out;
- // export private key to outBuffer
- gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
- GPGME_EXPORT_MODE_SECRET, data_out);
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKey(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
- data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
- GPGME_EXPORT_MODE_MINIMAL, data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
+ bool ascii,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+ auto buffer = data_out.Read2GFBuffer();
+
+ if (secret) {
+ int mode = 0;
+ mode |= GPGME_EXPORT_MODE_SECRET;
+
+ GpgData data_out_secret;
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode,
+ data_out_secret);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting secret keys finished, "
+ "ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out_secret, 0, SEEK_END));
+ buffer.Append(data_out_secret.Read2GFBuffer());
+ }
+
+ data_object->Swap({buffer});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
-GpgFrontend::GpgImportInformation::GpgImportInformation() = default;
-
-GpgFrontend::GpgImportInformation::GpgImportInformation(
- gpgme_import_result_t result) {
- if (result->unchanged) unchanged = result->unchanged;
- if (result->considered) considered = result->considered;
- if (result->no_user_id) no_user_id = result->no_user_id;
- if (result->imported) imported = result->imported;
- if (result->imported_rsa) imported_rsa = result->imported_rsa;
- if (result->unchanged) unchanged = result->unchanged;
- if (result->new_user_ids) new_user_ids = result->new_user_ids;
- if (result->new_sub_keys) new_sub_keys = result->new_sub_keys;
- if (result->new_signatures) new_signatures = result->new_signatures;
- if (result->new_revocations) new_revocations = result->new_revocations;
- if (result->secret_read) secret_read = result->secret_read;
- if (result->secret_imported) secret_imported = result->secret_imported;
- if (result->secret_unchanged) secret_unchanged = result->secret_unchanged;
- if (result->not_imported) not_imported = result->not_imported;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
index 6e90f436..d0724f7b 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.h
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,67 +20,22 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYIMPORTEXPORTOR_H
-#define _GPGKEYIMPORTEXPORTOR_H
+#pragma once
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-class GpgImportedKey {
- public:
- std::string fpr; ///<
- int import_status; ///<
-};
-
-typedef std::list<GpgImportedKey> GpgImportedKeyList; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
- public:
- GpgImportInformation();
-
- /**
- * @brief Construct a new Gpg Import Information object
- *
- * @param result
- */
- explicit GpgImportInformation(gpgme_import_result_t result);
-
- int considered = 0; ///<
- int no_user_id = 0; ///<
- int imported = 0; ///<
- int imported_rsa = 0; ///<
- int unchanged = 0; ///<
- int new_user_ids = 0; ///<
- int new_sub_keys = 0; ///<
- int new_signatures = 0; ///<
- int new_revocations = 0; ///<
- int secret_read = 0; ///<
- int secret_imported = 0; ///<
- int secret_unchanged = 0; ///<
- int not_imported = 0; ///<
-
- GpgImportedKeyList importedKeys; ///<
-};
+class GpgImportInformation;
/**
* @brief
@@ -103,19 +58,19 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @param inBuffer
* @return GpgImportInformation
*/
- GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+ auto ImportKey(const GFBuffer&) -> std::shared_ptr<GpgImportInformation>;
/**
* @brief
*
- * @param uid_list
- * @param out_buffer
+ * @param key
* @param secret
- * @return true
- * @return false
+ * @param ascii
+ * @return std::tuple<GpgError, GFBuffer>
*/
- bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret = false) const;
+ [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode = false) const
+ -> std::tuple<GpgError, GFBuffer>;
/**
* @brief
@@ -126,67 +81,23 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @return true
* @return false
*/
- bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer,
- bool secret = false) const;
+ void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const;
/**
* @brief
*
* @param keys
- * @param outBuffer
* @param secret
- * @return true
- * @return false
- */
- bool ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
+ * @param ascii
+ * @param cb
*/
- bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKeyShortest(const GpgKey& key,
- ByteArrayPtr& outBuffer) const;
+ void ExportAllKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ const GpgOperationCallback& cb) const;
private:
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgContext& ctx_;
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index e556eec6..b5efe141 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,150 +28,146 @@
#include "GpgKeyManager.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <memory>
-#include <string>
-
-#include "GpgBasicOperator.h"
-#include "GpgKeyGetter.h"
-#include "spdlog/spdlog.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/GpgUtils.h"
GpgFrontend::GpgKeyManager::GpgKeyManager(int channel)
: SingletonFunctionObject<GpgKeyManager>(channel) {}
-bool GpgFrontend::GpgKeyManager::SignKey(
+auto GpgFrontend::GpgKeyManager::SignKey(
const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
- const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
- GpgBasicOperator::GetInstance().SetSigners(keys);
+ const QString& uid, const std::unique_ptr<QDateTime>& expires) -> bool {
+ GpgBasicOperator::GetInstance().SetSigners(keys, true);
unsigned int flags = 0;
unsigned int expires_time_t = 0;
- if (expires == nullptr)
+ if (expires == nullptr) {
flags |= GPGME_KEYSIGN_NOEXPIRE;
- else
- expires_time_t = to_time_t(*expires);
+ } else {
+ expires_time_t = expires->toSecsSinceEpoch();
+ }
- auto err = check_gpg_error(gpgme_op_keysign(
- ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+ auto err = CheckGpgError(
+ gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
+ uid.toUtf8(), expires_time_t, flags));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::RevSign(
+auto GpgFrontend::GpgKeyManager::RevSign(
const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool {
auto& key_getter = GpgKeyGetter::GetInstance();
for (const auto& sign_id : *signature_id) {
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- auto err = check_gpg_error(gpgme_op_revsig(ctx_, gpgme_key_t(key),
- gpgme_key_t(signing_key),
- sign_id.second.c_str(), 0));
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false;
+ auto err = CheckGpgError(
+ gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
+ gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0));
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
}
return true;
}
-bool GpgFrontend::GpgKeyManager::SetExpire(
- const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
+auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
+ std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires)
+ -> bool {
unsigned long expires_time = 0;
- if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+ if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
const char* sub_fprs = nullptr;
- if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
+ if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().toUtf8();
- auto err = check_gpg_error(
- gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0));
+ auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ expires_time, sub_fprs, 0));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
- int trust_level) {
+auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
+ int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
- SPDLOG_ERROR("illegal owner trust level: {}", trust_level);
+ GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
}
- AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, std::string status, std::string args) {
- SPDLOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
- state, status, args);
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
-
- switch (state) {
- case AS_START:
- if (status == "GET_LINE" && args == "keyedit.prompt")
- return AS_COMMAND;
- return AS_ERROR;
- case AS_COMMAND:
- if (status == "GET_LINE" && args == "edit_ownertrust.value") {
- return AS_VALUE;
- }
- return AS_ERROR;
- case AS_VALUE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- } else if (status == "GET_BOOL" &&
- args == "edit_ownertrust.set_ultimate.okay") {
- return AS_REALLY_ULTIMATE;
- }
- return AS_ERROR;
- case AS_REALLY_ULTIMATE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- case AS_QUIT:
- if (status == "GET_LINE" && args == "keyedit.save.okay") {
- return AS_SAVE;
- }
- return AS_ERROR;
- case AS_ERROR:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- default:
- return AS_ERROR;
- };
- };
+ AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
+ QString status,
+ QString args) {
+ GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
+ state, status, args);
+ auto tokens = args.split(' ');
+
+ switch (state) {
+ case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_COMMAND;
+ }
+ return AS_ERROR;
+ case AS_COMMAND:
+ if (status == "GET_LINE" && args == "edit_ownertrust.value") {
+ return AS_VALUE;
+ }
+ return AS_ERROR;
+ case AS_VALUE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ } else if (status == "GET_BOOL" &&
+ args == "edit_ownertrust.set_ultimate.okay") {
+ return AS_REALLY_ULTIMATE;
+ }
+ return AS_ERROR;
+ case AS_REALLY_ULTIMATE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ case AS_QUIT:
+ if (status == "GET_LINE" && args == "keyedit.save.okay") {
+ return AS_SAVE;
+ }
+ return AS_ERROR;
+ case AS_ERROR:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ default:
+ return AS_ERROR;
+ };
+ };
AutomatonActionHandler action_handler =
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
- SPDLOG_DEBUG("action_handler state: {}", state);
+ GF_CORE_LOG_DEBUG("action_handler state: {}", state);
switch (state) {
case AS_COMMAND:
- return std::string("trust");
+ return QString("trust");
case AS_VALUE:
handler.SetSuccess(true);
- return std::to_string(trust_level);
+ return QString::number(trust_level);
case AS_REALLY_ULTIMATE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_QUIT:
- return std::string("quit");
+ return QString("quit");
case AS_SAVE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_START:
case AS_ERROR:
- return std::string("");
+ return QString("");
default:
- return std::string("");
+ return QString("");
}
- return std::string("");
+ return QString("");
};
auto key_fpr = key.GetFingerprint();
@@ -180,49 +176,44 @@ bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
GpgData data_out;
- auto err = gpgme_op_interact(ctx_, gpgme_key_t(key), 0,
- GpgKeyManager::interactor_cb_fnc,
- (void*)&handel_struct, data_out);
- if (err != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
- trust_level, key.GetId(), gpgme_strerror(err));
- }
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR &&
- handel_struct.Success();
+ auto err =
+ gpgme_op_interact(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
+ GpgKeyManager::interactor_cb_fnc,
+ static_cast<void*>(&handel_struct), data_out);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR && handel_struct.Success();
}
-gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
- const char* status,
- const char* args,
- int fd) {
- auto handle_struct = static_cast<AutomatonHandelStruct*>(handle);
- std::string status_s = status;
- std::string args_s = args;
- SPDLOG_DEBUG("cb start status: {}, args: {}, fd: {}, handle struct state: {}",
- status_s, args_s, fd, handle_struct->CuurentStatus());
+auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
+ const char* status,
+ const char* args, int fd)
+ -> gpgme_error_t {
+ auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
+ QString status_s = status;
+ QString args_s = args;
+ GF_CORE_LOG_DEBUG(
+ "cb start status: {}, args: {}, fd: {}, handle struct state: {}",
+ status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
+ auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- SPDLOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
- handle_struct->KeyFpr(), tokens[0]);
+ GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
+ handle_struct->KeyFpr(), tokens[0]);
return -1;
}
return 0;
}
- if (status_s == "GOT_IT" || status_s.empty()) {
- SPDLOG_DEBUG("status GOT_IT, continue...");
+ if (status_s == "GOT_IT" || status_s.isEmpty()) {
+ GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
- SPDLOG_DEBUG("handle struct next state caught error, skipping...");
+ GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@@ -233,10 +224,11 @@ gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
- SPDLOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
- next_state, cmd);
- if (!cmd.empty()) {
- gpgme_io_write(fd, cmd.c_str(), cmd.size());
+ GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
+ next_state, cmd);
+ if (!cmd.isEmpty()) {
+ auto btye_array = cmd.toUtf8();
+ gpgme_io_write(fd, btye_array, btye_array.size());
gpgme_io_write(fd, "\n", 1);
} else if (status_s == "GET_LINE") {
// avoid trapping in this state
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index 62f7baca..8b4d41b2 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#pragma once
#include <functional>
-#include <string>
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -60,8 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @param expires expire date and time of the signature
* @return if successful
*/
- bool SignKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SignKey(const GpgKey& target, KeyArgsList& keys, const QString& uid,
+ const std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
@@ -71,8 +69,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool RevSign(const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id);
+ auto RevSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool;
/**
* @brief Set the Expire object
@@ -83,21 +81,21 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
*
* @return
*/
- bool SetOwnerTrustLevel(const GpgKey& key, int trust_level);
+ auto SetOwnerTrustLevel(const GpgKey& key, int trust_level) -> bool;
private:
- static gpgme_error_t interactor_cb_fnc(void* handle, const char* status,
- const char* args, int fd);
+ static auto interactor_cb_fnc(void* handle, const char* status,
+ const char* args, int fd) -> gpgme_error_t;
- using Command = std::string;
+ using Command = QString;
using AutomatonState = enum {
AS_START,
AS_COMMAND,
@@ -113,35 +111,37 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
using AutomatonActionHandler =
std::function<Command(AutomatonHandelStruct&, AutomatonState)>;
using AutomatonNextStateHandler =
- std::function<AutomatonState(AutomatonState, std::string, std::string)>;
+ std::function<AutomatonState(AutomatonState, QString, QString)>;
struct AutomatonHandelStruct {
void SetStatus(AutomatonState next_state) { current_state_ = next_state; }
- AutomatonState CuurentStatus() { return current_state_; }
+ auto CuurentStatus() -> AutomatonState { return current_state_; }
void SetHandler(AutomatonNextStateHandler next_state_handler,
AutomatonActionHandler action_handler) {
- next_state_handler_ = next_state_handler;
- action_handler_ = action_handler;
+ next_state_handler_ = std::move(next_state_handler);
+ action_handler_ = std::move(action_handler);
}
- AutomatonState NextState(std::string gpg_status, std::string args) {
- return next_state_handler_(current_state_, gpg_status, args);
+ auto NextState(QString gpg_status, QString args) -> AutomatonState {
+ return next_state_handler_(current_state_, std::move(gpg_status),
+ std::move(args));
}
- Command Action() { return action_handler_(*this, current_state_); }
+ auto Action() -> Command { return action_handler_(*this, current_state_); }
void SetSuccess(bool success) { success_ = success; }
- bool Success() { return success_; }
+ [[nodiscard]] auto Success() const -> bool { return success_; }
- std::string KeyFpr() { return key_fpr_; }
+ auto KeyFpr() -> QString { return key_fpr_; }
- AutomatonHandelStruct(std::string key_fpr) : key_fpr_(key_fpr) {}
+ explicit AutomatonHandelStruct(QString key_fpr)
+ : key_fpr_(std::move(key_fpr)) {}
private:
AutomatonState current_state_ = AS_START;
AutomatonNextStateHandler next_state_handler_;
AutomatonActionHandler action_handler_;
bool success_ = false;
- std::string key_fpr_;
+ QString key_fpr_;
};
GpgContext& ctx_ =
@@ -149,5 +149,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index d5919cff..118f4784 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,38 +28,42 @@
#include "GpgKeyOpera.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/format.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <string>
-#include <vector>
+#include <gpg-error.h>
-#include "GpgCommandExecutor.h"
-#include "GpgKeyGetter.h"
-#include "core/GpgConstants.h"
-#include "core/GpgGenKeyInfo.h"
+#include <memory>
-GpgFrontend::GpgKeyOpera::GpgKeyOpera(int channel)
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgGenerateKeyResult.h"
+#include "core/module/ModuleManager.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend {
+
+GpgKeyOpera::GpgKeyOpera(int channel)
: SingletonFunctionObject<GpgKeyOpera>(channel) {}
/**
* Delete keys
* @param uidList key ids
*/
-void GpgFrontend::GpgKeyOpera::DeleteKeys(
- GpgFrontend::KeyIdArgsListPtr key_ids) {
+void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
GpgError err;
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.IsGood()) {
- err = check_gpg_error(
- gpgme_op_delete_ext(ctx_, gpgme_key_t(key),
- GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ err = CheckGpgError(gpgme_op_delete_ext(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
+ GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
}
}
}
@@ -72,26 +76,24 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
* @param expires date and time
* @return if successful
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
- const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
+auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError {
unsigned long expires_time = 0;
if (expires != nullptr) {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires_time =
- to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
+ expires_time = QDateTime::currentDateTime().secsTo(*expires);
}
- SPDLOG_DEBUG(key.GetId(), subkey_fpr, expires_time);
-
GpgError err;
- if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty())
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, nullptr, 0);
- else
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time,
- subkey_fpr.c_str(), 0);
+ if (key.GetFingerprint() == subkey_fpr || subkey_fpr.isEmpty()) {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, nullptr, 0);
+ } else {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, subkey_fpr.toUtf8(), 0);
+ }
return err;
}
@@ -102,48 +104,52 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
* @param outputFileName out file name(path)
* @return the process doing this job
*/
-void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
- const GpgKey& key, const std::string& output_file_path) {
+void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
+ const QString& output_path) {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
// get all components
- GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().AppPath,
- {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
- output_file_path, "--gen-revoke", key.GetFingerprint().c_str()},
- [=](int exit_code, const std::string& p_out, const std::string& p_err) {
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
- } else {
- SPDLOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
- }
- },
- [](QProcess* proc) -> void {
- // Code From Gpg4Win
- while (proc->canReadLine()) {
- const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- SPDLOG_DEBUG("line: {}", line.toStdString());
- if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.code")) {
- proc->write("0\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.text")) {
- proc->write("\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
- // We asked before
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
- "ask_revocation_reason.okay")) {
- proc->write("y\n");
- }
- }
- });
+ GpgCommandExecutor::ExecuteSync(
+ {app_path,
+ QStringList{"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
+ output_path, "--gen-revoke", key.GetFingerprint()},
+ [=](int exit_code, const QString& p_out, const QString& p_err) {
+ if (exit_code != 0) {
+ GF_CORE_LOG_ERROR(
+ "gnupg gen revoke execute error, process stderr: {}, process "
+ "stdout: {}",
+ p_err, p_out);
+ } else {
+ GF_CORE_LOG_DEBUG(
+ "gnupg gen revoke exit_code: {}, process stdout size: {}",
+ exit_code, p_out.size());
+ }
+ },
+ nullptr,
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ GF_CORE_LOG_DEBUG("line: {}", line.toStdString());
+ if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.code")) {
+ proc->write("0\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.text")) {
+ proc->write("\n");
+ } else if (line ==
+ QLatin1String(
+ "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
+ // We asked before
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
+ "ask_revocation_reason.okay")) {
+ proc->write("y\n");
+ }
+ }
+ }});
}
/**
@@ -151,138 +157,366 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
* @param params key generation args
* @return error information
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
- const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) {
- auto userid_utf8 = params->GetUserid();
- const char* userid = userid_utf8.c_str();
- auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
-
- SPDLOG_DEBUG("params: {} {}", params->GetAlgo(), params->GetKeySizeStr());
-
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
+void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid();
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
+ expires, flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
+ algo.toUtf8(), 0, expires, nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- GpgError err;
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey", "2.1.0");
+}
- SPDLOG_DEBUG("ctx version, {}", ctx_.GetInfo(false).GnupgVersion);
+auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=, &ctx = ctx_](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid();
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
+ expires, flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
+ algo.toUtf8(), 0, expires, nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") {
- unsigned int flags = 0;
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createkey", "2.1.0");
+}
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {}, key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ algo.toUtf8(), 0, expires, flags);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- SPDLOG_DEBUG("args: {}", userid, algo, expires, flags);
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createsubkey", "2.1.13");
+}
- err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
+auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
+ flags);
+
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ algo.toUtf8(), 0, expires, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- } else {
- std::stringstream ss;
- auto param_format =
- boost::format{
- "<GnupgKeyParms format=\"internal\">\n"
- "Key-Type: %1%\n"
- "Key-Usage: sign\n"
- "Key-Length: %2%\n"
- "Name-Real: %3%\n"
- "Name-Comment: %4%\n"
- "Name-Email: %5%\n"} %
- params->GetAlgo() % params->GetKeyLength() % params->GetName() %
- params->GetComment() % params->GetEmail();
- ss << param_format;
-
- if (!params->IsNonExpired()) {
- auto date = params->GetExpireTime().date();
- ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date);
- } else
- ss << boost::format{"Expire-Date: 0\n"};
- if (!params->IsNoPassPhrase())
- ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase();
-
- ss << "</GnupgKeyParms>";
-
- SPDLOG_DEBUG("params: {}", ss.str());
-
- err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
- }
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createsubkey", "2.1.13");
+}
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_genkey_result(ctx_));
- std::swap(temp_result, result);
- }
+void GpgKeyOpera::GenerateKeyWithSubkey(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
+
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
+
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) {
+ data_object->Swap({genkey_result});
+ return err;
+ }
+
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
+
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
+
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+
+ err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-/**
- * Generate a new subkey of a certain key pair
- * @param key target key pair
- * @param params opera args
- * @return error info
- */
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
- if (!params->IsSubKey()) return GPG_ERR_CANCELED;
-
- SPDLOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(),
- params->GetKeySizeStr());
-
- auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
- unsigned int flags = 0;
+auto GpgKeyOpera::GenerateKeyWithSubkeySync(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
+
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) {
+ data_object->Swap({genkey_result});
+ return err;
+ }
- SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
+
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
+
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+
+ err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- auto err =
- gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
- const GpgFrontend::GpgKey& key) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") {
- SPDLOG_ERROR("operator not support");
- return GPG_ERR_NOT_SUPPORTED;
- }
- auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
- return check_gpg_error(err);
+void GpgKeyOpera::ModifyPassword(const GpgKey& key,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
+ return gpgme_op_passwd(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), 0);
+ },
+ callback, "gpgme_op_passwd", "2.0.15");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
- const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") {
- SPDLOG_ERROR("operator not support");
+
+auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
+ gpgme_tofu_policy_t tofu_policy)
+ -> GpgError {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+
+ if (CompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
+ GF_CORE_LOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
- auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
- return check_gpg_error(err);
+
+ auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), tofu_policy);
+ return CheckGpgError(err);
}
-void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
+void GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
auto keys = std::make_unique<KeyIdArgsList>();
keys->push_back(key_id);
DeleteKeys(std::move(keys));
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h
index 5446bd66..6ffe437c 100644
--- a/src/core/function/gpg/GpgKeyOpera.h
+++ b/src/core/function/gpg/GpgKeyOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYOPERA_H
-#define _GPGKEYOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include <functional>
+
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -77,8 +77,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param expires
* @return GpgError
*/
- GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError;
/**
* @brief
@@ -86,8 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @param output_file_name
*/
- void GenerateRevokeCert(const GpgKey& key,
- const std::string& output_file_name);
+ void GenerateRevokeCert(const GpgKey& key, const QString& output_path);
/**
* @brief
@@ -95,7 +94,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyPassword(const GpgKey& key);
+ void ModifyPassword(const GpgKey& key, const GpgOperationCallback&);
/**
* @brief
@@ -104,8 +103,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param tofu_policy
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key,
- gpgme_tofu_policy_t tofu_policy);
+ auto ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy)
+ -> GpgFrontend::GpgError;
/**
* @brief
*
@@ -113,8 +112,16 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param result
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params,
- GpgGenKeyResult& result);
+ void GenerateKey(const std::shared_ptr<GenKeyInfo>&,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param params
+ */
+ auto GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -123,13 +130,45 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param params
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+ void GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param params
+ */
+ auto GenerateSubkeySync(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback);
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ auto GenerateKeyWithSubkeySync(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params)
+ -> std::tuple<GpgError, DataObjectPtr>;
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 7e7a711e..6c0373de 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,44 +28,38 @@
#include "GpgUIDOperator.h"
-#include "boost/format.hpp"
+#include "core/GpgModel.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgUIDOperator::GpgUIDOperator(int channel)
+namespace GpgFrontend {
+
+GpgUIDOperator::GpgUIDOperator(int channel)
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = gpgme_op_adduid(ctx_, gpgme_key_t(key), uid.c_str(), 0);
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = gpgme_op_adduid(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), uid.toUtf8(), 0);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::RevUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err =
- check_gpg_error(gpgme_op_revuid(ctx_, gpgme_key_t(key), uid.c_str(), 0));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = CheckGpgError(gpgme_op_revuid(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(), 0));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::SetPrimaryUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = check_gpg_error(gpgme_op_set_uid_flag(
- ctx_, gpgme_key_t(key), uid.c_str(), "primary", nullptr));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
+ -> bool {
+ auto err = CheckGpgError(gpgme_op_set_uid_flag(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
+ "primary", nullptr));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& name,
- const std::string& comment,
- const std::string& email) {
- SPDLOG_DEBUG("new uuid: {} {} {}", name, comment, email);
- auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
- return AddUID(key, uid.str());
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
+ const QString& comment, const QString& email)
+ -> bool {
+ GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
+ return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
index c4a7d87b..b2cec8bc 100644
--- a/src/core/function/gpg/GpgUIDOperator.h
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#pragma once
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -54,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid uid args(combine name&comment&email)
* @return if successful
*/
- bool AddUID(const GpgKey& key, const std::string& uid);
+ auto AddUID(const GpgKey& key, const QString& uid) -> bool;
/**
* create a new uid in certain key pair
@@ -64,8 +63,8 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param email
* @return
*/
- bool AddUID(const GpgKey& key, const std::string& name,
- const std::string& comment, const std::string& email);
+ auto AddUID(const GpgKey& key, const QString& name, const QString& comment,
+ const QString& email) -> bool;
/**
* Revoke(Delete) UID from certain key pair
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool RevUID(const GpgKey& key, const std::string& uid);
+ auto RevUID(const GpgKey& key, const QString& uid) -> bool;
/**
* Set one of a uid of a key pair as primary
@@ -81,7 +80,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool SetPrimaryUID(const GpgKey& key, const std::string& uid);
+ auto SetPrimaryUID(const GpgKey& key, const QString& uid) -> bool;
private:
GpgContext& ctx_ =
@@ -89,5 +88,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
index d3ec8d6e..5d0ce920 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,70 +28,103 @@
#include "GpgDecryptResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse(
- GpgError m_error, GpgDecrResult m_result)
- : error_(m_error), result_(std::move(m_result)) {}
+ GpgError m_error, GpgDecryptResult m_result)
+ : error_(m_error), result_(m_result) {}
-void GpgFrontend::GpgDecryptResultAnalyse::do_analyse() {
- stream_ << "[#] " << _("Decrypt Operation");
+void GpgFrontend::GpgDecryptResultAnalyse::doAnalyse() {
+ auto *result = result_.GetRaw();
+
+ stream_ << "# " << tr("Decrypt Operation") << " ";
if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
- stream_ << "[" << _("Success") << "]" << std::endl;
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
} else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
- if (result_ != nullptr && result_->unsupported_algorithm != nullptr) {
- stream_ << "------------>" << std::endl;
- stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm
- << std::endl;
+ stream_ << "- " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
+ if (result != nullptr && result->unsupported_algorithm != nullptr) {
+ stream_ << Qt::endl;
+ stream_ << "## " << tr("Unsupported Algo") << ": "
+ << result->unsupported_algorithm << Qt::endl;
}
}
- if (result_ != nullptr && result_->recipients != nullptr) {
- stream_ << "------------>" << std::endl;
- if (result_->file_name != nullptr) {
- stream_ << _("File Name") << ": " << result_->file_name << std::endl;
- stream_ << std::endl;
+ if (result != nullptr && result->recipients != nullptr) {
+ stream_ << Qt::endl;
+
+ stream_ << "## " << tr("Gernal State") << ": " << Qt::endl;
+
+ if (result->file_name != nullptr) {
+ stream_ << "- " << tr("File Name") << ": " << result->file_name
+ << Qt::endl;
+ }
+ stream_ << "- " << tr("MIME") << ": "
+ << (result->is_mime == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << "- " << tr("Message Integrity Protection") << ": "
+ << (result->legacy_cipher_nomdc == 0 ? tr("true") : tr("false"))
+ << Qt::endl;
+ if (result->legacy_cipher_nomdc == 1) setStatus(0); /// < unsafe situation
+
+ if (result->symkey_algo != nullptr) {
+ stream_ << "- " << tr("Symmetric Encryption Algorithm") << ": "
+ << result->symkey_algo << Qt::endl;
+ }
+
+ if (result->session_key != nullptr) {
+ stream_ << "- " << tr("Session Key") << ": " << result->session_key
+ << Qt::endl;
}
- if (result_->is_mime) {
- stream_ << _("MIME") << ": " << _("true") << std::endl;
+
+ stream_ << "- " << tr("German Encryption Standards") << ": "
+ << (result->is_de_vs == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << Qt::endl << Qt::endl;
+
+ auto *recipient = result->recipients;
+ auto index = 0;
+ if (recipient != nullptr) {
+ stream_ << "## " << tr("Recipient(s)") << ": " << Qt::endl << Qt::endl;
}
- auto recipient = result_->recipients;
- if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl;
while (recipient != nullptr) {
+ // check
+ if (recipient->keyid == nullptr) return;
+ stream_ << "### " << tr("Recipient") << " [" << ++index << "]: ";
print_recipient(stream_, recipient);
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
recipient = recipient->next;
}
- stream_ << "<------------" << std::endl;
+
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
void GpgFrontend::GpgDecryptResultAnalyse::print_recipient(
- std::stringstream &stream, gpgme_recipient_t recipient) {
- // check
- if (recipient->keyid == nullptr) return;
-
- stream << " {>} " << _("Recipient") << ": ";
+ QTextStream &stream, gpgme_recipient_t recipient) {
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid);
if (key.IsGood()) {
- stream << key.GetName().c_str();
- if (!key.GetEmail().empty()) {
- stream << "<" << key.GetEmail().c_str() << ">";
- }
+ stream << key.GetName();
+ if (!key.GetComment().isEmpty()) stream << "(" << key.GetComment() << ")";
+ if (!key.GetEmail().isEmpty()) stream << "<" << key.GetEmail() << ">";
} else {
- stream << "<" << _("Unknown") << ">";
- set_status(0);
+ stream << "<" << tr("unknown") << ">";
+ setStatus(0);
}
- stream << std::endl;
+ stream << Qt::endl;
- stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl;
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl;
+ stream << "- " << tr("Key ID") << ": " << recipient->keyid << Qt::endl;
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(recipient->pubkey_algo) << Qt::endl;
+ stream << "- " << tr("Status") << ": " << gpgme_strerror(recipient->status)
+ << Qt::endl;
}
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
index 1fc08d1f..c795e025 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgDecryptResult.h"
namespace GpgFrontend {
@@ -40,6 +39,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Decrypt Result Analyse object
@@ -47,14 +47,14 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param m_error
* @param m_result
*/
- explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result);
+ explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecryptResult m_result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
/**
@@ -63,12 +63,10 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param stream
* @param recipient
*/
- void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient);
+ void print_recipient(QTextStream &stream, gpgme_recipient_t recipient);
- GpgError error_; ///<
- GpgDecrResult result_; ///<
+ GpgError error_; ///<
+ GpgDecryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
index 21d37eab..a6b18b0a 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,39 +28,53 @@
#include "GpgEncryptResultAnalyse.h"
-GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(
- GpgError error, GpgEncrResult result)
- : error_(error), result_(std::move(result)) {}
+#include "core/model/GpgEncryptResult.h"
-void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start encrypt result analyse");
+namespace GpgFrontend {
- stream_ << "[#] " << _("Encrypt Operation") << " ";
+GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(GpgError error,
+ GpgEncryptResult result)
+ : error_(error), result_(result) {}
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+void GpgEncryptResultAnalyse::doAnalyse() {
+ stream_ << "# " << tr("Encrypt Operation") << " ";
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << "- " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (!~status_) {
- stream_ << "------------>" << std::endl;
- if (result_ != nullptr) {
- stream_ << _("Invalid Recipients") << ": " << std::endl;
- auto inv_reci = result_->invalid_recipients;
+ if ((~status_) == 0) {
+ stream_ << Qt::endl;
+
+ const auto *result = result_.GetRaw();
+
+ if (result != nullptr) {
+ stream_ << "## " << tr("Invalid Recipients") << ": " << Qt::endl
+ << Qt::endl;
+
+ auto *inv_reci = result->invalid_recipients;
+ auto index = 0;
+
while (inv_reci != nullptr) {
- stream_ << _("Fingerprint") << ": " << inv_reci->fpr << std::endl;
- stream_ << _("Reason") << ": " << gpgme_strerror(inv_reci->reason)
- << std::endl;
- stream_ << std::endl;
+ stream_ << "### " << tr("Recipients") << " " << ++index << ": "
+ << Qt::endl;
+ stream_ << "- " << tr("Fingerprint") << ": " << inv_reci->fpr
+ << Qt::endl;
+ stream_ << "- " << tr("Reason") << ": "
+ << gpgme_strerror(inv_reci->reason) << Qt::endl;
+ stream_ << Qt::endl << Qt::endl;
inv_reci = inv_reci->next;
}
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
index 6811ef06..e9594628 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgEncryptResult.h"
namespace GpgFrontend {
/**
@@ -39,6 +38,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Encrypt Result Analyse object
@@ -46,19 +46,17 @@ class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
* @param error
* @param result
*/
- explicit GpgEncryptResultAnalyse(GpgError error, GpgEncrResult result);
+ explicit GpgEncryptResultAnalyse(GpgError error, GpgEncryptResult result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
- GpgError error_; ///<
- GpgEncrResult result_; ///<
+ GpgError error_; ///<
+ GpgEncryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.cpp b/src/core/function/result_analyse/GpgResultAnalyse.cpp
index 40ba4c3e..4c1f44e7 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,19 +28,19 @@
#include "GpgResultAnalyse.h"
-const std::string GpgFrontend::GpgResultAnalyse::GetResultReport() const {
- return stream_.str();
+auto GpgFrontend::GpgResultAnalyse::GetResultReport() const -> const QString {
+ return *stream_.string();
}
-int GpgFrontend::GpgResultAnalyse::GetStatus() const { return status_; }
+auto GpgFrontend::GpgResultAnalyse::GetStatus() const -> int { return status_; }
-void GpgFrontend::GpgResultAnalyse::set_status(int m_status) {
+void GpgFrontend::GpgResultAnalyse::setStatus(int m_status) {
if (m_status < status_) status_ = m_status;
}
void GpgFrontend::GpgResultAnalyse::Analyse() {
if (!analysed_) {
- do_analyse();
+ doAnalyse();
analysed_ = true;
}
}
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h
index e609505f..9958b6a2 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,21 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGRESULTANALYSE_H
-#define GPGFRONTEND_GPGRESULTANALYSE_H
+#pragma once
#include <sstream>
-#include <string>
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
+
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
+class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse : public QObject {
+ Q_OBJECT
public:
/**
* @brief Construct a new Result Analyse object
@@ -45,16 +45,16 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
/**
* @brief Get the Result Report object
*
- * @return const std::string
+ * @return const QString
*/
- [[nodiscard]] const std::string GetResultReport() const;
+ [[nodiscard]] auto GetResultReport() const -> const QString;
/**
* @brief Get the Status object
*
* @return int
*/
- [[nodiscard]] int GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> int;
/**
* @brief
@@ -67,20 +67,19 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
* @brief
*
*/
- virtual void do_analyse() = 0;
+ virtual void doAnalyse() = 0;
/**
* @brief Set the status object
*
* @param m_status
*/
- void set_status(int m_status);
+ void setStatus(int m_status);
- std::stringstream stream_; ///<
- int status_ = 1; ///<
- bool analysed_ = false; ///<
+ QString buffer_;
+ QTextStream stream_ = QTextStream(&buffer_); ///<
+ int status_ = 1; ///<
+ bool analysed_ = false; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
index e4d1354f..bf429f38 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,88 +28,98 @@
#include "GpgSignResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/LocalizedUtils.h"
-GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error,
- GpgSignResult result)
+namespace GpgFrontend {
+
+GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error, GpgSignResult result)
: error_(error), result_(std::move(result)) {}
-void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start sign result analyse");
+void GpgSignResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Sign Operation") << " ";
+ stream_ << "# " << tr("Sign Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << "- " << tr("Failed") << " " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (result_ != nullptr &&
- (result_->signatures != nullptr || result_->invalid_signers != nullptr)) {
- SPDLOG_DEBUG("sign result analyse getting result");
- stream_ << "------------>" << std::endl;
- auto new_sign = result_->signatures;
+ if (result != nullptr &&
+ (result->signatures != nullptr || result->invalid_signers != nullptr)) {
+ stream_ << Qt::endl;
+ auto *new_sign = result->signatures;
+ auto index = 0;
while (new_sign != nullptr) {
- stream_ << "[>]" << _("New Signature") << ": " << std::endl;
-
- SPDLOG_DEBUG("signers fingerprint: ", new_sign->fpr);
-
- stream_ << " " << _("Sign Mode") << ": ";
- if (new_sign->type == GPGME_SIG_MODE_NORMAL)
- stream_ << _("Normal");
- else if (new_sign->type == GPGME_SIG_MODE_CLEAR)
- stream_ << _("Clear");
- else if (new_sign->type == GPGME_SIG_MODE_DETACH)
- stream_ << _("Detach");
+ stream_ << "## " << tr("New Signature") << " [" << ++index
+ << "]: " << Qt::endl;
+
+ stream_ << "- " << tr("Sign Mode") << ": ";
+ if (new_sign->type == GPGME_SIG_MODE_NORMAL) {
+ stream_ << tr("Normal");
+ } else if (new_sign->type == GPGME_SIG_MODE_CLEAR) {
+ stream_ << tr("Clear");
+ } else if (new_sign->type == GPGME_SIG_MODE_DETACH) {
+ stream_ << tr("Detach");
+ }
- stream_ << std::endl;
+ stream_ << Qt::endl;
- auto singerKey =
- GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
- if (singerKey.IsGood()) {
- stream_ << " " << _("Signer") << ": "
- << singerKey.GetUIDs()->front().GetUID() << std::endl;
+ auto singer_key = GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
+ if (singer_key.IsGood()) {
+ stream_ << "- " << tr("Signer") << ": "
+ << singer_key.GetUIDs()->front().GetUID() << Qt::endl;
} else {
- stream_ << " " << _("Signer") << ": "
- << "<unknown>" << std::endl;
+ stream_ << "- " << tr("Signer") << ": "
+ << "<unknown>" << Qt::endl;
}
- stream_ << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl;
- stream_ << " " << _("Hash Algo") << ": "
- << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl;
- stream_ << " " << _("Date") << "(" << _("UTC") << ")"
+ stream_ << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << Qt::endl;
+ stream_ << "- " << tr("Hash Algo") << ": "
+ << gpgme_hash_algo_name(new_sign->hash_algo) << Qt::endl;
+ stream_ << "- " << tr("Date") << "(" << tr("UTC") << ")"
<< ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(new_sign->timestamp))
- << std::endl;
+ << QDateTime::fromSecsSinceEpoch(new_sign->timestamp).toString()
+ << Qt::endl;
+ stream_ << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(new_sign->timestamp)
+ << Qt::endl;
- stream_ << std::endl;
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
new_sign = new_sign->next;
}
- SPDLOG_DEBUG("sign result analyse getting invalid signer");
+ auto *invalid_signer = result->invalid_signers;
+ stream_ << Qt::endl;
- auto invalid_signer = result_->invalid_signers;
-
- if (invalid_signer != nullptr)
- stream_ << _("Invalid Signers") << ": " << std::endl;
+ if (invalid_signer != nullptr) {
+ stream_ << "## " << tr("Invalid Signers") << ": " << Qt::endl;
+ }
+ index = 0;
while (invalid_signer != nullptr) {
- set_status(0);
- stream_ << "[>] " << _("Signer") << ": " << std::endl;
- stream_ << " " << _("Fingerprint") << ": " << invalid_signer->fpr
- << std::endl;
- stream_ << " " << _("Reason") << ": "
- << gpgme_strerror(invalid_signer->reason) << std::endl;
- stream_ << std::endl;
+ setStatus(0);
+ stream_ << "### " << tr("Signer") << " [" << ++index << "]: " << Qt::endl
+ << Qt::endl;
+ stream_ << "- " << tr("Fingerprint") << ": " << invalid_signer->fpr
+ << Qt::endl;
+ stream_ << "- " << tr("Reason") << ": "
+ << gpgme_strerror(invalid_signer->reason) << Qt::endl;
+ stream_ << "---------------------------------------" << Qt::endl;
invalid_signer = invalid_signer->next;
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
-} \ No newline at end of file
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h
index 43a78942..58a20417 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSIGNRESULTANALYSE_H
-#define GPGFRONTEND_GPGSIGNRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
+#include "core/model/GpgSignResult.h"
namespace GpgFrontend {
@@ -38,6 +38,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Sign Result Analyse object
@@ -52,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() override;
private:
GpgError error_; ///<
@@ -61,5 +62,3 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSIGNRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
index b19db5b2..618275f9 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,188 +28,200 @@
#include "GpgVerifyResultAnalyse.h"
-#include <boost/format.hpp>
-
#include "GpgFrontend.h"
-#include "core/GpgConstants.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/LocalizedUtils.h"
GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(
GpgError error, GpgVerifyResult result)
- : error_(error), result_(std::move(result)) {}
+ : error_(error), result_(result) {}
-void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("started");
+void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Verify Operation") << " ";
+ stream_ << "# " << tr("Verify Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << " - " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << " - " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (result_ != nullptr && result_->signatures != nullptr) {
- stream_ << "------------>" << std::endl;
- auto sign = result_->signatures;
+ if (result != nullptr && result->signatures != nullptr) {
+ stream_ << Qt::endl;
+ auto *sign = result->signatures;
+
+ stream_ << "-> " << tr("Signed On") << "(" << tr("UTC") << ")"
+ << ": " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
- stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")"
- << " "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
+ stream_ << "-> " << tr("Signed On") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
- stream_ << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
+ stream_ << Qt::endl << "## " << tr("Signatures List") << ":" << Qt::endl;
+ stream_ << Qt::endl;
- bool canContinue = true;
+ bool can_continue = true;
int count = 1;
- while (sign && canContinue) {
- stream_ << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
+ while ((sign != nullptr) && can_continue) {
+ stream_ << "### " << tr("Signature [%1]:").arg(count++) << Qt::endl;
+ stream_ << "- " << tr("Status") << ": ";
switch (gpg_err_code(sign->status)) {
case GPG_ERR_BAD_SIGNATURE:
- stream_ << _("A Bad Signature.") << std::endl;
+ stream_ << tr("A Bad Signature.") << Qt::endl;
print_signer(stream_, sign);
- stream_ << _("This Signature is invalid.") << std::endl;
- canContinue = false;
- set_status(-1);
+ stream_ << tr("This Signature is invalid.") << Qt::endl;
+ can_continue = false;
+ setStatus(-1);
break;
case GPG_ERR_NO_ERROR:
- stream_ << _("A") << " ";
- if (sign->summary & GPGME_SIGSUM_GREEN) {
- stream_ << _("Good") << " ";
+ stream_ << tr("A") << " ";
+ if ((sign->summary & GPGME_SIGSUM_GREEN) != 0) {
+ stream_ << tr("Good") << " ";
}
- if (sign->summary & GPGME_SIGSUM_RED) {
- stream_ << _("Bad") << " ";
+ if ((sign->summary & GPGME_SIGSUM_RED) != 0) {
+ stream_ << tr("Bad") << " ";
}
- if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
- stream_ << _("Expired") << " ";
+ if ((sign->summary & GPGME_SIGSUM_SIG_EXPIRED) != 0) {
+ stream_ << tr("Expired") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
- stream_ << _("Missing Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_MISSING) != 0) {
+ stream_ << tr("Missing Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
- stream_ << _("Revoked Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_REVOKED) != 0) {
+ stream_ << tr("Revoked Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
- stream_ << _("Expired Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_EXPIRED) != 0) {
+ stream_ << tr("Expired Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
- stream_ << _("Missing CRL's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_CRL_MISSING) != 0) {
+ stream_ << tr("Missing CRL's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_VALID) {
- stream_ << _("Signature Fully Valid.") << std::endl;
+ if ((sign->summary & GPGME_SIGSUM_VALID) != 0) {
+ stream_ << tr("Signature Fully Valid.") << Qt::endl;
} else {
- stream_ << _("Signature Not Fully Valid.") << std::endl;
- stream_ << _("(May used a subkey to sign)") << std::endl;
+ stream_ << tr("Signature Not Fully Valid.") << Qt::endl;
+ stream_ << tr("(Adjust Trust Level to make it Fully Vaild)")
+ << Qt::endl;
}
- if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
- if (!print_signer(stream_, sign)) set_status(0);
+ if ((sign->status & GPGME_SIGSUM_KEY_MISSING) == 0U) {
+ if (!print_signer(stream_, sign)) setStatus(0);
} else {
- stream_ << _("Key is NOT present with ID 0x") << sign->fpr
- << std::endl;
+ stream_ << tr("Key is NOT present with ID 0x") << sign->fpr
+ << Qt::endl;
}
- set_status(1);
+ setStatus(1);
break;
case GPG_ERR_NO_PUBKEY:
- stream_ << _("A signature could NOT be verified due to a Missing Key")
- << std::endl;
- set_status(-2);
+ stream_
+ << tr("A signature could NOT be verified due to a Missing Key")
+ << Qt::endl;
+ setStatus(-2);
break;
case GPG_ERR_CERT_REVOKED:
- stream_ << _("A signature is valid but the key used to verify the "
- "signature has been revoked")
- << std::endl;
+ stream_ << tr("A signature is valid but the key used to verify the "
+ "signature has been revoked")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ setStatus(-1);
break;
case GPG_ERR_SIG_EXPIRED:
- stream_ << _("A signature is valid but expired") << std::endl;
+ stream_ << tr("A signature is valid but expired") << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ setStatus(-1);
break;
case GPG_ERR_KEY_EXPIRED:
- stream_ << _("A signature is valid but the key used to "
- "verify the signature has expired.")
- << std::endl;
+ stream_ << tr("A signature is valid but the key used to "
+ "verify the signature has expired.")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
break;
case GPG_ERR_GENERAL:
- stream_ << _("There was some other error which prevented "
- "the signature verification.")
- << std::endl;
+ stream_ << tr("There was some other error which prevented "
+ "the signature verification.")
+ << Qt::endl;
status_ = -1;
- canContinue = false;
+ can_continue = false;
break;
default:
- auto fpr = std::string(sign->fpr);
- stream_ << _("Error for key with fingerprint") << " "
- << GpgFrontend::beautify_fingerprint(fpr);
- set_status(-1);
+ auto fpr = QString(sign->fpr);
+ stream_ << tr("Error for key with fingerprint") << " "
+ << GpgFrontend::BeautifyFingerprint(fpr);
+ setStatus(-1);
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
sign = sign->next;
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
} else {
stream_
- << "[>] "
- << _("Could not find information that can be used for verification.")
- << std::endl;
- set_status(0);
+ << "-> "
+ << tr("Could not find information that can be used for verification.")
+ << Qt::endl;
+ setStatus(0);
return;
}
}
-bool GpgFrontend::GpgVerifyResultAnalyse::print_signer(
- std::stringstream &stream, gpgme_signature_t sign) {
- bool keyFound = true;
+auto GpgFrontend::GpgVerifyResultAnalyse::print_signer(QTextStream &stream,
+ gpgme_signature_t sign)
+ -> bool {
+ bool key_found = true;
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr);
if (!key.IsGood()) {
- stream << " " << _("Signed By") << ": "
- << "<" << _("Unknown") << ">" << std::endl;
- set_status(0);
- keyFound = false;
+ stream << "- " << tr("Signed By") << ": "
+ << "<" << tr("Unknown") << ">" << Qt::endl;
+ setStatus(0);
+ key_found = false;
} else {
- stream << " " << _("Signed By") << ": "
- << key.GetUIDs()->front().GetUID() << std::endl;
+ stream << "- " << tr("Signed By") << ": " << key.GetUIDs()->front().GetUID()
+ << Qt::endl;
+ }
+ if (sign->pubkey_algo != 0U) {
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(sign->pubkey_algo) << Qt::endl;
+ }
+ if (sign->hash_algo != 0U) {
+ stream << "- " << tr("Hash Algo") << ": "
+ << gpgme_hash_algo_name(sign->hash_algo) << Qt::endl;
}
- if (sign->pubkey_algo)
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
- if (sign->hash_algo)
- stream << " " << _("Hash Algo") << ": "
- << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
- if (sign->timestamp)
- stream << " " << _("Date") << "(" << _("UTC") << ")"
- << ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
- stream << std::endl;
- return keyFound;
+ if (sign->timestamp != 0U) {
+ stream << "- " << tr("Date") << "(" << tr("UTC") << ")"
+ << ": " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
+
+ stream << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
+ }
+ stream << Qt::endl;
+ return key_found;
}
-gpgme_signature_t GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const {
- if (result_)
- return result_->signatures;
- else
- return nullptr;
+auto GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const
+ -> gpgme_signature_t {
+ if (result_.IsGood()) {
+ return result_.GetRaw()->signatures;
+ }
+ return nullptr;
}
-GpgFrontend::GpgVerifyResult
-GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() {
- return std::move(result_);
+
+auto GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult()
+ -> GpgFrontend::GpgVerifyResult {
+ return result_;
}
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
index ce8e03ad..8aa2e41f 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
-#define GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/model/GpgKeySignature.h"
+#include "core/model/GpgVerifyResult.h"
namespace GpgFrontend {
/**
@@ -38,6 +37,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Verify Result Analyse object
@@ -52,21 +52,21 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
*
* @return gpgme_signature_t
*/
- gpgme_signature_t GetSignatures() const;
+ auto GetSignatures() const -> gpgme_signature_t;
/**
* @brief
*
* @return GpgVerifyResult
*/
- GpgVerifyResult TakeChargeOfResult();
+ auto TakeChargeOfResult() -> GpgVerifyResult;
- private:
+ protected:
/**
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() final;
private:
/**
@@ -77,12 +77,10 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
* @return true
* @return false
*/
- bool print_signer(std::stringstream &stream, gpgme_signature_t sign);
+ auto print_signer(QTextStream &stream, gpgme_signature_t sign) -> bool;
GpgError error_; ///<
GpgVerifyResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
diff --git a/src/core/log/QtLoggerFmt.h b/src/core/log/QtLoggerFmt.h
new file mode 100644
index 00000000..e7ac2c82
--- /dev/null
+++ b/src/core/log/QtLoggerFmt.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+template <>
+struct fmt::formatter<QString> {
+ // Parses format specifications.
+ constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
+ return ctx.begin();
+ }
+
+ // Formats the QString qstr and writes it to the output.
+ template <typename FormatContext>
+ auto format(const QString& qstr, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ // Convert QString to UTF-8 QString (to handle Unicode characters
+ // correctly)
+ QByteArray utf8_array = qstr.toUtf8();
+ return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
+ }
+};
+
+template <>
+struct fmt::formatter<QByteArray> {
+ // Parses format specifications.
+ constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
+ return ctx.begin();
+ }
+
+ // Formats the QString qstr and writes it to the output.
+ template <typename FormatContext>
+ auto format(const QByteArray& qarray, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ // Convert QString to UTF-8 QString (to handle Unicode characters
+ // correctly)
+ return fmt::format_to(ctx.out(), "{}", qarray.constData());
+ }
+};
diff --git a/src/core/thread/CtxCheckTask.h b/src/core/model/CommonStruct.h
index 06ddfd82..d7d09602 100644
--- a/src/core/thread/CtxCheckTask.h
+++ b/src/core/model/CommonStruct.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,45 +19,28 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CTXCHECKTRHEAD_H
-#define GPGFRONTEND_CTXCHECKTRHEAD_H
+#pragma once
-#include "core/GpgFrontendCore.h"
-#include "core/thread/Task.h"
+namespace GpgFrontend {
-namespace GpgFrontend::Thread {
/**
* @brief
*
*/
-class GPGFRONTEND_CORE_EXPORT CtxCheckTask : public Task {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Ctx Check Thread object
- *
- */
- CtxCheckTask();
-
- signals:
- /**
- * @brief
- *
- */
- void SignalGnupgNotInstall();
-
- protected:
- /**
- * @brief
- *
- */
- void Run() override;
+template <typename T>
+struct GPGFRONTEND_CORE_EXPORT RefDeleter {
+ void operator()(T* _key) {
+ gpgme_unre
+ }
};
-} // namespace GpgFrontend::Thread
-#endif // GPGFRONTEND_CTXCHECKTRHEAD_H
+template <typename T>
+using KeyRefHandler = std::unique_ptr<T, RefDeleter<T>>; ///<
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/DataObject.cpp b/src/core/model/DataObject.cpp
new file mode 100644
index 00000000..d0e9d141
--- /dev/null
+++ b/src/core/model/DataObject.cpp
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "DataObject.h"
+
+#include <stack>
+
+namespace GpgFrontend {
+
+class DataObject::Impl {
+ public:
+ Impl() = default;
+
+ Impl(std::initializer_list<std::any> init_list) : params_(init_list) {}
+
+ void AppendObject(const std::any& obj) { params_.push_back(obj); }
+
+ auto GetParameter(size_t index) -> std::any {
+ if (index >= params_.size()) {
+ throw std::out_of_range("index out of range");
+ }
+ return params_[index];
+ }
+
+ auto GetObjectSize() -> size_t { return params_.size(); }
+
+ private:
+ std::vector<std::any> params_;
+};
+
+DataObject::DataObject() : p_(SecureCreateUniqueObject<Impl>()) {}
+
+DataObject::DataObject(std::initializer_list<std::any> i)
+ : p_(SecureCreateUniqueObject<Impl>(i)) {}
+
+DataObject::~DataObject() = default;
+
+DataObject::DataObject(DataObject&&) noexcept = default;
+
+auto DataObject::operator[](size_t index) const -> std::any {
+ return p_->GetParameter(index);
+}
+
+auto DataObject::GetParameter(size_t index) const -> std::any {
+ return p_->GetParameter(index);
+}
+
+void DataObject::AppendObject(std::any obj) { return p_->AppendObject(obj); }
+
+auto DataObject::GetObjectSize() const -> size_t { return p_->GetObjectSize(); }
+
+void DataObject::Swap(DataObject& other) noexcept { std::swap(p_, other.p_); }
+
+void DataObject::Swap(DataObject&& other) noexcept { p_ = std::move(other.p_); }
+
+void swap(DataObject& a, DataObject& b) noexcept { a.Swap(b); }
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/DataObject.h b/src/core/model/DataObject.h
new file mode 100644
index 00000000..6b41a051
--- /dev/null
+++ b/src/core/model/DataObject.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <typeindex>
+#include <typeinfo>
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class DataObject;
+using DataObjectPtr = std::shared_ptr<DataObject>; ///<
+
+class GPGFRONTEND_CORE_EXPORT DataObject {
+ public:
+ DataObject();
+
+ DataObject(std::initializer_list<std::any>);
+
+ ~DataObject();
+
+ DataObject(DataObject&&) noexcept;
+
+ auto operator[](size_t index) const -> std::any;
+
+ void AppendObject(std::any);
+
+ [[nodiscard]] auto GetParameter(size_t index) const -> std::any;
+
+ [[nodiscard]] auto GetObjectSize() const -> size_t;
+
+ void Swap(DataObject& other) noexcept;
+
+ void Swap(DataObject&& other) noexcept;
+
+ template <typename... Args>
+ auto Check() -> bool {
+ if (sizeof...(Args) != GetObjectSize()) return false;
+
+ std::vector<std::type_info const*> type_list = {&typeid(Args)...};
+ for (size_t i = 0; i < type_list.size(); ++i) {
+ if (std::type_index(*type_list[i]) !=
+ std::type_index((*this)[i].type())) {
+ GF_CORE_LOG_ERROR(
+ "value of index {} in data object is type: {}, "
+ "not expected type: {}",
+ i, ((*this)[i]).type().name(), type_list[i]->name());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename... Args>
+auto TransferParams(Args&&... args) -> std::shared_ptr<DataObject> {
+ return GpgFrontend::SecureCreateSharedObject<DataObject>(
+ DataObject{std::forward<Args>(args)...});
+}
+
+template <typename T>
+auto ExtractParams(const std::shared_ptr<DataObject>& d_o, int index) -> T {
+ if (!d_o) {
+ throw std::invalid_argument("nullptr provided for DataObjectPtr");
+ }
+ return std::any_cast<T>(d_o->GetParameter(index));
+}
+
+void swap(DataObject& a, DataObject& b) noexcept;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFBuffer.cpp b/src/core/model/GFBuffer.cpp
new file mode 100644
index 00000000..411a5725
--- /dev/null
+++ b/src/core/model/GFBuffer.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GFBuffer.h"
+
+namespace GpgFrontend {
+
+GFBuffer::GFBuffer() = default;
+
+GFBuffer::GFBuffer(QByteArray buffer) : buffer_(std::move(buffer)) {}
+
+GFBuffer::GFBuffer(const QString& str) : buffer_(str.toUtf8()) {}
+
+auto GFBuffer::operator==(const GFBuffer& o) const -> bool {
+ return buffer_ == o.buffer_;
+}
+
+auto GFBuffer::Data() const -> const char* { return buffer_.constData(); }
+
+void GFBuffer::Resize(ssize_t size) { buffer_.resize(size); }
+
+auto GFBuffer::Size() const -> size_t { return buffer_.size(); }
+
+auto GFBuffer::ConvertToQByteArray() const -> QByteArray { return buffer_; }
+
+auto GFBuffer::Empty() const -> bool { return this->Size() == 0; }
+
+void GFBuffer::Append(const GFBuffer& o) { buffer_.append(o.buffer_); }
+
+void GFBuffer::Append(const char* buffer, ssize_t size) {
+ buffer_.append(buffer, size);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFBuffer.h b/src/core/model/GFBuffer.h
new file mode 100644
index 00000000..46189195
--- /dev/null
+++ b/src/core/model/GFBuffer.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GFBuffer {
+ public:
+ GFBuffer();
+
+ explicit GFBuffer(QByteArray buffer);
+
+ explicit GFBuffer(const QString& str);
+
+ auto operator==(const GFBuffer& o) const -> bool;
+
+ [[nodiscard]] auto Data() const -> const char*;
+
+ void Resize(ssize_t size);
+
+ [[nodiscard]] auto Size() const -> size_t;
+
+ [[nodiscard]] auto Empty() const -> bool;
+
+ void Append(const GFBuffer&);
+
+ void Append(const char*, ssize_t);
+
+ [[nodiscard]] auto ConvertToQByteArray() const -> QByteArray;
+
+ private:
+ QByteArray buffer_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFDataExchanger.cpp b/src/core/model/GFDataExchanger.cpp
new file mode 100644
index 00000000..abf79c6b
--- /dev/null
+++ b/src/core/model/GFDataExchanger.cpp
@@ -0,0 +1,89 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GFDataExchanger.h"
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
+ if (close_) return -1;
+ if (size == 0) return 0;
+
+ std::atomic<ssize_t> write_bytes = 0;
+ std::unique_lock<std::mutex> lock(mutex_);
+ try {
+ for (size_t i = 0; i < size; i++) {
+ if (queue_.size() == queue_max_size_) not_empty_.notify_all();
+ not_full_.wait(lock,
+ [=] { return queue_.size() < queue_max_size_ || close_; });
+ if (close_) return -1;
+
+ queue_.push(buffer[i]);
+ write_bytes++;
+ }
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "gf data exchanger caught exception when it writes to queue, abort...");
+ }
+
+ if (!queue_.empty()) not_empty_.notify_all();
+ return write_bytes;
+}
+
+auto GFDataExchanger::Read(std::byte* buffer, size_t size) -> ssize_t {
+ std::unique_lock<std::mutex> lock(mutex_);
+ if (size == 0 || (close_ && queue_.empty())) return 0;
+
+ std::atomic<ssize_t> read_bytes = 0;
+ for (size_t i = 0; i < size; ++i) {
+ if (queue_.empty()) not_full_.notify_all();
+ not_empty_.wait(lock, [=] { return !queue_.empty() || close_; });
+
+ if (close_ && queue_.empty()) return 0;
+ buffer[i] = queue_.front();
+ queue_.pop();
+ read_bytes++;
+ }
+
+ if (queue_.size() < queue_max_size_) not_full_.notify_all();
+ return read_bytes;
+}
+
+void GFDataExchanger::CloseWrite() {
+ std::unique_lock<std::mutex> const lock(mutex_);
+
+ close_ = true;
+ not_full_.notify_all();
+ not_empty_.notify_all();
+}
+
+GFDataExchanger::GFDataExchanger(ssize_t size) : queue_max_size_(size) {}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFDataExchanger.h b/src/core/model/GFDataExchanger.h
new file mode 100644
index 00000000..7d4ab050
--- /dev/null
+++ b/src/core/model/GFDataExchanger.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <queue>
+
+namespace GpgFrontend {
+
+class GFDataExchanger {
+ public:
+ explicit GFDataExchanger(ssize_t size);
+
+ auto Write(const std::byte* buffer, size_t size) -> ssize_t;
+
+ auto Read(std::byte* buffer, size_t size) -> ssize_t;
+
+ void CloseWrite();
+
+ private:
+ std::condition_variable not_full_, not_empty_;
+ std::queue<std::byte> queue_;
+ std::mutex mutex_;
+ const ssize_t queue_max_size_;
+ std::atomic_bool close_ = false;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgData.cpp b/src/core/model/GpgData.cpp
index 05f61a46..8b2be895 100644
--- a/src/core/model/GpgData.cpp
+++ b/src/core/model/GpgData.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,52 +28,128 @@
#include "core/model/GpgData.h"
-GpgFrontend::GpgData::GpgData() {
+#include <unistd.h>
+
+#include "core/model/GFDataExchanger.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+constexpr size_t kBufferSize = 32 * 1024;
+
+auto GFReadExCb(void* handle, void* buffer, size_t size) -> ssize_t {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ return ex->Read(static_cast<std::byte*>(buffer), size);
+}
+
+auto GFWriteExCb(void* handle, const void* buffer, size_t size) -> ssize_t {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ return ex->Write(static_cast<const std::byte*>(buffer), size);
+}
+
+void GFReleaseExCb(void* handle) {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ ex->CloseWrite();
+}
+
+GpgData::GpgData() {
gpgme_data_t data;
auto err = gpgme_data_new(&data);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
- data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data);
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(GFBuffer buffer) : cached_buffer_(buffer) {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new_from_mem(
+ &data, reinterpret_cast<const char*>(buffer.Data()), buffer.Size(), 0);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
}
-GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) {
+GpgData::GpgData(const void* buffer, size_t size, bool copy) {
gpgme_data_t data;
auto err = gpgme_data_new_from_mem(&data, static_cast<const char*>(buffer),
size, copy);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
- data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data);
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
}
-/**
- * Read gpgme-Data to QByteArray
- * mainly from http://basket.kde.org/ (kgpgme.cpp)
- */
-#define BUF_SIZE (32 * 1024)
+GpgData::GpgData(int fd) : fd_(fd), data_cbs_() {
+ gpgme_data_t data;
-GpgFrontend::ByteArrayPtr GpgFrontend::GpgData::Read2Buffer() {
+ auto err = gpgme_data_new_from_fd(&data, fd_);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(const QString& path, bool read) {
+ gpgme_data_t data;
+
+ // support unicode path
+ QFile file(path);
+ file.open(read ? QIODevice::ReadOnly : QIODevice::WriteOnly);
+ fp_ = fdopen(dup(file.handle()), read ? "rb" : "wb");
+
+ auto err = gpgme_data_new_from_stream(&data, fp_);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(std::shared_ptr<GFDataExchanger> ex)
+ : data_cbs_(), data_ex_(std::move(ex)) {
+ gpgme_data_t data;
+
+ data_cbs_.read = GFReadExCb;
+ data_cbs_.write = GFWriteExCb;
+ data_cbs_.seek = nullptr;
+ data_cbs_.release = GFReleaseExCb;
+
+ auto err = gpgme_data_new_from_cbs(&data, &data_cbs_, data_ex_.get());
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::~GpgData() {
+ if (fp_ != nullptr) {
+ fclose(fp_);
+ }
+
+ if (fd_ >= 0) {
+ close(fd_);
+ }
+}
+
+auto GpgData::Read2GFBuffer() -> GFBuffer {
gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET);
- ByteArrayPtr out_buffer = std::make_unique<std::string>();
+ GFBuffer out_buffer;
- if (ret) {
- gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ if (ret != 0) {
+ const GpgError err = gpgme_err_code_from_errno(errno);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- char buf[BUF_SIZE + 2];
+ std::array<char, kBufferSize + 2> buf;
- while ((ret = gpgme_data_read(*this, buf, BUF_SIZE)) > 0) {
- const size_t size = out_buffer->size();
- out_buffer->resize(static_cast<int>(size + ret));
- memcpy(out_buffer->data() + size, buf, ret);
+ while ((ret = gpgme_data_read(*this, buf.data(), kBufferSize)) > 0) {
+ out_buffer.Append(buf.data(), ret);
}
+
if (ret < 0) {
- gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ const GpgError err = gpgme_err_code_from_errno(errno);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
}
}
return out_buffer;
}
-GpgFrontend::GpgData::operator gpgme_data_t() { return data_ref_.get(); } \ No newline at end of file
+GpgData::operator gpgme_data_t() { return data_ref_.get(); }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h
index 816465d3..358ebd19 100644
--- a/src/core/model/GpgData.h
+++ b/src/core/model/GpgData.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,27 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGDATA_H
-#define _GPGDATA_H
+#pragma once
-#include "core/GpgConstants.h"
+#include "core/GpgFrontendCoreExport.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
+
+class GFDataExchanger;
+
/**
* @brief
*
*/
-class GpgData {
+class GPGFRONTEND_CORE_EXPORT GpgData {
public:
/**
* @brief Construct a new Gpg Data object
@@ -51,7 +55,40 @@ class GpgData {
* @param size
* @param copy
*/
- GpgData(void* buffer, size_t size, bool copy = true);
+ GpgData(const void* buffer, size_t size, bool copy = true);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param fd
+ */
+ explicit GpgData(int fd);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param fd
+ */
+ explicit GpgData(std::shared_ptr<GFDataExchanger>);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param path
+ */
+ explicit GpgData(const QString& path, bool read);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ */
+ explicit GpgData(GFBuffer);
+
+ /**
+ * @brief Destroy the Gpg Data object
+ *
+ */
+ ~GpgData();
/**
* @brief
@@ -65,23 +102,27 @@ class GpgData {
*
* @return ByteArrayPtr
*/
- ByteArrayPtr Read2Buffer();
+ auto Read2GFBuffer() -> GFBuffer;
private:
/**
* @brief
*
*/
- struct _data_ref_deleter {
+ struct DataRefDeleter {
void operator()(gpgme_data_t _data) {
if (_data != nullptr) gpgme_data_release(_data);
}
};
- std::unique_ptr<struct gpgme_data, _data_ref_deleter> data_ref_ =
- nullptr; ///<
+ GFBuffer cached_buffer_;
+
+ std::unique_ptr<struct gpgme_data, DataRefDeleter> data_ref_ = nullptr; ///<
+ FILE* fp_ = nullptr;
+ int fd_ = -1;
+
+ struct gpgme_data_cbs data_cbs_;
+ std::shared_ptr<GFDataExchanger> data_ex_;
};
} // namespace GpgFrontend
-
-#endif // _GPGDATA_H \ No newline at end of file
diff --git a/src/core/model/GpgDecryptResult.cpp b/src/core/model/GpgDecryptResult.cpp
new file mode 100644
index 00000000..3568bfd9
--- /dev/null
+++ b/src/core/model/GpgDecryptResult.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgDecryptResult.h"
+
+namespace GpgFrontend {
+
+GpgDecryptResult::GpgDecryptResult(gpgme_decrypt_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_decrypt_result>(
+ (gpgme_result_ref(r), r), [](gpgme_decrypt_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgDecryptResult::GpgDecryptResult() = default;
+
+GpgDecryptResult::~GpgDecryptResult() = default;
+
+auto GpgDecryptResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgDecryptResult::GetRaw() -> gpgme_decrypt_result_t {
+ return result_ref_.get();
+}
+
+auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> {
+ std::vector<GpgRecipient> result;
+ for (auto* reci = result_ref_->recipients; reci != nullptr;
+ reci = reci->next) {
+ try {
+ result.emplace_back(reci);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgDecryptResult.h b/src/core/model/GpgDecryptResult.h
new file mode 100644
index 00000000..8289d97d
--- /dev/null
+++ b/src/core/model/GpgDecryptResult.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GpgRecipient.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgDecryptResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_decrypt_result_t;
+
+ auto Recipients() -> std::vector<GpgRecipient>;
+
+ explicit GpgDecryptResult(gpgme_decrypt_result_t);
+
+ GpgDecryptResult();
+
+ virtual ~GpgDecryptResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_decrypt_result> result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgEncryptResult.cpp b/src/core/model/GpgEncryptResult.cpp
new file mode 100644
index 00000000..843cf7eb
--- /dev/null
+++ b/src/core/model/GpgEncryptResult.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgEncryptResult.h"
+
+namespace GpgFrontend {
+GpgEncryptResult::GpgEncryptResult(gpgme_encrypt_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_encrypt_result>(
+ (gpgme_result_ref(r), r), [](gpgme_encrypt_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgEncryptResult::GpgEncryptResult() = default;
+
+GpgEncryptResult::~GpgEncryptResult() = default;
+
+auto GpgEncryptResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgEncryptResult::GetRaw() -> gpgme_encrypt_result_t {
+ return result_ref_.get();
+}
+
+auto GpgEncryptResult::InvalidRecipients()
+ -> std::vector<std::tuple<QString, GpgError>> {
+ std::vector<std::tuple<QString, GpgError>> result;
+ for (auto* invalid_key = result_ref_->invalid_recipients;
+ invalid_key != nullptr; invalid_key = invalid_key->next) {
+ try {
+ result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgEncryptResult.h b/src/core/model/GpgEncryptResult.h
new file mode 100644
index 00000000..61fca710
--- /dev/null
+++ b/src/core/model/GpgEncryptResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgEncryptResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_encrypt_result_t;
+
+ auto InvalidRecipients() -> std::vector<std::tuple<QString, GpgError>>;
+
+ explicit GpgEncryptResult(gpgme_encrypt_result_t);
+
+ GpgEncryptResult();
+
+ virtual ~GpgEncryptResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_encrypt_result> result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp
new file mode 100644
index 00000000..d7daa852
--- /dev/null
+++ b/src/core/model/GpgGenKeyInfo.cpp
@@ -0,0 +1,485 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgGenKeyInfo.h"
+
+#include <cassert>
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
+ auto algo_args = t_algo_args.toLower();
+ GF_CORE_LOG_DEBUG("set algo args: {}", algo_args);
+
+ // reset all options
+ reset_options();
+
+ if (!this->subkey_) {
+ this->SetAllowCertification(true);
+ } else {
+ this->SetAllowCertification(false);
+ }
+
+ this->allow_change_certification_ = false;
+
+ if (algo_args == "rsa") {
+ /**
+ * RSA is the world’s premier asymmetric cryptographic algorithm,
+ * and is built on the difficulty of factoring extremely large composites.
+ * GnuPG supports RSA with key sizes of between 1024 and 4096 bits.
+ */
+ suggest_min_key_size_ = 1024;
+ suggest_max_key_size_ = 4096;
+ suggest_size_addition_step_ = 1024;
+ SetKeyLength(2048);
+
+ } else if (algo_args == "dsa") {
+ /**
+ * Algorithm (DSA) as a government standard for digital signatures.
+ * Originally, it supported key lengths between 512 and 1024 bits.
+ * Recently, NIST has declared 512-bit keys obsolete:
+ * now, DSA is available in 1024, 2048 and 3072-bit lengths.
+ */
+ SetAllowEncryption(false);
+ allow_change_encryption_ = false;
+
+ suggest_min_key_size_ = 1024;
+ suggest_max_key_size_ = 3072;
+ suggest_size_addition_step_ = 1024;
+ SetKeyLength(2048);
+
+ } else if (algo_args == "ed25519") {
+ /**
+ * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
+ * ranging from 1024 to 4096 bits.
+ */
+ SetAllowEncryption(false);
+ allow_change_encryption_ = false;
+
+ suggest_min_key_size_ = -1;
+ suggest_max_key_size_ = -1;
+ suggest_size_addition_step_ = -1;
+ SetKeyLength(-1);
+ } else if (algo_args == "cv25519" || algo_args == "nistp256" ||
+ algo_args == "nistp384" || algo_args == "nistp521" ||
+ algo_args == "brainpoolp256r1" || algo_args == "brainpoolp384r1" ||
+ algo_args == "brainpoolp512r1") {
+ SetAllowAuthentication(false);
+ allow_change_authentication_ = false;
+
+ SetAllowSigning(false);
+ allow_change_signing_ = false;
+
+ SetAllowCertification(false);
+ allow_change_certification_ = false;
+
+ suggest_min_key_size_ = -1;
+ suggest_max_key_size_ = -1;
+ suggest_size_addition_step_ = -1;
+ SetKeyLength(-1);
+ } else {
+ SPDLOG_ERROR("unsupported genkey algo arguments: {}", algo_args);
+ return;
+ }
+
+ this->algo_ = algo_args;
+}
+
+void GenKeyInfo::reset_options() {
+ allow_change_encryption_ = true;
+ SetAllowEncryption(true);
+
+ allow_change_certification_ = true;
+ SetAllowCertification(true);
+
+ allow_change_signing_ = true;
+ SetAllowSigning(true);
+
+ allow_change_authentication_ = true;
+ SetAllowAuthentication(true);
+
+ passphrase_.clear();
+}
+
+auto GenKeyInfo::GetKeySizeStr() const -> QString {
+ if (key_size_ > 0) {
+ return QString::number(key_size_);
+ }
+ return {};
+}
+
+void GenKeyInfo::SetKeyLength(int m_key_size) {
+ if (m_key_size < suggest_min_key_size_ ||
+ m_key_size > suggest_max_key_size_) {
+ return;
+ }
+ GenKeyInfo::key_size_ = m_key_size;
+}
+
+void GenKeyInfo::SetExpireTime(const QDateTime &m_expired) {
+ if (!IsNonExpired()) {
+ GenKeyInfo::expired_ = m_expired;
+ }
+}
+
+void GenKeyInfo::SetNonExpired(bool m_non_expired) {
+ if (!m_non_expired) this->expired_ = QDateTime::fromSecsSinceEpoch(0);
+ GenKeyInfo::non_expired_ = m_non_expired;
+}
+
+void GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) {
+ if (allow_change_encryption_) {
+ GenKeyInfo::allow_encryption_ = m_allow_encryption;
+ }
+}
+
+void GenKeyInfo::SetAllowCertification(bool m_allow_certification) {
+ if (allow_change_certification_) {
+ GenKeyInfo::allow_certification_ = m_allow_certification;
+ }
+}
+
+GenKeyInfo::GenKeyInfo(bool m_is_sub_key) : subkey_(m_is_sub_key) {
+ assert(!GetSupportedKeyAlgo().empty());
+ SetAlgo(std::get<0>(GetSupportedKeyAlgo()[0]));
+}
+
+auto GenKeyInfo::GetSupportedKeyAlgo()
+ -> const std::vector<GenKeyInfo::KeyGenAlgo> & {
+ static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportKeyAlgo = {
+ {"RSA", "RSA", ""},
+ {"DSA", "DSA", ""},
+ {"ECDSA", "ED25519", ""},
+ {"ECDSA + ECDH", "ED25519", "CV25519"},
+ {"ECDSA + ECDH NIST P-256", "ED25519", "NISTP256"},
+ {"ECDSA + ECDH BrainPooL P-256", "ED25519", "BRAINPOOLP256R1"},
+ };
+ return kSupportKeyAlgo;
+}
+
+auto GenKeyInfo::GetSupportedSubkeyAlgo()
+ -> const std::vector<GenKeyInfo::KeyGenAlgo> & {
+ static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportSubkeyAlgo = {
+ {"RSA", "", "RSA"},
+ {"DSA", "", "DSA"},
+ {"ECDSA", "", "ED25519"},
+ {"ECDH", "", "CV25519"},
+ {"ECDH NIST P-256", "", "NISTP256"},
+ {"ECDH NIST P-384", "", "NISTP384"},
+ {"ECDH NIST P-521", "", "NISTP521"},
+ {"ECDH BrainPooL P-256", "", "BRAINPOOLP256R1"},
+ {"ECDH BrainPooL P-384", "", "BRAINPOOLP384R1"},
+ {"ECDH BrainPooL P-512", "", "BRAINPOOLP512R1"}};
+
+ return kSupportSubkeyAlgo;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsSubKey() const -> bool { return subkey_; }
+
+/**
+ * @brief Set the Is Sub Key object
+ *
+ * @param m_sub_key
+ */
+void GenKeyInfo::SetIsSubKey(bool m_sub_key) {
+ GenKeyInfo::subkey_ = m_sub_key;
+}
+
+/**
+ * @brief Get the Userid object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetUserid() const -> QString {
+ return QString("%1(%2)<%3>").arg(name_).arg(comment_).arg(email_);
+}
+
+/**
+ * @brief Set the Name object
+ *
+ * @param m_name
+ */
+void GenKeyInfo::SetName(const QString &m_name) { this->name_ = m_name; }
+
+/**
+ * @brief Set the Email object
+ *
+ * @param m_email
+ */
+void GenKeyInfo::SetEmail(const QString &m_email) { this->email_ = m_email; }
+
+/**
+ * @brief Set the Comment object
+ *
+ * @param m_comment
+ */
+void GenKeyInfo::SetComment(const QString &m_comment) {
+ this->comment_ = m_comment;
+}
+
+/**
+ * @brief Get the Name object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetName() const -> QString { return name_; }
+
+/**
+ * @brief Get the Email object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetEmail() const -> QString { return email_; }
+
+/**
+ * @brief Get the Comment object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetComment() const -> QString {
+ return comment_;
+}
+
+/**
+ * @brief Get the Algo object
+ *
+ * @return const QString&
+ */
+[[nodiscard]] auto GenKeyInfo::GetAlgo() const -> const QString & {
+ return algo_;
+}
+
+/**
+ * @brief Get the Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetKeyLength() const -> int { return key_size_; }
+
+/**
+ * @brief Get the Expired object
+ *
+ * @return const QDateTime&
+ */
+[[nodiscard]] auto GenKeyInfo::GetExpireTime() const -> const QDateTime & {
+ return expired_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsNonExpired() const -> bool {
+ return non_expired_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsNoPassPhrase() const -> bool {
+ return this->no_passphrase_;
+}
+
+/**
+ * @brief Set the Non Pass Phrase object
+ *
+ * @param m_non_pass_phrase
+ */
+void GenKeyInfo::SetNonPassPhrase(bool m_non_pass_phrase) {
+ GenKeyInfo::no_passphrase_ = m_non_pass_phrase;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowSigning() const -> bool {
+ return allow_signing_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowNoPassPhrase() const -> bool {
+ return allow_no_pass_phrase_;
+}
+
+/**
+ * @brief Set the Allow Signing object
+ *
+ * @param m_allow_signing
+ */
+void GenKeyInfo::SetAllowSigning(bool m_allow_signing) {
+ if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowEncryption() const -> bool {
+ return allow_encryption_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowCertification() const -> bool {
+ return allow_certification_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowAuthentication() const -> bool {
+ return allow_authentication_;
+}
+
+/**
+ * @brief Set the Allow Authentication object
+ *
+ * @param m_allow_authentication
+ */
+void GenKeyInfo::SetAllowAuthentication(bool m_allow_authentication) {
+ if (allow_change_authentication_) {
+ GenKeyInfo::allow_authentication_ = m_allow_authentication;
+ }
+}
+
+/**
+ * @brief Get the Pass Phrase object
+ *
+ * @return const QString&
+ */
+[[nodiscard]] auto GenKeyInfo::GetPassPhrase() const -> const QString & {
+ return passphrase_;
+}
+
+/**
+ * @brief Set the Pass Phrase object
+ *
+ * @param m_pass_phrase
+ */
+void GenKeyInfo::SetPassPhrase(const QString &m_pass_phrase) {
+ GenKeyInfo::passphrase_ = m_pass_phrase;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeSigning() const -> bool {
+ return allow_change_signing_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeEncryption() const -> bool {
+ return allow_change_encryption_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeCertification() const -> bool {
+ return allow_change_certification_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeAuthentication() const -> bool {
+ return allow_change_authentication_;
+}
+
+/**
+ * @brief Get the Suggest Max Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSuggestMaxKeySize() const -> int {
+ return suggest_max_key_size_;
+}
+
+/**
+ * @brief Get the Suggest Min Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSuggestMinKeySize() const -> int {
+ return suggest_min_key_size_;
+}
+
+/**
+ * @brief Get the Size Change Step object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSizeChangeStep() const -> int {
+ return suggest_size_addition_step_;
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/GpgGenKeyInfo.h b/src/core/model/GpgGenKeyInfo.h
index d47b803e..166c6b0f 100644
--- a/src/core/GpgGenKeyInfo.h
+++ b/src/core/model/GpgGenKeyInfo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,78 +20,41 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGGENKEYINFO_H
-#define GPGFRONTEND_GPGGENKEYINFO_H
-
-#include <boost/date_time.hpp>
-#include <boost/date_time/gregorian/greg_duration_types.hpp>
-#include <boost/format.hpp>
-#include <string>
-#include <vector>
-
-#include "GpgFrontend.h"
+#pragma once
namespace GpgFrontend {
class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
- bool standalone_ = false; ///<
- bool subkey_ = false; ///<
- std::string name_; ///<
- std::string email_; ///<
- std::string comment_; ///<
-
- std::string algo_; ///<
- int key_size_ = 2048;
- boost::posix_time::ptime expired_ =
- boost::posix_time::second_clock::local_time() +
- boost::gregorian::years(2); ///<
- bool non_expired_ = false; ///<
-
- bool no_passphrase_ = false; ///<
- bool allow_no_pass_phrase_ = true; ///<
-
- int suggest_max_key_size_ = 4096; ///<
- int suggest_size_addition_step_ = 1024; ///<
- int suggest_min_key_size_ = 1024; ///<
-
- std::string passphrase_; ///<
-
- using KeyGenAlgo = std::pair<std::string, std::string>;
-
public:
- /**
- * @brief Get the Supported Key Algo object
- *
- * @return const std::vector<std::string>&
- */
- static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgo();
+ using KeyGenAlgo = std::tuple<QString, QString, QString>;
/**
- * @brief Get the Supported Subkey Algo object
+ * @brief Construct a new Gen Key Info object
*
- * @return const std::vector<std::string>&
+ * @param m_is_sub_key
+ * @param m_standalone
*/
- static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgo();
+ explicit GenKeyInfo(bool m_is_sub_key = false);
/**
- * @brief Get the Supported Key Algo Standalone object
+ * @brief Get the Supported Key Algo object
*
- * @return const std::vector<std::string>&
+ * @return const std::vector<QString>&
*/
- static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgoStandalone();
+ static auto GetSupportedKeyAlgo() -> const std::vector<KeyGenAlgo> &;
/**
- * @brief Get the Supported Subkey Algo Standalone object
+ * @brief Get the Supported Subkey Algo object
*
- * @return const std::vector<std::string>&
+ * @return const std::vector<QString>&
*/
- static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgoStandalone();
+ static auto GetSupportedSubkeyAlgo() -> const std::vector<KeyGenAlgo> &;
/**
* @brief
@@ -99,95 +62,91 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsSubKey() const { return subkey_; }
+ [[nodiscard]] auto IsSubKey() const -> bool;
/**
* @brief Set the Is Sub Key object
*
* @param m_sub_key
*/
- void SetIsSubKey(bool m_sub_key) { GenKeyInfo::subkey_ = m_sub_key; }
+ void SetIsSubKey(bool m_sub_key);
/**
* @brief Get the Userid object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUserid() const {
- auto uid_format = boost::format("%1%(%2%)<%3%>") % this->name_ %
- this->comment_ % this->email_;
- return uid_format.str();
- }
+ [[nodiscard]] auto GetUserid() const -> QString;
/**
* @brief Set the Name object
*
* @param m_name
*/
- void SetName(const std::string &m_name) { this->name_ = m_name; }
+ void SetName(const QString &m_name);
/**
* @brief Set the Email object
*
* @param m_email
*/
- void SetEmail(const std::string &m_email) { this->email_ = m_email; }
+ void SetEmail(const QString &m_email);
/**
* @brief Set the Comment object
*
* @param m_comment
*/
- void SetComment(const std::string &m_comment) { this->comment_ = m_comment; }
+ void SetComment(const QString &m_comment);
/**
* @brief Get the Name object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const { return name_; }
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief Get the Email object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const { return email_; }
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief Get the Comment object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const { return comment_; }
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief Get the Algo object
*
- * @return const std::string&
+ * @return const QString&
*/
- [[nodiscard]] const std::string &GetAlgo() const { return algo_; }
+ [[nodiscard]] auto GetAlgo() const -> const QString &;
/**
* @brief Set the Algo object
*
* @param m_algo
*/
- void SetAlgo(const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo);
+ void SetAlgo(const QString &);
/**
* @brief Get the Key Size Str object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetKeySizeStr() const;
+ [[nodiscard]] auto GetKeySizeStr() const -> QString;
/**
* @brief Get the Key Size object
*
* @return int
*/
- [[nodiscard]] int GetKeyLength() const { return key_size_; }
+ [[nodiscard]] auto GetKeyLength() const -> int;
/**
* @brief Set the Key Size object
@@ -199,18 +158,16 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
/**
* @brief Get the Expired object
*
- * @return const boost::posix_time::ptime&
+ * @return const QDateTime&
*/
- [[nodiscard]] const boost::posix_time::ptime &GetExpireTime() const {
- return expired_;
- }
+ [[nodiscard]] auto GetExpireTime() const -> const QDateTime &;
/**
* @brief Set the Expired object
*
* @param m_expired
*/
- void SetExpireTime(const boost::posix_time::ptime &m_expired);
+ void SetExpireTime(const QDateTime &m_expired);
/**
* @brief
@@ -218,7 +175,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsNonExpired() const { return non_expired_; }
+ [[nodiscard]] auto IsNonExpired() const -> bool;
/**
* @brief Set the Non Expired object
@@ -233,16 +190,14 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsNoPassPhrase() const { return this->no_passphrase_; }
+ [[nodiscard]] auto IsNoPassPhrase() const -> bool;
/**
* @brief Set the Non Pass Phrase object
*
* @param m_non_pass_phrase
*/
- void SetNonPassPhrase(bool m_non_pass_phrase) {
- GenKeyInfo::no_passphrase_ = m_non_pass_phrase;
- }
+ void SetNonPassPhrase(bool m_non_pass_phrase);
/**
* @brief
@@ -250,7 +205,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowSigning() const { return allow_signing_; }
+ [[nodiscard]] auto IsAllowSigning() const -> bool;
/**
* @brief
@@ -258,18 +213,14 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowNoPassPhrase() const {
- return allow_no_pass_phrase_;
- }
+ [[nodiscard]] auto IsAllowNoPassPhrase() const -> bool;
/**
* @brief Set the Allow Signing object
*
* @param m_allow_signing
*/
- void SetAllowSigning(bool m_allow_signing) {
- if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing;
- }
+ void SetAllowSigning(bool m_allow_signing);
/**
* @brief
@@ -277,7 +228,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowEncryption() const { return allow_encryption_; }
+ [[nodiscard]] auto IsAllowEncryption() const -> bool;
/**
* @brief Set the Allow Encryption object
@@ -292,9 +243,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowCertification() const {
- return allow_certification_;
- }
+ [[nodiscard]] auto IsAllowCertification() const -> bool;
/**
* @brief Set the Allow Certification object
@@ -309,35 +258,28 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowAuthentication() const {
- return allow_authentication_;
- }
+ [[nodiscard]] auto IsAllowAuthentication() const -> bool;
/**
* @brief Set the Allow Authentication object
*
* @param m_allow_authentication
*/
- void SetAllowAuthentication(bool m_allow_authentication) {
- if (allow_change_authentication_)
- GenKeyInfo::allow_authentication_ = m_allow_authentication;
- }
+ void SetAllowAuthentication(bool m_allow_authentication);
/**
* @brief Get the Pass Phrase object
*
- * @return const std::string&
+ * @return const QString&
*/
- [[nodiscard]] const std::string &GetPassPhrase() const { return passphrase_; }
+ [[nodiscard]] auto GetPassPhrase() const -> const QString &;
/**
* @brief Set the Pass Phrase object
*
* @param m_pass_phrase
*/
- void SetPassPhrase(const std::string &m_pass_phrase) {
- GenKeyInfo::passphrase_ = m_pass_phrase;
- }
+ void SetPassPhrase(const QString &m_pass_phrase);
/**
* @brief
@@ -345,9 +287,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeSigning() const {
- return allow_change_signing_;
- }
+ [[nodiscard]] auto IsAllowChangeSigning() const -> bool;
/**
* @brief
@@ -355,9 +295,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeEncryption() const {
- return allow_change_encryption_;
- }
+ [[nodiscard]] auto IsAllowChangeEncryption() const -> bool;
/**
* @brief
@@ -365,9 +303,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeCertification() const {
- return allow_change_certification_;
- }
+ [[nodiscard]] auto IsAllowChangeCertification() const -> bool;
/**
* @brief
@@ -375,38 +311,49 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeAuthentication() const {
- return allow_change_authentication_;
- }
+ [[nodiscard]] auto IsAllowChangeAuthentication() const -> bool;
/**
* @brief Get the Suggest Max Key Size object
*
* @return int
*/
- [[nodiscard]] int GetSuggestMaxKeySize() const {
- return suggest_max_key_size_;
- }
+ [[nodiscard]] auto GetSuggestMaxKeySize() const -> int;
/**
* @brief Get the Suggest Min Key Size object
*
* @return int
*/
- [[nodiscard]] int GetSuggestMinKeySize() const {
- return suggest_min_key_size_;
- }
+ [[nodiscard]] auto GetSuggestMinKeySize() const -> int;
/**
* @brief Get the Size Change Step object
*
* @return int
*/
- [[nodiscard]] int GetSizeChangeStep() const {
- return suggest_size_addition_step_;
- }
+ [[nodiscard]] auto GetSizeChangeStep() const -> int;
private:
+ bool subkey_ = false; ///<
+ QString name_; ///<
+ QString email_; ///<
+ QString comment_; ///<
+
+ QString algo_; ///<
+ int key_size_ = 2048;
+ QDateTime expired_ = QDateTime::currentDateTime().addYears(2);
+ bool non_expired_ = false; ///<
+
+ bool no_passphrase_ = false; ///<
+ bool allow_no_pass_phrase_ = true; ///<
+
+ int suggest_max_key_size_ = 4096; ///<
+ int suggest_size_addition_step_ = 1024; ///<
+ int suggest_min_key_size_ = 1024; ///<
+
+ QString passphrase_; ///<
+
bool allow_encryption_ = true; ///<
bool allow_change_encryption_ = true; ///<
bool allow_certification_ = true; ///<
@@ -421,17 +368,6 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
*
*/
void reset_options();
-
- public:
- /**
- * @brief Construct a new Gen Key Info object
- *
- * @param m_is_sub_key
- * @param m_standalone
- */
- explicit GenKeyInfo(bool m_is_sub_key = false, bool m_standalone = false);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGGENKEYINFO_H
diff --git a/src/core/model/GpgGenerateKeyResult.cpp b/src/core/model/GpgGenerateKeyResult.cpp
new file mode 100644
index 00000000..f7ebf14e
--- /dev/null
+++ b/src/core/model/GpgGenerateKeyResult.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgGenerateKeyResult.h"
+
+#include <gpgme.h>
+
+namespace GpgFrontend {
+
+GpgGenerateKeyResult::GpgGenerateKeyResult(gpgme_genkey_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_genkey_result>(
+ (gpgme_result_ref(r), r), [](gpgme_genkey_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+auto GpgGenerateKeyResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgGenerateKeyResult::GetFingerprint() -> QString const {
+ return result_ref_->fpr;
+}
+
+GpgGenerateKeyResult::GpgGenerateKeyResult() = default;
+
+GpgGenerateKeyResult::GpgGenerateKeyResult(const GpgGenerateKeyResult &) =
+ default;
+
+auto GpgGenerateKeyResult::operator=(const GpgGenerateKeyResult &)
+ -> GpgGenerateKeyResult & = default;
+
+GpgGenerateKeyResult::~GpgGenerateKeyResult() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgGenerateKeyResult.h b/src/core/model/GpgGenerateKeyResult.h
new file mode 100644
index 00000000..f312d415
--- /dev/null
+++ b/src/core/model/GpgGenerateKeyResult.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCore.h"
+#include "core/GpgFrontendCoreExport.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgGenerateKeyResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetFingerprint() -> QString const;
+
+ explicit GpgGenerateKeyResult(gpgme_genkey_result_t);
+
+ GpgGenerateKeyResult();
+
+ GpgGenerateKeyResult(const GpgGenerateKeyResult &);
+
+ auto operator=(const GpgGenerateKeyResult &) -> GpgGenerateKeyResult &;
+
+ virtual ~GpgGenerateKeyResult();
+
+ private:
+ using ResultRefHandler =
+ std::shared_ptr<struct _gpgme_op_genkey_result>; ///<
+
+ ResultRefHandler result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgImportInformation.cpp b/src/core/model/GpgImportInformation.cpp
new file mode 100644
index 00000000..cda146de
--- /dev/null
+++ b/src/core/model/GpgImportInformation.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgImportInformation.h"
+
+namespace GpgFrontend {
+
+GpgImportInformation::GpgImportInformation() = default;
+
+GpgImportInformation::GpgImportInformation(gpgme_import_result_t result) {
+ if (result->unchanged != 0) unchanged = result->unchanged;
+ if (result->considered != 0) considered = result->considered;
+ if (result->no_user_id != 0) no_user_id = result->no_user_id;
+ if (result->imported != 0) imported = result->imported;
+ if (result->imported_rsa != 0) imported_rsa = result->imported_rsa;
+ if (result->unchanged != 0) unchanged = result->unchanged;
+ if (result->new_user_ids != 0) new_user_ids = result->new_user_ids;
+ if (result->new_sub_keys != 0) new_sub_keys = result->new_sub_keys;
+ if (result->new_signatures != 0) new_signatures = result->new_signatures;
+ if (result->new_revocations != 0) new_revocations = result->new_revocations;
+ if (result->secret_read != 0) secret_read = result->secret_read;
+ if (result->secret_imported != 0) secret_imported = result->secret_imported;
+ if (result->secret_unchanged != 0) {
+ secret_unchanged = result->secret_unchanged;
+ }
+ if (result->not_imported != 0) not_imported = result->not_imported;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgImportInformation.h b/src/core/model/GpgImportInformation.h
new file mode 100644
index 00000000..5f85a338
--- /dev/null
+++ b/src/core/model/GpgImportInformation.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
+ public:
+ /**
+ * @brief
+ *
+ */
+ class GpgImportedKey {
+ public:
+ QString fpr; ///<
+ int import_status; ///<
+ };
+
+ using GpgImportedKeyList = std::list<GpgImportedKey>; ///<
+
+ /**
+ * @brief Construct a new Gpg Import Information object
+ *
+ */
+ GpgImportInformation();
+
+ /**
+ * @brief Construct a new Gpg Import Information object
+ *
+ * @param result
+ */
+ explicit GpgImportInformation(gpgme_import_result_t result);
+
+ int considered = 0; ///<
+ int no_user_id = 0; ///<
+ int imported = 0; ///<
+ int imported_rsa = 0; ///<
+ int unchanged = 0; ///<
+ int new_user_ids = 0; ///<
+ int new_sub_keys = 0; ///<
+ int new_signatures = 0; ///<
+ int new_revocations = 0; ///<
+ int secret_read = 0; ///<
+ int secret_imported = 0; ///<
+ int secret_unchanged = 0; ///<
+ int not_imported = 0; ///<
+
+ GpgImportedKeyList imported_keys; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp
index 3a167b81..53842249 100644
--- a/src/core/model/GpgKey.cpp
+++ b/src/core/model/GpgKey.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,70 +30,80 @@
#include <mutex>
-GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(std::move(key)) {}
+namespace GpgFrontend {
-GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); }
+GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(key) {}
-GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept {
+GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); }
+
+auto GpgKey::operator=(GpgKey &&k) noexcept -> GpgKey & {
swap(key_ref_, k.key_ref_);
return *this;
}
-bool GpgFrontend::GpgKey::operator==(const GpgKey &o) const {
+GpgKey::GpgKey(const GpgKey &key) {
+ auto *key_ref = key.key_ref_.get();
+ gpgme_key_ref(key_ref);
+ this->key_ref_ = KeyRefHandler(key_ref);
+}
+
+auto GpgKey::operator=(const GpgKey &key) -> GpgKey & {
+ if (this == &key) {
+ return *this;
+ }
+
+ auto *key_ref = key.key_ref_.get();
+ gpgme_key_ref(key_ref);
+
+ this->key_ref_ = KeyRefHandler(key_ref);
+ return *this;
+}
+
+auto GpgKey::operator==(const GpgKey &o) const -> bool {
return o.GetId() == this->GetId();
}
-bool GpgFrontend::GpgKey::operator<=(const GpgKey &o) const {
+auto GpgKey::operator<=(const GpgKey &o) const -> bool {
return this->GetId() < o.GetId();
}
-GpgFrontend::GpgKey::operator gpgme_key_t() const { return key_ref_.get(); }
+GpgKey::operator gpgme_key_t() const { return key_ref_.get(); }
-bool GpgFrontend::GpgKey::IsGood() const { return key_ref_ != nullptr; }
+auto GpgKey::IsGood() const -> bool { return key_ref_ != nullptr; }
-std::string GpgFrontend::GpgKey::GetId() const {
- return key_ref_->subkeys->keyid;
-}
+auto GpgKey::GetId() const -> QString { return key_ref_->subkeys->keyid; }
-std::string GpgFrontend::GpgKey::GetName() const {
- return key_ref_->uids->name;
-};
+auto GpgKey::GetName() const -> QString { return key_ref_->uids->name; };
-std::string GpgFrontend::GpgKey::GetEmail() const {
- return key_ref_->uids->email;
-}
+auto GpgKey::GetEmail() const -> QString { return key_ref_->uids->email; }
-std::string GpgFrontend::GpgKey::GetComment() const {
- return key_ref_->uids->comment;
-}
+auto GpgKey::GetComment() const -> QString { return key_ref_->uids->comment; }
-std::string GpgFrontend::GpgKey::GetFingerprint() const {
- return key_ref_->fpr;
-}
+auto GpgKey::GetFingerprint() const -> QString { return key_ref_->fpr; }
-std::string GpgFrontend::GpgKey::GetProtocol() const {
+auto GpgKey::GetProtocol() const -> QString {
return gpgme_get_protocol_name(key_ref_->protocol);
}
-std::string GpgFrontend::GpgKey::GetOwnerTrust() const {
+auto GpgKey::GetOwnerTrust() const -> QString {
switch (key_ref_->owner_trust) {
case GPGME_VALIDITY_UNKNOWN:
- return _("Unknown");
+ return tr("Unknown");
case GPGME_VALIDITY_UNDEFINED:
- return _("Undefined");
+ return tr("Undefined");
case GPGME_VALIDITY_NEVER:
- return _("Never");
+ return tr("Never");
case GPGME_VALIDITY_MARGINAL:
- return _("Marginal");
+ return tr("Marginal");
case GPGME_VALIDITY_FULL:
- return _("Full");
+ return tr("Full");
case GPGME_VALIDITY_ULTIMATE:
- return _("Ultimate");
+ return tr("Ultimate");
}
return "Invalid";
}
-int GpgFrontend::GpgKey::GetOwnerTrustLevel() const {
+auto GpgKey::GetOwnerTrustLevel() const -> int {
switch (key_ref_->owner_trust) {
case GPGME_VALIDITY_UNKNOWN:
return 0;
@@ -111,66 +121,72 @@ int GpgFrontend::GpgKey::GetOwnerTrustLevel() const {
return 0;
}
-std::string GpgFrontend::GpgKey::GetPublicKeyAlgo() const {
+auto GpgKey::GetPublicKeyAlgo() const -> QString {
return gpgme_pubkey_algo_name(key_ref_->subkeys->pubkey_algo);
}
-boost::posix_time::ptime GpgFrontend::GpgKey::GetLastUpdateTime() const {
- return boost::posix_time::from_time_t(
+auto GpgKey::GetKeyAlgo() const -> QString {
+ auto *buffer = gpgme_pubkey_algo_string(key_ref_->subkeys);
+ auto algo = QString(buffer);
+ gpgme_free(buffer);
+ return algo.toUpper();
+}
+
+auto GpgKey::GetLastUpdateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(
static_cast<time_t>(key_ref_->last_update));
}
-boost::posix_time::ptime GpgFrontend::GpgKey::GetExpireTime() const {
- return boost::posix_time::from_time_t(key_ref_->subkeys->expires);
+auto GpgKey::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(key_ref_->subkeys->expires);
};
-boost::posix_time::ptime GpgFrontend::GpgKey::GetCreateTime() const {
- return boost::posix_time::from_time_t(key_ref_->subkeys->timestamp);
+auto GpgKey::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(key_ref_->subkeys->timestamp);
};
-unsigned int GpgFrontend::GpgKey::GetPrimaryKeyLength() const {
+auto GpgKey::GetPrimaryKeyLength() const -> unsigned int {
return key_ref_->subkeys->length;
}
-bool GpgFrontend::GpgKey::IsHasEncryptionCapability() const {
+auto GpgKey::IsHasEncryptionCapability() const -> bool {
return key_ref_->can_encrypt;
}
-bool GpgFrontend::GpgKey::IsHasSigningCapability() const {
+auto GpgKey::IsHasSigningCapability() const -> bool {
return key_ref_->can_sign;
}
-bool GpgFrontend::GpgKey::IsHasCertificationCapability() const {
+auto GpgKey::IsHasCertificationCapability() const -> bool {
return key_ref_->can_certify;
}
-bool GpgFrontend::GpgKey::IsHasAuthenticationCapability() const {
+auto GpgKey::IsHasAuthenticationCapability() const -> bool {
return key_ref_->can_authenticate;
}
-bool GpgFrontend::GpgKey::IsHasCardKey() const {
+auto GpgKey::IsHasCardKey() const -> bool {
auto subkeys = GetSubKeys();
return std::any_of(
subkeys->begin(), subkeys->end(),
[](const GpgSubKey &subkey) -> bool { return subkey.IsCardKey(); });
}
-bool GpgFrontend::GpgKey::IsPrivateKey() const { return key_ref_->secret; }
+auto GpgKey::IsPrivateKey() const -> bool { return key_ref_->secret; }
-bool GpgFrontend::GpgKey::IsExpired() const { return key_ref_->expired; }
+auto GpgKey::IsExpired() const -> bool { return key_ref_->expired; }
-bool GpgFrontend::GpgKey::IsRevoked() const { return key_ref_->revoked; }
+auto GpgKey::IsRevoked() const -> bool { return key_ref_->revoked; }
-bool GpgFrontend::GpgKey::IsDisabled() const { return key_ref_->disabled; }
+auto GpgKey::IsDisabled() const -> bool { return key_ref_->disabled; }
-bool GpgFrontend::GpgKey::IsHasMasterKey() const {
+auto GpgKey::IsHasMasterKey() const -> bool {
return key_ref_->subkeys->secret;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>>
-GpgFrontend::GpgKey::GetSubKeys() const {
+auto GpgKey::GetSubKeys() const -> std::unique_ptr<std::vector<GpgSubKey>> {
auto p_keys = std::make_unique<std::vector<GpgSubKey>>();
- auto next = key_ref_->subkeys;
+ auto *next = key_ref_->subkeys;
while (next != nullptr) {
p_keys->push_back(GpgSubKey(next));
next = next->next;
@@ -178,10 +194,9 @@ GpgFrontend::GpgKey::GetSubKeys() const {
return p_keys;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::GetUIDs()
- const {
+auto GpgKey::GetUIDs() const -> std::unique_ptr<std::vector<GpgUID>> {
auto p_uids = std::make_unique<std::vector<GpgUID>>();
- auto uid_next = key_ref_->uids;
+ auto *uid_next = key_ref_->uids;
while (uid_next != nullptr) {
p_uids->push_back(GpgUID(uid_next));
uid_next = uid_next->next;
@@ -189,32 +204,24 @@ std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::GetUIDs()
return p_uids;
}
-bool GpgFrontend::GpgKey::IsHasActualSigningCapability() const {
+auto GpgKey::IsHasActualSigningCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsSecretKey() &&
- subkey.IsHasSigningCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsSecretKey() && subkey.IsHasSigningCapability() &&
+ !subkey.IsDisabled() && !subkey.IsRevoked() &&
+ !subkey.IsExpired();
+ });
}
-bool GpgFrontend::GpgKey::IsHasActualAuthenticationCapability() const {
+auto GpgKey::IsHasActualAuthenticationCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsSecretKey() &&
- subkey.IsHasAuthenticationCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsSecretKey() && subkey.IsHasAuthenticationCapability() &&
+ !subkey.IsDisabled() && !subkey.IsRevoked() &&
+ !subkey.IsExpired();
+ });
}
/**
@@ -222,7 +229,7 @@ bool GpgFrontend::GpgKey::IsHasActualAuthenticationCapability() const {
* @param key target key
* @return if key certify
*/
-bool GpgFrontend::GpgKey::IsHasActualCertificationCapability() const {
+auto GpgKey::IsHasActualCertificationCapability() const -> bool {
return IsHasMasterKey() && !IsExpired() && !IsRevoked() && !IsDisabled();
}
@@ -231,28 +238,17 @@ bool GpgFrontend::GpgKey::IsHasActualCertificationCapability() const {
* @param key target key
* @return if key encrypt
*/
-bool GpgFrontend::GpgKey::IsHasActualEncryptionCapability() const {
+auto GpgKey::IsHasActualEncryptionCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsHasEncryptionCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
-}
-
-GpgFrontend::GpgKey GpgFrontend::GpgKey::Copy() const {
- {
- const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex);
- gpgme_key_ref(key_ref_.get());
- }
- auto *_new_key_ref = key_ref_.get();
- return GpgKey(std::move(_new_key_ref));
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsHasEncryptionCapability() && !subkey.IsDisabled() &&
+ !subkey.IsRevoked() && !subkey.IsExpired();
+ });
}
-void GpgFrontend::GpgKey::_key_ref_deleter::operator()(gpgme_key_t _key) {
+void GpgKey::KeyRefDeleter::operator()(gpgme_key_t _key) {
if (_key != nullptr) gpgme_key_unref(_key);
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h
index fb87b791..d9c97d59 100644
--- a/src/core/model/GpgKey.h
+++ b/src/core/model/GpgKey.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGKEY_H
-#define GPGFRONTEND_GPGKEY_H
+#pragma once
-#include <mutex>
-
-#include "GpgSubKey.h"
-#include "GpgUID.h"
+#include "core/model/GpgSubKey.h"
+#include "core/model/GpgUID.h"
namespace GpgFrontend {
@@ -41,6 +38,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgKey {
+ Q_DECLARE_TR_FUNCTIONS(GpgKey)
public:
/**
* @brief
@@ -48,98 +46,105 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsGood() const;
+ [[nodiscard]] auto IsGood() const -> bool;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetId() const;
+ [[nodiscard]] auto GetId() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetProtocol() const;
+ [[nodiscard]] auto GetProtocol() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetOwnerTrust() const;
+ [[nodiscard]] auto GetOwnerTrust() const -> QString;
/**
* @brief
*
* @return int
*/
- [[nodiscard]] int GetOwnerTrustLevel() const;
+ [[nodiscard]] auto GetOwnerTrustLevel() const -> int;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPublicKeyAlgo() const;
+ [[nodiscard]] auto GetPublicKeyAlgo() const -> QString;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QString
*/
- [[nodiscard]] boost::posix_time::ptime GetLastUpdateTime() const;
+ [[nodiscard]] auto GetKeyAlgo() const -> QString;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetLastUpdateTime() const -> QDateTime;
+
+ /**
+ * @brief
+ *
+ * @return QDateTime
+ */
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief s
*
* @return unsigned int
*/
- [[nodiscard]] unsigned int GetPrimaryKeyLength() const;
+ [[nodiscard]] auto GetPrimaryKeyLength() const -> unsigned int;
/**
* @brief
@@ -147,7 +152,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasEncryptionCapability() const;
+ [[nodiscard]] auto IsHasEncryptionCapability() const -> bool;
/**
* @brief
@@ -156,7 +161,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualEncryptionCapability() const;
+ [[nodiscard]] auto IsHasActualEncryptionCapability() const -> bool;
/**
* @brief
@@ -164,7 +169,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasSigningCapability() const;
+ [[nodiscard]] auto IsHasSigningCapability() const -> bool;
/**
* @brief
@@ -172,7 +177,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualSigningCapability() const;
+ [[nodiscard]] auto IsHasActualSigningCapability() const -> bool;
/**
* @brief
@@ -180,7 +185,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCertificationCapability() const;
+ [[nodiscard]] auto IsHasCertificationCapability() const -> bool;
/**
* @brief
@@ -188,7 +193,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualCertificationCapability() const;
+ [[nodiscard]] auto IsHasActualCertificationCapability() const -> bool;
/**
* @brief
@@ -196,7 +201,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasAuthenticationCapability() const -> bool;
/**
* @brief
@@ -204,7 +209,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasActualAuthenticationCapability() const -> bool;
/**
* @brief
@@ -212,7 +217,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCardKey() const;
+ [[nodiscard]] auto IsHasCardKey() const -> bool;
/**
* @brief
@@ -220,7 +225,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsPrivateKey() const;
+ [[nodiscard]] auto IsPrivateKey() const -> bool;
/**
* @brief
@@ -228,7 +233,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -236,7 +241,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -244,7 +249,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsDisabled() const;
+ [[nodiscard]] auto IsDisabled() const -> bool;
/**
* @brief
@@ -252,21 +257,22 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasMasterKey() const;
+ [[nodiscard]] auto IsHasMasterKey() const -> bool;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgSubKey>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> GetSubKeys() const;
+ [[nodiscard]] auto GetSubKeys() const
+ -> std::unique_ptr<std::vector<GpgSubKey>>;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgUID>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> GetUIDs() const;
+ [[nodiscard]] auto GetUIDs() const -> std::unique_ptr<std::vector<GpgUID>>;
/**
* @brief Construct a new Gpg Key object
@@ -299,7 +305,22 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
*
* @param k
*/
- GpgKey(GpgKey&& k) noexcept;
+ GpgKey(GpgKey&&) noexcept;
+
+ /**
+ * @brief
+ *
+ * @param k
+ * @return GpgKey&
+ */
+ auto operator=(GpgKey&&) noexcept -> GpgKey&;
+
+ /**
+ * @brief Construct a new Gpg Key object
+ *
+ * @param k
+ */
+ GpgKey(const GpgKey&);
/**
* @brief
@@ -307,7 +328,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @param k
* @return GpgKey&
*/
- GpgKey& operator=(GpgKey&& k) noexcept;
+ auto operator=(const GpgKey&) -> GpgKey&;
/**
* @brief
@@ -315,7 +336,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @param key
* @return GpgKey&
*/
- GpgKey& operator=(const gpgme_key_t& key) = delete;
+ auto operator=(const gpgme_key_t&) -> GpgKey& = delete;
/**
* @brief
@@ -324,7 +345,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- bool operator==(const GpgKey& o) const;
+ auto operator==(const GpgKey&) const -> bool;
/**
* @brief
@@ -333,7 +354,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- bool operator<=(const GpgKey& o) const;
+ auto operator<=(const GpgKey&) const -> bool;
/**
* @brief
@@ -342,30 +363,18 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
*/
explicit operator gpgme_key_t() const;
- /**
- * @brief
- *
- * @return GpgKey
- */
- [[nodiscard]] GpgKey Copy() const;
-
private:
/**
* @brief
*
*/
- struct GPGFRONTEND_CORE_EXPORT _key_ref_deleter {
+ struct GPGFRONTEND_CORE_EXPORT KeyRefDeleter {
void operator()(gpgme_key_t _key);
};
- using KeyRefHandler =
- std::unique_ptr<struct _gpgme_key, _key_ref_deleter>; ///<
+ using KeyRefHandler = std::unique_ptr<struct _gpgme_key, KeyRefDeleter>; ///<
KeyRefHandler key_ref_ = nullptr; ///<
-
- mutable std::mutex gpgme_key_opera_mutex; // mutex for gpgme key operations
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGKEY_H
diff --git a/src/core/model/GpgKeySignature.cpp b/src/core/model/GpgKeySignature.cpp
index aa196391..3182000c 100644
--- a/src/core/model/GpgKeySignature.cpp
+++ b/src/core/model/GpgKeySignature.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,67 +28,53 @@
#include "core/model/GpgKeySignature.h"
-GpgFrontend::GpgKeySignature::GpgKeySignature() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgKeySignature::~GpgKeySignature() = default;
+GpgKeySignature::GpgKeySignature() = default;
-GpgFrontend::GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig)
+GpgKeySignature::~GpgKeySignature() = default;
+
+GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig)
: signature_ref_(sig, [&](gpgme_key_sig_t signature) {}) {}
-GpgFrontend::GpgKeySignature::GpgKeySignature(GpgKeySignature &&) noexcept =
+GpgKeySignature::GpgKeySignature(GpgKeySignature &&) noexcept = default;
+
+GpgKeySignature &GpgKeySignature::operator=(GpgKeySignature &&) noexcept =
default;
-GpgFrontend::GpgKeySignature &GpgFrontend::GpgKeySignature::operator=(
- GpgKeySignature &&) noexcept = default;
+bool GpgKeySignature::IsRevoked() const { return signature_ref_->revoked; }
-bool GpgFrontend::GpgKeySignature::IsRevoked() const {
- return signature_ref_->revoked;
-}
-
-bool GpgFrontend::GpgKeySignature::IsExpired() const {
- return signature_ref_->expired;
-}
+bool GpgKeySignature::IsExpired() const { return signature_ref_->expired; }
-bool GpgFrontend::GpgKeySignature::IsInvalid() const {
- return signature_ref_->invalid;
-}
+bool GpgKeySignature::IsInvalid() const { return signature_ref_->invalid; }
-bool GpgFrontend::GpgKeySignature::IsExportable() const {
+bool GpgKeySignature::IsExportable() const {
return signature_ref_->exportable;
}
-gpgme_error_t GpgFrontend::GpgKeySignature::GetStatus() const {
+gpgme_error_t GpgKeySignature::GetStatus() const {
return signature_ref_->status;
}
-std::string GpgFrontend::GpgKeySignature::GetKeyID() const {
- return signature_ref_->keyid;
-}
+QString GpgKeySignature::GetKeyID() const { return signature_ref_->keyid; }
-std::string GpgFrontend::GpgKeySignature::GetPubkeyAlgo() const {
+QString GpgKeySignature::GetPubkeyAlgo() const {
return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo);
}
-boost::posix_time::ptime GpgFrontend::GpgKeySignature::GetCreateTime() const {
- return boost::posix_time::from_time_t(signature_ref_->timestamp);
+QDateTime GpgKeySignature::GetCreateTime() const {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->timestamp);
}
-boost::posix_time::ptime GpgFrontend::GpgKeySignature::GetExpireTime() const {
- return boost::posix_time::from_time_t(signature_ref_->expires);
+QDateTime GpgKeySignature::GetExpireTime() const {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->expires);
}
-std::string GpgFrontend::GpgKeySignature::GetUID() const {
- return signature_ref_->uid;
-}
+QString GpgKeySignature::GetUID() const { return signature_ref_->uid; }
-std::string GpgFrontend::GpgKeySignature::GetName() const {
- return signature_ref_->name;
-}
+QString GpgKeySignature::GetName() const { return signature_ref_->name; }
-std::string GpgFrontend::GpgKeySignature::GetEmail() const {
- return signature_ref_->email;
-}
+QString GpgKeySignature::GetEmail() const { return signature_ref_->email; }
-std::string GpgFrontend::GpgKeySignature::GetComment() const {
- return signature_ref_->comment;
-} \ No newline at end of file
+QString GpgKeySignature::GetComment() const { return signature_ref_->comment; }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKeySignature.h b/src/core/model/GpgKeySignature.h
index 25de2c75..c9ceeccc 100644
--- a/src/core/model/GpgKeySignature.h
+++ b/src/core/model/GpgKeySignature.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H
-#define GPGFRONTEND_GPGKEYSIGNATURE_H
+#pragma once
-#include <boost/date_time.hpp>
-#include <string>
-
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
/**
* @brief
@@ -52,7 +48,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -60,7 +56,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -68,7 +64,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsInvalid() const;
+ [[nodiscard]] auto IsInvalid() const -> bool;
/**
* @brief
@@ -76,70 +72,70 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExportable() const;
+ [[nodiscard]] auto IsExportable() const -> bool;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> GpgError;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetKeyID() const;
+ [[nodiscard]] auto GetKeyID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUID() const;
+ [[nodiscard]] auto GetUID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief Construct a new Gpg Key Signature object
@@ -177,14 +173,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
*
* @return GpgKeySignature&
*/
- GpgKeySignature &operator=(GpgKeySignature &&) noexcept;
+ auto operator=(GpgKeySignature &&) noexcept -> GpgKeySignature &;
/**
* @brief
*
* @return GpgKeySignature&
*/
- GpgKeySignature &operator=(const GpgKeySignature &) = delete;
+ auto operator=(const GpgKeySignature &) -> GpgKeySignature & = delete;
private:
using KeySignatrueRefHandler =
@@ -195,5 +191,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGKEYSIGNATURE_H
diff --git a/src/core/model/GpgPassphraseContext.cpp b/src/core/model/GpgPassphraseContext.cpp
new file mode 100644
index 00000000..5df3f5a8
--- /dev/null
+++ b/src/core/model/GpgPassphraseContext.cpp
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgPassphraseContext.h"
+
+namespace GpgFrontend {
+
+GpgPassphraseContext::GpgPassphraseContext(const QString& uids_info,
+ const QString& passphrase_info,
+ bool prev_was_bad, bool ask_for_new)
+ : passphrase_info_(passphrase_info),
+ uids_info_(uids_info),
+ prev_was_bad_(prev_was_bad),
+ ask_for_new_(ask_for_new) {}
+
+GpgPassphraseContext::GpgPassphraseContext() = default;
+
+auto GpgPassphraseContext::GetPassphrase() const -> QString {
+ return passphrase_;
+}
+
+void GpgPassphraseContext::SetPassphrase(const QString& passphrase) {
+ passphrase_ = passphrase;
+}
+
+auto GpgPassphraseContext::GetUidsInfo() const -> QString { return uids_info_; }
+
+auto GpgPassphraseContext::GetPassphraseInfo() const -> QString {
+ return passphrase_info_;
+}
+
+auto GpgPassphraseContext::IsPreWasBad() const -> bool { return prev_was_bad_; }
+
+auto GpgPassphraseContext::IsAskForNew() const -> bool { return ask_for_new_; }
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgPassphraseContext.h b/src/core/model/GpgPassphraseContext.h
new file mode 100644
index 00000000..2bc1ac75
--- /dev/null
+++ b/src/core/model/GpgPassphraseContext.h
@@ -0,0 +1,63 @@
+
+
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgPassphraseContext : public QObject {
+ Q_OBJECT
+ public:
+ GpgPassphraseContext(const QString& uids_info, const QString& passphrase_info,
+ bool prev_was_bad, bool ask_for_new);
+
+ GpgPassphraseContext();
+
+ void SetPassphrase(const QString& passphrase);
+
+ [[nodiscard]] auto GetPassphrase() const -> QString;
+
+ [[nodiscard]] auto GetUidsInfo() const -> QString;
+
+ [[nodiscard]] auto GetPassphraseInfo() const -> QString;
+
+ [[nodiscard]] auto IsPreWasBad() const -> bool;
+
+ [[nodiscard]] auto IsAskForNew() const -> bool;
+
+ private:
+ QString passphrase_info_;
+ QString uids_info_;
+ QString passphrase_;
+ bool prev_was_bad_;
+ bool ask_for_new_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgRecipient.cpp b/src/core/model/GpgRecipient.cpp
new file mode 100644
index 00000000..54de43bc
--- /dev/null
+++ b/src/core/model/GpgRecipient.cpp
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgRecipient.h"
+
+namespace GpgFrontend {
+
+GpgRecipient::GpgRecipient() = default;
+
+GpgRecipient::GpgRecipient(gpgme_recipient_t r) {
+ this->keyid = QString{r->keyid};
+ this->pubkey_algo = QString{gpgme_pubkey_algo_name(r->pubkey_algo)};
+ this->status = r->status;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgRecipient.h b/src/core/model/GpgRecipient.h
new file mode 100644
index 00000000..a436c1d7
--- /dev/null
+++ b/src/core/model/GpgRecipient.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+struct GPGFRONTEND_CORE_EXPORT GpgRecipient {
+ /* The key ID of key for which the text was encrypted. */
+ QString keyid;
+
+ /* The public key algorithm of the recipient key. */
+ QString pubkey_algo;
+
+ /* The status of the recipient. */
+ GpgError status;
+
+ GpgRecipient();
+
+ explicit GpgRecipient(gpgme_recipient_t r);
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.cpp b/src/core/model/GpgSignResult.cpp
new file mode 100644
index 00000000..4a0e5f35
--- /dev/null
+++ b/src/core/model/GpgSignResult.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgSignResult.h"
+
+namespace GpgFrontend {
+GpgSignResult::GpgSignResult(gpgme_sign_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_sign_result>(
+ (gpgme_result_ref(r), r), [](gpgme_sign_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgSignResult::GpgSignResult() = default;
+
+GpgSignResult::~GpgSignResult() = default;
+
+auto GpgSignResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgSignResult::GetRaw() -> gpgme_sign_result_t {
+ return result_ref_.get();
+}
+
+auto GpgSignResult::InvalidSigners()
+ -> std::vector<std::tuple<QString, GpgError>> {
+ std::vector<std::tuple<QString, GpgError>> result;
+ for (auto* invalid_key = result_ref_->invalid_signers; invalid_key != nullptr;
+ invalid_key = invalid_key->next) {
+ try {
+ result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_signers, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.h b/src/core/model/GpgSignResult.h
new file mode 100644
index 00000000..ccb0361f
--- /dev/null
+++ b/src/core/model/GpgSignResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgSignResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_sign_result_t;
+
+ auto InvalidSigners() -> std::vector<std::tuple<QString, GpgError>>;
+
+ explicit GpgSignResult(gpgme_sign_result_t);
+
+ GpgSignResult();
+
+ virtual ~GpgSignResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_sign_result> result_ref_ = nullptr; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignature.cpp b/src/core/model/GpgSignature.cpp
index 73f9179d..e2cb7e4b 100644
--- a/src/core/model/GpgSignature.cpp
+++ b/src/core/model/GpgSignature.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,21 +28,28 @@
#include "GpgSignature.h"
+namespace GpgFrontend {
+
/**
* @brief Construct a new Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::GpgSignature(GpgSignature &&) noexcept = default;
+GpgSignature::GpgSignature(GpgSignature &&) noexcept = default;
/**
* @brief
*
* @return GpgSignature&
*/
-GpgFrontend::GpgSignature &GpgFrontend::GpgSignature::operator=(
- GpgFrontend::GpgSignature &&) noexcept = default;
+auto GpgSignature::operator=(GpgSignature &&) noexcept
+ -> GpgSignature & = default;
-GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig)
+/**
+ * @brief Construct a new Gpg Signature:: Gpg Signature object
+ *
+ * @param sig
+ */
+GpgSignature::GpgSignature(gpgme_signature_t sig)
: signature_ref_(sig, [&](gpgme_signature_t signature) {}) {}
/**
@@ -50,7 +57,7 @@ GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig)
*
* @return gpgme_validity_t
*/
-gpgme_validity_t GpgFrontend::GpgSignature::GetValidity() const {
+auto GpgSignature::GetValidity() const -> gpgme_validity_t {
return signature_ref_->validity;
}
@@ -59,7 +66,7 @@ gpgme_validity_t GpgFrontend::GpgSignature::GetValidity() const {
*
* @return gpgme_error_t
*/
-gpgme_error_t GpgFrontend::GpgSignature::GetStatus() const {
+auto GpgSignature::GetStatus() const -> gpgme_error_t {
return signature_ref_->status;
}
@@ -68,52 +75,52 @@ gpgme_error_t GpgFrontend::GpgSignature::GetStatus() const {
*
* @return gpgme_error_t
*/
-gpgme_error_t GpgFrontend::GpgSignature::GetSummary() const {
+auto GpgSignature::GetSummary() const -> gpgme_error_t {
return signature_ref_->summary;
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetPubkeyAlgo() const {
+auto GpgSignature::GetPubkeyAlgo() const -> QString {
return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo);
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetHashAlgo() const {
+auto GpgSignature::GetHashAlgo() const -> QString {
return gpgme_hash_algo_name(signature_ref_->hash_algo);
}
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
-boost::posix_time::ptime GpgFrontend::GpgSignature::GetCreateTime() const {
- return boost::posix_time::from_time_t(signature_ref_->timestamp);
+auto GpgSignature::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->timestamp);
}
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
-boost::posix_time::ptime GpgFrontend::GpgSignature::GetExpireTime() const {
- return boost::posix_time::from_time_t(signature_ref_->exp_timestamp);
+auto GpgSignature::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->exp_timestamp);
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetFingerprint() const {
+auto GpgSignature::GetFingerprint() const -> QString {
return signature_ref_->fpr;
}
@@ -121,10 +128,12 @@ std::string GpgFrontend::GpgSignature::GetFingerprint() const {
* @brief Construct a new Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::GpgSignature() = default;
+GpgSignature::GpgSignature() = default;
/**
* @brief Destroy the Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::~GpgSignature() = default;
+GpgSignature::~GpgSignature() = default;
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgSignature.h b/src/core/model/GpgSignature.h
index 2e49c4d7..316b9100 100644
--- a/src/core/model/GpgSignature.h
+++ b/src/core/model/GpgSignature.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSIGNATURE_H
-#define GPGFRONTEND_GPGSIGNATURE_H
+#pragma once
-#include <boost/date_time/gregorian/greg_date.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -47,56 +43,56 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
*
* @return gpgme_validity_t
*/
- [[nodiscard]] gpgme_validity_t GetValidity() const;
+ [[nodiscard]] auto GetValidity() const -> gpgme_validity_t;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> GpgError;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetSummary() const;
+ [[nodiscard]] auto GetSummary() const -> GpgError;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetHashAlgo() const;
+ [[nodiscard]] auto GetHashAlgo() const -> QString;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief Construct a new Gpg Signature object
@@ -134,14 +130,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
*
* @return GpgSignature&
*/
- GpgSignature &operator=(GpgSignature &&) noexcept;
+ auto operator=(GpgSignature &&) noexcept -> GpgSignature &;
/**
* @brief
*
* @return GpgSignature&
*/
- GpgSignature &operator=(const GpgSignature &) = delete;
+ auto operator=(const GpgSignature &) -> GpgSignature & = delete;
private:
using KeySignatrueRefHandler =
@@ -151,5 +147,3 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
KeySignatrueRefHandler signature_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSIGNATURE_H
diff --git a/src/core/model/GpgSubKey.cpp b/src/core/model/GpgSubKey.cpp
index e63816b1..cb0078de 100644
--- a/src/core/model/GpgSubKey.cpp
+++ b/src/core/model/GpgSubKey.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,84 +20,86 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "core/model/GpgSubKey.h"
+#include "GpgSubKey.h"
-GpgFrontend::GpgSubKey::GpgSubKey() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgSubKey::GpgSubKey(gpgme_subkey_t subkey)
- : _subkey_ref(subkey, [&](gpgme_subkey_t subkey) {}) {}
+GpgSubKey::GpgSubKey() = default;
-GpgFrontend::GpgSubKey::GpgSubKey(GpgSubKey&& o) noexcept {
- swap(_subkey_ref, o._subkey_ref);
+GpgSubKey::GpgSubKey(gpgme_subkey_t subkey)
+ : subkey_ref_(subkey, [&](gpgme_subkey_t subkey) {}) {}
+
+GpgSubKey::GpgSubKey(GpgSubKey&& o) noexcept {
+ swap(subkey_ref_, o.subkey_ref_);
}
-GpgFrontend::GpgSubKey& GpgFrontend::GpgSubKey::operator=(
- GpgSubKey&& o) noexcept {
- swap(_subkey_ref, o._subkey_ref);
+auto GpgSubKey::operator=(GpgSubKey&& o) noexcept -> GpgSubKey& {
+ swap(subkey_ref_, o.subkey_ref_);
return *this;
};
-bool GpgFrontend::GpgSubKey::operator==(const GpgSubKey& o) const {
+auto GpgSubKey::operator==(const GpgSubKey& o) const -> bool {
return GetFingerprint() == o.GetFingerprint();
}
-std::string GpgFrontend::GpgSubKey::GetID() const { return _subkey_ref->keyid; }
+auto GpgSubKey::GetID() const -> QString { return subkey_ref_->keyid; }
-std::string GpgFrontend::GpgSubKey::GetFingerprint() const {
- return _subkey_ref->fpr;
-}
+auto GpgSubKey::GetFingerprint() const -> QString { return subkey_ref_->fpr; }
-std::string GpgFrontend::GpgSubKey::GetPubkeyAlgo() const {
- return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo);
+auto GpgSubKey::GetPubkeyAlgo() const -> QString {
+ return gpgme_pubkey_algo_name(subkey_ref_->pubkey_algo);
}
-unsigned int GpgFrontend::GpgSubKey::GetKeyLength() const {
- return _subkey_ref->length;
+auto GpgSubKey::GetKeyAlgo() const -> QString {
+ auto* buffer = gpgme_pubkey_algo_string(subkey_ref_.get());
+ auto algo = QString(buffer);
+ gpgme_free(buffer);
+ return algo.toUpper();
}
-bool GpgFrontend::GpgSubKey::IsHasEncryptionCapability() const {
- return _subkey_ref->can_encrypt;
+auto GpgSubKey::GetKeyLength() const -> unsigned int {
+ return subkey_ref_->length;
}
-bool GpgFrontend::GpgSubKey::IsHasSigningCapability() const {
- return _subkey_ref->can_sign;
+auto GpgSubKey::IsHasEncryptionCapability() const -> bool {
+ return subkey_ref_->can_encrypt;
}
-bool GpgFrontend::GpgSubKey::IsHasCertificationCapability() const {
- return _subkey_ref->can_certify;
+auto GpgSubKey::IsHasSigningCapability() const -> bool {
+ return subkey_ref_->can_sign;
}
-bool GpgFrontend::GpgSubKey::IsHasAuthenticationCapability() const {
- return _subkey_ref->can_authenticate;
+auto GpgSubKey::IsHasCertificationCapability() const -> bool {
+ return subkey_ref_->can_certify;
}
-bool GpgFrontend::GpgSubKey::IsPrivateKey() const {
- return _subkey_ref->secret;
+auto GpgSubKey::IsHasAuthenticationCapability() const -> bool {
+ return subkey_ref_->can_authenticate;
}
-bool GpgFrontend::GpgSubKey::IsExpired() const { return _subkey_ref->expired; }
+auto GpgSubKey::IsPrivateKey() const -> bool { return subkey_ref_->secret; }
-bool GpgFrontend::GpgSubKey::IsRevoked() const { return _subkey_ref->revoked; }
+auto GpgSubKey::IsExpired() const -> bool { return subkey_ref_->expired; }
-bool GpgFrontend::GpgSubKey::IsDisabled() const {
- return _subkey_ref->disabled;
-}
+auto GpgSubKey::IsRevoked() const -> bool { return subkey_ref_->revoked; }
-bool GpgFrontend::GpgSubKey::IsSecretKey() const { return _subkey_ref->secret; }
+auto GpgSubKey::IsDisabled() const -> bool { return subkey_ref_->disabled; }
-bool GpgFrontend::GpgSubKey::IsCardKey() const {
- return _subkey_ref->is_cardkey;
-}
+auto GpgSubKey::IsSecretKey() const -> bool { return subkey_ref_->secret; }
+
+auto GpgSubKey::IsCardKey() const -> bool { return subkey_ref_->is_cardkey; }
-boost::posix_time::ptime GpgFrontend::GpgSubKey::GetCreateTime() const {
- return boost::posix_time::from_time_t(_subkey_ref->timestamp);
+auto GpgSubKey::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(subkey_ref_->timestamp);
}
-boost::posix_time::ptime GpgFrontend::GpgSubKey::GetExpireTime() const {
- return boost::posix_time::from_time_t(_subkey_ref->expires);
+auto GpgSubKey::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(subkey_ref_->expires);
}
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h
index 5a86d21d..83d75e2d 100644
--- a/src/core/model/GpgSubKey.h
+++ b/src/core/model/GpgSubKey.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSUBKEY_H
-#define GPGFRONTEND_GPGSUBKEY_H
-
-#include <boost/date_time.hpp>
-#include <string>
-
-#include "core/GpgConstants.h"
+#pragma once
namespace GpgFrontend {
@@ -45,30 +39,37 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
/**
* @brief
*
- * @return std::string
+ * @return QString
+ */
+ [[nodiscard]] auto GetID() const -> QString;
+
+ /**
+ * @brief
+ *
+ * @return QString
*/
- [[nodiscard]] std::string GetID() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetKeyAlgo() const -> QString;
/**
* @brief
*
* @return unsigned int
*/
- [[nodiscard]] unsigned int GetKeyLength() const;
+ [[nodiscard]] auto GetKeyLength() const -> unsigned int;
/**
* @brief
@@ -76,7 +77,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasEncryptionCapability() const;
+ [[nodiscard]] auto IsHasEncryptionCapability() const -> bool;
/**
* @brief
@@ -84,7 +85,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasSigningCapability() const;
+ [[nodiscard]] auto IsHasSigningCapability() const -> bool;
/**
* @brief
@@ -92,7 +93,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCertificationCapability() const;
+ [[nodiscard]] auto IsHasCertificationCapability() const -> bool;
/**
* @brief
@@ -100,7 +101,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasAuthenticationCapability() const -> bool;
/**
* @brief
@@ -108,7 +109,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsPrivateKey() const;
+ [[nodiscard]] auto IsPrivateKey() const -> bool;
/**
* @brief
@@ -116,7 +117,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -124,7 +125,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -132,7 +133,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsDisabled() const;
+ [[nodiscard]] auto IsDisabled() const -> bool;
/**
* @brief
@@ -140,7 +141,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsSecretKey() const;
+ [[nodiscard]] auto IsSecretKey() const -> bool;
/**
* @brief
@@ -148,21 +149,21 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsCardKey() const;
+ [[nodiscard]] auto IsCardKey() const -> bool;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] QDateTime GetExpireTime() const;
/**
* @brief Construct a new Gpg Sub Key object
@@ -196,14 +197,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @param o
* @return GpgSubKey&
*/
- GpgSubKey& operator=(GpgSubKey&& o) noexcept;
+ auto operator=(GpgSubKey&& o) noexcept -> GpgSubKey&;
/**
* @brief
*
* @return GpgSubKey&
*/
- GpgSubKey& operator=(const GpgSubKey&) = delete;
+ auto operator=(const GpgSubKey&) -> GpgSubKey& = delete;
/**
* @brief
@@ -212,16 +213,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- bool operator==(const GpgSubKey& o) const;
+ auto operator==(const GpgSubKey& o) const -> bool;
private:
using SubkeyRefHandler =
std::unique_ptr<struct _gpgme_subkey,
std::function<void(gpgme_subkey_t)>>; ///<
- SubkeyRefHandler _subkey_ref = nullptr; ///<
+ SubkeyRefHandler subkey_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSUBKEY_H
diff --git a/src/core/model/GpgTOFUInfo.cpp b/src/core/model/GpgTOFUInfo.cpp
index 84ce1e29..251affc2 100644
--- a/src/core/model/GpgTOFUInfo.cpp
+++ b/src/core/model/GpgTOFUInfo.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,39 +28,40 @@
#include "GpgTOFUInfo.h"
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo(gpgme_tofu_info_t tofu_info)
- : _tofu_info_ref(tofu_info, [&](gpgme_tofu_info_t tofu_info) {}) {}
+GpgTOFUInfo::GpgTOFUInfo() = default;
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo(GpgTOFUInfo&& o) noexcept {
- swap(_tofu_info_ref, o._tofu_info_ref);
+GpgTOFUInfo::GpgTOFUInfo(gpgme_tofu_info_t tofu_info)
+ : tofu_info_ref_(tofu_info, [&](gpgme_tofu_info_t tofu_info) {}) {}
+
+GpgTOFUInfo::GpgTOFUInfo(GpgTOFUInfo&& o) noexcept {
+ swap(tofu_info_ref_, o.tofu_info_ref_);
}
-GpgFrontend::GpgTOFUInfo& GpgFrontend::GpgTOFUInfo::operator=(
- GpgTOFUInfo&& o) noexcept {
- swap(_tofu_info_ref, o._tofu_info_ref);
+auto GpgTOFUInfo::operator=(GpgTOFUInfo&& o) noexcept -> GpgTOFUInfo& {
+ swap(tofu_info_ref_, o.tofu_info_ref_);
return *this;
};
-unsigned GpgFrontend::GpgTOFUInfo::GetValidity() const {
- return _tofu_info_ref->validity;
+auto GpgTOFUInfo::GetValidity() const -> unsigned {
+ return tofu_info_ref_->validity;
}
-unsigned GpgFrontend::GpgTOFUInfo::GetPolicy() const {
- return _tofu_info_ref->policy;
+auto GpgTOFUInfo::GetPolicy() const -> unsigned {
+ return tofu_info_ref_->policy;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignCount() const {
- return _tofu_info_ref->signcount;
+auto GpgTOFUInfo::GetSignCount() const -> unsigned long {
+ return tofu_info_ref_->signcount;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetEncrCount() const {
- return _tofu_info_ref->encrcount;
+auto GpgTOFUInfo::GetEncrCount() const -> unsigned long {
+ return tofu_info_ref_->encrcount;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignFirst() const {
- return _tofu_info_ref->signfirst;
+auto GpgTOFUInfo::GetSignFirst() const -> unsigned long {
+ return tofu_info_ref_->signfirst;
}
/**
@@ -68,8 +69,8 @@ unsigned long GpgFrontend::GpgTOFUInfo::GetSignFirst() const {
*
* @return unsigned long
*/
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignLast() const {
- return _tofu_info_ref->signlast;
+auto GpgTOFUInfo::GetSignLast() const -> unsigned long {
+ return tofu_info_ref_->signlast;
}
/**
@@ -77,15 +78,17 @@ unsigned long GpgFrontend::GpgTOFUInfo::GetSignLast() const {
*
* @return unsigned long
*/
-unsigned long GpgFrontend::GpgTOFUInfo::GetEncrLast() const {
- return _tofu_info_ref->encrlast;
+auto GpgTOFUInfo::GetEncrLast() const -> unsigned long {
+ return tofu_info_ref_->encrlast;
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgTOFUInfo::GetDescription() const {
- return _tofu_info_ref->description;
-} \ No newline at end of file
+auto GpgTOFUInfo::GetDescription() const -> QString {
+ return tofu_info_ref_->description;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgTOFUInfo.h b/src/core/model/GpgTOFUInfo.h
index b82a4eb2..ec4c49b7 100644
--- a/src/core/model/GpgTOFUInfo.h
+++ b/src/core/model/GpgTOFUInfo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGTOFU_H
-#define GPGFRONTEND_GPGTOFU_H
-
-#include "core/GpgConstants.h"
+#pragma once
namespace GpgFrontend {
/**
@@ -43,55 +40,55 @@ class GPGFRONTEND_CORE_EXPORT GpgTOFUInfo {
*
* @return unsigned
*/
- [[nodiscard]] unsigned GetValidity() const;
+ [[nodiscard]] auto GetValidity() const -> unsigned;
/**
* @brief
*
* @return unsigned
*/
- [[nodiscard]] unsigned GetPolicy() const;
+ [[nodiscard]] auto GetPolicy() const -> unsigned;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignCount() const;
+ [[nodiscard]] auto GetSignCount() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetEncrCount() const;
+ [[nodiscard]] auto GetEncrCount() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignFirst() const;
+ [[nodiscard]] auto GetSignFirst() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignLast() const;
+ [[nodiscard]] auto GetSignLast() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetEncrLast() const;
+ [[nodiscard]] auto GetEncrLast() const -> unsigned long;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetDescription() const;
+ [[nodiscard]] auto GetDescription() const -> QString;
/**
* @brief Construct a new Gpg T O F U Info object
@@ -125,23 +122,21 @@ class GPGFRONTEND_CORE_EXPORT GpgTOFUInfo {
* @param o
* @return GpgTOFUInfo&
*/
- GpgTOFUInfo& operator=(GpgTOFUInfo&& o) noexcept;
+ auto operator=(GpgTOFUInfo&& o) noexcept -> GpgTOFUInfo&;
/**
* @brief
*
* @return GpgTOFUInfo&
*/
- GpgTOFUInfo& operator=(const GpgTOFUInfo&) = delete;
+ auto operator=(const GpgTOFUInfo&) -> GpgTOFUInfo& = delete;
private:
using SubkeyRefHandler =
std::unique_ptr<struct _gpgme_tofu_info,
std::function<void(gpgme_tofu_info_t)>>; ///<
- SubkeyRefHandler _tofu_info_ref = nullptr; ///<
+ SubkeyRefHandler tofu_info_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGTOFU_H
diff --git a/src/core/model/GpgUID.cpp b/src/core/model/GpgUID.cpp
index d87192c3..e0d9d3a6 100644
--- a/src/core/model/GpgUID.cpp
+++ b/src/core/model/GpgUID.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,31 +28,30 @@
#include "core/model/GpgUID.h"
-GpgFrontend::GpgUID::GpgUID() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgUID::GpgUID(gpgme_user_id_t uid)
+GpgUID::GpgUID() = default;
+
+GpgUID::GpgUID(gpgme_user_id_t uid)
: uid_ref_(uid, [&](gpgme_user_id_t uid) {}) {}
-GpgFrontend::GpgUID::GpgUID(GpgUID &&o) noexcept { swap(uid_ref_, o.uid_ref_); }
+GpgUID::GpgUID(GpgUID &&o) noexcept { swap(uid_ref_, o.uid_ref_); }
-std::string GpgFrontend::GpgUID::GetName() const { return uid_ref_->name; }
+auto GpgUID::GetName() const -> QString { return uid_ref_->name; }
-std::string GpgFrontend::GpgUID::GetEmail() const { return uid_ref_->email; }
+auto GpgUID::GetEmail() const -> QString { return uid_ref_->email; }
-std::string GpgFrontend::GpgUID::GetComment() const {
- return uid_ref_->comment;
-}
+auto GpgUID::GetComment() const -> QString { return uid_ref_->comment; }
-std::string GpgFrontend::GpgUID::GetUID() const { return uid_ref_->uid; }
+auto GpgUID::GetUID() const -> QString { return uid_ref_->uid; }
-bool GpgFrontend::GpgUID::GetRevoked() const { return uid_ref_->revoked; }
+auto GpgUID::GetRevoked() const -> bool { return uid_ref_->revoked; }
-bool GpgFrontend::GpgUID::GetInvalid() const { return uid_ref_->invalid; }
+auto GpgUID::GetInvalid() const -> bool { return uid_ref_->invalid; }
-std::unique_ptr<std::vector<GpgFrontend::GpgTOFUInfo>>
-GpgFrontend::GpgUID::GetTofuInfos() const {
+auto GpgUID::GetTofuInfos() const -> std::unique_ptr<std::vector<GpgTOFUInfo>> {
auto infos = std::make_unique<std::vector<GpgTOFUInfo>>();
- auto info_next = uid_ref_->tofu;
+ auto *info_next = uid_ref_->tofu;
while (info_next != nullptr) {
infos->push_back(GpgTOFUInfo(info_next));
info_next = info_next->next;
@@ -60,13 +59,15 @@ GpgFrontend::GpgUID::GetTofuInfos() const {
return infos;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgKeySignature>>
-GpgFrontend::GpgUID::GetSignatures() const {
+auto GpgUID::GetSignatures() const
+ -> std::unique_ptr<std::vector<GpgKeySignature>> {
auto sigs = std::make_unique<std::vector<GpgKeySignature>>();
- auto sig_next = uid_ref_->signatures;
+ auto *sig_next = uid_ref_->signatures;
while (sig_next != nullptr) {
sigs->push_back(GpgKeySignature(sig_next));
sig_next = sig_next->next;
}
return sigs;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgUID.h b/src/core/model/GpgUID.h
index 670c318d..14b4db3f 100644
--- a/src/core/model/GpgUID.h
+++ b/src/core/model/GpgUID.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGUID_H
-#define GPGFRONTEND_GPGUID_H
+#pragma once
#include "GpgKeySignature.h"
#include "GpgTOFUInfo.h"
@@ -42,30 +41,30 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUID() const;
+ [[nodiscard]] auto GetUID() const -> QString;
/**
* @brief
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @return true
* @return false
*/
- [[nodiscard]] bool GetRevoked() const;
+ [[nodiscard]] auto GetRevoked() const -> bool;
/**
* @brief
@@ -81,22 +80,23 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @return true
* @return false
*/
- [[nodiscard]] bool GetInvalid() const;
+ [[nodiscard]] auto GetInvalid() const -> bool;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgTOFUInfo>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgTOFUInfo>> GetTofuInfos() const;
+ [[nodiscard]] auto GetTofuInfos() const
+ -> std::unique_ptr<std::vector<GpgTOFUInfo>>;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgKeySignature>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> GetSignatures()
- const;
+ [[nodiscard]] auto GetSignatures() const
+ -> std::unique_ptr<std::vector<GpgKeySignature>>;
/**
* @brief Construct a new Gpg U I D object
@@ -130,14 +130,14 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @param o
* @return GpgUID&
*/
- GpgUID &operator=(GpgUID &&o) noexcept;
+ auto operator=(GpgUID &&o) noexcept -> GpgUID &;
/**
* @brief
*
* @return GpgUID&
*/
- GpgUID &operator=(const GpgUID &) = delete;
+ auto operator=(const GpgUID &) -> GpgUID & = delete;
private:
using UidRefHandler =
@@ -148,5 +148,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGUID_H \ No newline at end of file
diff --git a/src/core/model/GpgVerifyResult.cpp b/src/core/model/GpgVerifyResult.cpp
new file mode 100644
index 00000000..75421c69
--- /dev/null
+++ b/src/core/model/GpgVerifyResult.cpp
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgVerifyResult.h"
+
+#include "core/model/GpgSignature.h"
+
+namespace GpgFrontend {
+GpgVerifyResult::GpgVerifyResult(gpgme_verify_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_verify_result>(
+ (gpgme_result_ref(r), r), [](gpgme_verify_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgVerifyResult::GpgVerifyResult() = default;
+
+GpgVerifyResult::~GpgVerifyResult() = default;
+
+auto GpgVerifyResult::IsGood() const -> bool { return result_ref_ != nullptr; }
+
+auto GpgVerifyResult::GetRaw() const -> gpgme_verify_result_t {
+ return result_ref_.get();
+}
+
+auto GpgVerifyResult::GetSignature() const -> std::vector<GpgSignature> {
+ std::vector<GpgSignature> sigatures;
+
+ auto* signature = result_ref_->signatures;
+ while (signature != nullptr) {
+ sigatures.emplace_back(signature);
+ signature = signature->next;
+ }
+ return sigatures;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgVerifyResult.h b/src/core/model/GpgVerifyResult.h
new file mode 100644
index 00000000..cae43c10
--- /dev/null
+++ b/src/core/model/GpgVerifyResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgVerifyResult {
+ public:
+ [[nodiscard]] auto IsGood() const -> bool;
+
+ [[nodiscard]] auto GetRaw() const -> gpgme_verify_result_t;
+
+ [[nodiscard]] auto GetSignature() const -> std::vector<GpgSignature>;
+
+ explicit GpgVerifyResult(gpgme_verify_result_t);
+
+ GpgVerifyResult();
+
+ virtual ~GpgVerifyResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_verify_result> result_ref_ = nullptr; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp
new file mode 100644
index 00000000..fab26453
--- /dev/null
+++ b/src/core/module/Event.cpp
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "Event.h"
+
+namespace GpgFrontend::Module {
+
+class Event::Impl {
+ public:
+ Impl(QString event_id, std::initializer_list<ParameterInitializer> params,
+ EventCallback callback)
+ : event_identifier_(std::move(event_id)),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()) {
+ for (const auto& param : params) {
+ AddParameter(param);
+ }
+ GF_CORE_LOG_DEBUG("create event {}", event_identifier_);
+ }
+
+ auto operator[](const QString& key) const -> std::optional<ParameterValue> {
+ auto it_data = data_.find(key);
+ if (it_data != data_.end()) {
+ return it_data->second;
+ }
+ return std::nullopt;
+ }
+
+ auto operator==(const Event& other) const -> bool {
+ return event_identifier_ == other.p_->event_identifier_;
+ }
+
+ auto operator!=(const Event& other) const -> bool {
+ return !(*this == other);
+ }
+
+ auto operator<(const Event& other) const -> bool {
+ return this->event_identifier_ < other.p_->event_identifier_;
+ }
+
+ explicit operator QString() const { return event_identifier_; }
+
+ auto GetIdentifier() -> EventIdentifier { return event_identifier_; }
+
+ void AddParameter(const QString& key, const ParameterValue& value) {
+ data_[key] = value;
+ }
+
+ void AddParameter(const ParameterInitializer& param) {
+ AddParameter(param.key, param.value);
+ }
+
+ void ExecuteCallback(ListenerIdentifier listener_id,
+ const DataObjectPtr& data_object) {
+ GF_CORE_LOG_DEBUG("try to execute callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ if (callback_) {
+ GF_CORE_LOG_DEBUG("executing callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ if (!QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, event_identifier = event_identifier_,
+ listener_id, data_object]() {
+ callback(event_identifier, listener_id, data_object);
+ })) {
+ GF_CORE_LOG_ERROR(
+ "failed to invoke callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ }
+ }
+ }
+
+ private:
+ EventIdentifier event_identifier_;
+ std::map<QString, ParameterValue> data_;
+ EventCallback callback_;
+ QThread* callback_thread_ = nullptr; ///<
+};
+
+Event::Event(const QString& event_id,
+ std::initializer_list<ParameterInitializer> params,
+ EventCallback callback)
+ : p_(SecureCreateUniqueObject<Impl>(event_id, params,
+ std::move(callback))) {}
+
+Event::~Event() = default;
+
+auto Event::Event::operator==(const Event& other) const -> bool {
+ return this->p_ == other.p_;
+}
+
+auto Event::Event::operator!=(const Event& other) const -> bool {
+ return this->p_ != other.p_;
+}
+
+auto Event::Event::operator<(const Event& other) const -> bool {
+ return this->p_ < other.p_;
+}
+
+Event::Event::operator QString() const { return static_cast<QString>(*p_); }
+
+auto Event::Event::GetIdentifier() -> EventIdentifier {
+ return p_->GetIdentifier();
+}
+
+void Event::AddParameter(const QString& key, const ParameterValue& value) {
+ p_->AddParameter(key, value);
+}
+
+void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) {
+ p_->ExecuteCallback(std::move(l_id), d_o);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/Event.h b/src/core/module/Event.h
new file mode 100644
index 00000000..92268216
--- /dev/null
+++ b/src/core/module/Event.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <functional>
+#include <optional>
+
+#include "core/GpgFrontendCore.h"
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend::Module {
+
+class Event;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using EventIdentifier = QString;
+using Evnets = std::vector<Event>;
+
+class GPGFRONTEND_CORE_EXPORT Event {
+ public:
+ using ParameterValue = std::any;
+ using EventIdentifier = QString;
+ using ListenerIdentifier = QString;
+ using EventCallback =
+ std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>;
+ struct ParameterInitializer {
+ QString key;
+ ParameterValue value;
+ };
+
+ explicit Event(const QString&,
+ std::initializer_list<ParameterInitializer> = {},
+ EventCallback = nullptr);
+
+ ~Event();
+
+ auto operator[](const QString& key) const -> std::optional<ParameterValue>;
+
+ auto operator==(const Event& other) const -> bool;
+
+ auto operator!=(const Event& other) const -> bool;
+
+ auto operator<(const Event& other) const -> bool;
+
+ auto operator<=(const Event& other) const -> bool;
+
+ explicit operator QString() const;
+
+ auto GetIdentifier() -> EventIdentifier;
+
+ void AddParameter(const QString& key, const ParameterValue& value);
+
+ void ExecuteCallback(ListenerIdentifier, DataObjectPtr);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename... Args>
+auto MakeEvent(const EventIdentifier& event_id, Args&&... args,
+ Event::EventCallback e_cb) -> EventRefrernce {
+ std::initializer_list<Event::ParameterInitializer> params = {
+ Event::ParameterInitializer{std::forward<Args>(args)}...};
+ return GpgFrontend::SecureCreateSharedObject<Event>(event_id, params, e_cb);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp
new file mode 100644
index 00000000..9bc4f06b
--- /dev/null
+++ b/src/core/module/GlobalModuleContext.cpp
@@ -0,0 +1,377 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GlobalModuleContext.h"
+
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "core/module/Event.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
+#include "model/DataObject.h"
+#include "thread/TaskRunnerGetter.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalModuleContext::Impl {
+ public:
+ explicit Impl() {
+ // Initialize acquired channels with default values.
+ acquired_channel_.insert(kGpgFrontendDefaultChannel);
+ acquired_channel_.insert(kGpgFrontendNonAsciiChannel);
+ }
+
+ auto GetChannel(ModuleRawPtr module) -> int {
+ // Search for the module in the register table.
+ auto module_info_opt =
+ search_module_register_table(module->GetModuleIdentifier());
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR(
+ "cannot find module id {} at register table, fallbacking to "
+ "default "
+ "channel",
+ module->GetModuleIdentifier());
+ return GetDefaultChannel(module);
+ }
+
+ auto module_info = module_info_opt.value();
+ return module_info->channel;
+ }
+
+ static auto GetDefaultChannel(ModuleRawPtr) -> int {
+ return kGpgFrontendDefaultChannel;
+ }
+
+ auto GetTaskRunner(ModuleRawPtr /*module*/) -> std::optional<TaskRunnerPtr> {
+ return Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_Module);
+ }
+
+ auto GetTaskRunner(ModuleIdentifier /*module_id*/)
+ -> std::optional<TaskRunnerPtr> {
+ return Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_Module);
+ }
+
+ auto GetGlobalTaskRunner() -> std::optional<TaskRunnerPtr> {
+ return default_task_runner_;
+ }
+
+ auto RegisterModule(const ModulePtr& module) -> bool {
+ GF_CORE_LOG_DEBUG("attempting to register module: {}",
+ module->GetModuleIdentifier());
+ // Check if the module is null or already registered.
+ if (module == nullptr ||
+ module_register_table_.find(module->GetModuleIdentifier()) !=
+ module_register_table_.end()) {
+ GF_CORE_LOG_ERROR(
+ "module is null or have already registered this module");
+ return false;
+ }
+
+ if (!module->Register()) {
+ GF_CORE_LOG_ERROR("register module {} failed",
+ module->GetModuleIdentifier());
+ return false;
+ }
+
+ auto register_info =
+ GpgFrontend::SecureCreateSharedObject<ModuleRegisterInfo>();
+ register_info->module = module;
+ register_info->channel = acquire_new_unique_channel();
+
+ // move module to its task runner' thread
+ register_info->module->setParent(nullptr);
+ register_info->module->moveToThread(
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module)
+ ->GetThread());
+
+ // Register the module with its identifier.
+ module_register_table_[module->GetModuleIdentifier()] = register_info;
+
+ GF_CORE_LOG_DEBUG("successfully registered module: {}",
+ module->GetModuleIdentifier());
+ return true;
+ }
+
+ auto ActiveModule(ModuleIdentifier module_id) -> bool {
+ GF_CORE_LOG_DEBUG("attempting to activate module: {}", module_id);
+
+ // Search for the module in the register table.
+ auto module_info_opt = search_module_register_table(module_id);
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ module_id);
+ return false;
+ }
+
+ auto module_info = module_info_opt.value();
+
+ // try to get module from module info
+ auto module = module_info->module;
+ if (module == nullptr) {
+ GF_CORE_LOG_ERROR(
+ "module id {} at register table is releated to a null module",
+ module_id);
+ return false;
+ }
+
+ // Activate the module if it is not already active.
+ if (!module_info->activate) {
+ module->Active();
+ module_info->activate = true;
+ }
+
+ GF_CORE_LOG_DEBUG("module activation status: {}", module_info->activate);
+ return module_info->activate;
+ }
+
+ auto ListenEvent(ModuleIdentifier module_id, EventIdentifier event) -> bool {
+ GF_CORE_LOG_DEBUG("module: {} is attempting to listen to event {}",
+ module_id, event);
+ // Check if the event exists, if not, create it.
+ auto met_it = module_events_table_.find(event);
+ if (met_it == module_events_table_.end()) {
+ module_events_table_[event] = std::unordered_set<ModuleIdentifier>();
+ met_it = module_events_table_.find(event);
+ GF_CORE_LOG_DEBUG("new event {} of module system created", event);
+ }
+
+ auto& listeners_set = met_it->second;
+ // Add the listener (module) to the event.
+ auto listener_it = listeners_set.find(module_id);
+ if (listener_it == listeners_set.end()) {
+ listeners_set.insert(module_id);
+ }
+ return true;
+ }
+
+ auto DeactivateModule(ModuleIdentifier module_id) -> bool {
+ // Search for the module in the register table.
+ auto module_info_opt = search_module_register_table(module_id);
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ module_id);
+ return false;
+ }
+
+ auto module_info = module_info_opt.value();
+ // Activate the module if it is not already deactive.
+ if (!module_info->activate && module_info->module->Deactive()) {
+ module_info->activate = false;
+ }
+
+ return !module_info->activate;
+ }
+
+ auto TriggerEvent(const EventRefrernce& event) -> bool {
+ auto event_id = event->GetIdentifier();
+ GF_CORE_LOG_DEBUG("attempting to trigger event: {}", event_id);
+
+ // Find the set of listeners associated with the given event in the table
+ auto met_it = module_events_table_.find(event_id);
+ if (met_it == module_events_table_.end()) {
+ // Log a warning if the event is not registered and nobody is listening
+ GF_CORE_LOG_WARN(
+ "event {} is not listening by anyone and not registered as well",
+ event_id);
+ return false;
+ }
+
+ // Retrieve the set of listeners for this event
+ auto& listeners_set = met_it->second;
+
+ // Check if the set of listeners is empty
+ if (listeners_set.empty()) {
+ // Log a warning if nobody is listening to this event
+ GF_CORE_LOG_WARN("event {} is not listening by anyone",
+ event->GetIdentifier());
+ return false;
+ }
+
+ // Log the number of listeners for this event
+ GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}",
+ event->GetIdentifier(), listeners_set.size());
+
+ // Iterate through each listener and execute the corresponding module
+ for (const auto& listener_module_id : listeners_set) {
+ // Search for the module's information in the registration table
+ auto module_info_opt = search_module_register_table(listener_module_id);
+
+ // Log an error if the module is not found in the registration table
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ listener_module_id);
+ continue;
+ }
+
+ // Retrieve the module's information
+ auto module_info = module_info_opt.value();
+ auto module = module_info->module;
+
+ GF_CORE_LOG_DEBUG(
+ "module {} is listening to event {}, activate state: {}",
+ module_info->module->GetModuleIdentifier(), event->GetIdentifier(),
+ module_info->activate);
+
+ // Check if the module is activated
+ if (!module_info->activate) continue;
+
+ Thread::Task::TaskRunnable const exec_runnerable =
+ [module, event](DataObjectPtr) -> int { return module->Exec(event); };
+
+ Thread::Task::TaskCallback const exec_callback =
+ [listener_module_id, event_id](int code, DataObjectPtr) {
+ if (code < 0) {
+ // Log an error if the module execution fails
+ GF_CORE_LOG_ERROR(
+ "module {} execution failed of event {}: exec return code {}",
+ listener_module_id, event_id, code);
+ }
+ };
+
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module)
+ ->PostTask(new Thread::Task(exec_runnerable,
+ QString("event/%1/module/exec/%2")
+ .arg(event_id)
+ .arg(listener_module_id),
+ nullptr, exec_callback));
+ }
+
+ // Return true to indicate successful execution of all modules
+ return true;
+ }
+
+ auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool {
+ auto m = search_module_register_table(m_id);
+ return m.has_value() && m->get()->activate;
+ }
+
+ private:
+ struct ModuleRegisterInfo {
+ int channel;
+ ModulePtr module;
+ bool activate;
+ };
+
+ using ModuleRegisterInfoPtr = std::shared_ptr<ModuleRegisterInfo>;
+
+ std::unordered_map<ModuleIdentifier, ModuleRegisterInfoPtr>
+ module_register_table_;
+ std::map<EventIdentifier, std::unordered_set<ModuleIdentifier>>
+ module_events_table_;
+
+ std::set<int> acquired_channel_;
+ TaskRunnerPtr default_task_runner_;
+
+ auto acquire_new_unique_channel() -> int {
+ int random_channel = QRandomGenerator::global()->bounded(65535);
+ // Ensure the acquired channel is unique.
+ while (acquired_channel_.find(random_channel) != acquired_channel_.end()) {
+ random_channel = QRandomGenerator::global()->bounded(65535);
+ }
+
+ // Add the acquired channel to the set.
+ acquired_channel_.insert(random_channel);
+ return random_channel;
+ }
+
+ // Function to search for a module in the register table.
+ auto search_module_register_table(const ModuleIdentifier& identifier) const
+ -> std::optional<ModuleRegisterInfoPtr> {
+ auto mrt_it = module_register_table_.find(identifier);
+ if (mrt_it == module_register_table_.end()) {
+ return std::nullopt;
+ }
+ return mrt_it->second;
+ }
+};
+
+// Constructor for GlobalModuleContext, takes a TaskRunnerPtr as an argument.
+GlobalModuleContext::GlobalModuleContext()
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+GlobalModuleContext::~GlobalModuleContext() = default;
+
+// Function to get the task runner associated with a module.
+auto GlobalModuleContext::GetTaskRunner(ModuleRawPtr module)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(module);
+}
+
+// Function to get the task runner associated with a module.
+auto GlobalModuleContext::GetTaskRunner(ModuleIdentifier module_id)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(std::move(module_id));
+}
+
+// Function to get the global task runner.
+auto GlobalModuleContext::GetGlobalTaskRunner()
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetGlobalTaskRunner();
+}
+
+auto GlobalModuleContext::RegisterModule(ModulePtr module) -> bool {
+ return p_->RegisterModule(std::move(module));
+}
+
+auto GlobalModuleContext::ActiveModule(ModuleIdentifier module_id) -> bool {
+ return p_->ActiveModule(std::move(module_id));
+}
+
+auto GlobalModuleContext::ListenEvent(ModuleIdentifier module_id,
+ EventIdentifier event) -> bool {
+ return p_->ListenEvent(std::move(module_id), std::move(event));
+}
+
+auto GlobalModuleContext::DeactivateModule(ModuleIdentifier module_id) -> bool {
+ return p_->DeactivateModule(std::move(module_id));
+}
+
+auto GlobalModuleContext::TriggerEvent(EventRefrernce event) -> bool {
+ return p_->TriggerEvent(std::move(event));
+}
+
+auto GlobalModuleContext::GetChannel(ModuleRawPtr module) -> int {
+ return p_->GetChannel(module);
+}
+
+auto GlobalModuleContext::GetDefaultChannel(ModuleRawPtr channel) -> int {
+ return GlobalModuleContext::Impl::GetDefaultChannel(channel);
+}
+
+auto GlobalModuleContext::IsModuleActivated(ModuleIdentifier m_id) -> bool {
+ return p_->IsModuleActivated(std::move(m_id));
+}
+
+} // namespace GpgFrontend::Module
diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h
new file mode 100644
index 00000000..1c971bb5
--- /dev/null
+++ b/src/core/module/GlobalModuleContext.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <optional>
+
+#include "core/module/Event.h"
+#include "core/thread/TaskRunner.h"
+#include "function/SecureMemoryAllocator.h"
+#include "module/GlobalRegisterTable.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalModuleContext;
+class GlobalRegisterTable;
+
+class Module;
+class ModuleManager;
+using ModuleIdentifier = QString;
+using ModulePtr = std::shared_ptr<Module>;
+using ModuleRawPtr = Module*;
+
+using GMCPtr = std::shared_ptr<GlobalModuleContext>;
+using GRTPtr = std::shared_ptr<GlobalRegisterTable>;
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject {
+ Q_OBJECT
+ public:
+ explicit GlobalModuleContext();
+
+ ~GlobalModuleContext() override;
+
+ auto GetChannel(ModuleRawPtr) -> int;
+
+ static auto GetDefaultChannel(ModuleRawPtr) -> int;
+
+ auto GetTaskRunner(ModuleRawPtr) -> std::optional<TaskRunnerPtr>;
+
+ auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
+
+ auto GetGlobalTaskRunner() -> std::optional<TaskRunnerPtr>;
+
+ auto RegisterModule(ModulePtr) -> bool;
+
+ auto ActiveModule(ModuleIdentifier) -> bool;
+
+ auto DeactivateModule(ModuleIdentifier) -> bool;
+
+ auto ListenEvent(ModuleIdentifier, EventIdentifier) -> bool;
+
+ auto TriggerEvent(EventRefrernce) -> bool;
+
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp
new file mode 100644
index 00000000..c16eba37
--- /dev/null
+++ b/src/core/module/GlobalRegisterTable.cpp
@@ -0,0 +1,167 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GlobalRegisterTable.h"
+
+#include <any>
+#include <optional>
+#include <shared_mutex>
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+
+#include "function/SecureMemoryAllocator.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalRegisterTable::Impl {
+ public:
+ struct RTNode {
+ std::optional<std::any> value = std::nullopt;
+ std::unordered_map<QString, SecureUniquePtr<RTNode>> children;
+ int version = 0;
+ const std::type_info* type = nullptr;
+ };
+
+ explicit Impl(GlobalRegisterTable* parent) : parent_(parent) {}
+
+ auto PublishKV(const Namespace& n, const Key& k, std::any v) -> bool {
+ QStringList const segments = k.split('.');
+ int version = 0;
+
+ {
+ std::unique_lock lock(lock_);
+ auto& root_rt_node =
+ global_register_table_.emplace(n, SecureCreateUniqueObject<RTNode>())
+ .first->second;
+
+ RTNode* current = root_rt_node.get();
+ for (const QString& segment : segments) {
+ current = current->children
+ .emplace(segment, SecureCreateUniqueObject<RTNode>())
+ .first->second.get();
+ }
+
+ current->value = v;
+ current->type = &v.type();
+ version = ++current->version;
+ }
+
+ emit parent_->SignalPublish(n, k, version, v);
+ return true;
+ }
+
+ auto LookupKV(const Namespace& n, const Key& k) -> std::optional<std::any> {
+ QStringList const segments = k.split('.');
+
+ std::optional<std::any> rtn = std::nullopt;
+ {
+ std::shared_lock const lock(lock_);
+ auto it = global_register_table_.find(n);
+ if (it == global_register_table_.end()) return std::nullopt;
+
+ RTNode* current = it->second.get();
+ for (const QString& segment : segments) {
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) return std::nullopt;
+ current = it->second.get();
+ }
+ rtn = current->value;
+ }
+ return rtn;
+ }
+
+ auto ListChildKeys(const Namespace& n, const Key& k) -> std::vector<Key> {
+ QStringList const segments = k.split('.');
+
+ std::vector<Key> rtn;
+ {
+ std::shared_lock lock(lock_);
+ auto it = global_register_table_.find(n);
+ if (it == global_register_table_.end()) return {};
+
+ RTNode* current = it->second.get();
+ for (const QString& segment : segments) {
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) return {};
+ current = it->second.get();
+ }
+
+ for (auto& it : current->children) {
+ rtn.emplace_back(it.first);
+ }
+ }
+ return rtn;
+ }
+
+ auto ListenPublish(QObject* o, const Namespace& n, const Key& k, LPCallback c)
+ -> bool {
+ if (o == nullptr) return false;
+ return QObject::connect(parent_, &GlobalRegisterTable::SignalPublish, o,
+ [n, k, c](const Namespace& pn, const Key& pk,
+ int ver, std::any value) {
+ if (pn == n && pk == k) {
+ c(pn, pk, ver, std::move(value));
+ }
+ }) == nullptr;
+ }
+
+ private:
+ using Table = std::map<Namespace, SecureUniquePtr<RTNode>>;
+ std::shared_mutex lock_;
+ GlobalRegisterTable* parent_;
+
+ Table global_register_table_;
+};
+
+GlobalRegisterTable::GlobalRegisterTable()
+ : p_(SecureCreateUniqueObject<Impl>(this)) {}
+
+GlobalRegisterTable::~GlobalRegisterTable() = default;
+
+auto GlobalRegisterTable::PublishKV(Namespace n, Key k, std::any v) -> bool {
+ return p_->PublishKV(n, k, v);
+}
+
+auto GlobalRegisterTable::LookupKV(Namespace n, Key v)
+ -> std::optional<std::any> {
+ return p_->LookupKV(n, v);
+}
+
+auto GlobalRegisterTable::ListenPublish(QObject* o, Namespace n, Key k,
+ LPCallback c) -> bool {
+ return p_->ListenPublish(o, n, k, c);
+}
+
+auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k)
+ -> std::vector<Key> {
+ return p_->ListChildKeys(n, k);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalRegisterTable.h b/src/core/module/GlobalRegisterTable.h
new file mode 100644
index 00000000..db68c888
--- /dev/null
+++ b/src/core/module/GlobalRegisterTable.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <functional>
+#include <optional>
+
+#include "function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend::Module {
+
+using Namespace = QString;
+using Key = QString;
+using LPCallback = std::function<void(Namespace, Key, int, std::any)>;
+
+class GlobalRegisterTable : public QObject {
+ Q_OBJECT
+ public:
+ GlobalRegisterTable();
+
+ ~GlobalRegisterTable() override;
+
+ auto PublishKV(Namespace, Key, std::any) -> bool;
+
+ auto LookupKV(Namespace, Key) -> std::optional<std::any>;
+
+ auto ListenPublish(QObject *, Namespace, Key, LPCallback) -> bool;
+
+ auto ListChildKeys(Namespace n, Key k) -> std::vector<Key>;
+
+ signals:
+ void SignalPublish(Namespace, Key, int, std::any);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GpgFrontendModuleSystem.h b/src/core/module/GpgFrontendModuleSystem.h
new file mode 100644
index 00000000..903aec69
--- /dev/null
+++ b/src/core/module/GpgFrontendModuleSystem.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <core/GpgFrontendCore.h>
+#include <core/module/Event.h>
+#include <core/module/Module.h>
+#include <core/module/ModuleManager.h> \ No newline at end of file
diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp
new file mode 100644
index 00000000..9076dc2c
--- /dev/null
+++ b/src/core/module/Module.cpp
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "Module.h"
+
+#include "core/module/GlobalModuleContext.h"
+
+namespace GpgFrontend::Module {
+
+class Module::Impl {
+ public:
+ friend class GlobalModuleContext;
+
+ using ExecCallback = std::function<void(int)>;
+
+ Impl(ModuleRawPtr m_ptr, ModuleIdentifier id, ModuleVersion version,
+ ModuleMetaData meta_data)
+ : m_ptr_(m_ptr),
+ identifier_(std::move(id)),
+ version_(std::move(version)),
+ meta_data_(std::move(meta_data)) {}
+
+ auto GetChannel() -> int { return get_gpc()->GetChannel(m_ptr_); }
+
+ auto GetDefaultChannel() -> int {
+ return GlobalModuleContext::GetDefaultChannel(m_ptr_);
+ }
+
+ auto GetTaskRunner() -> std::optional<TaskRunnerPtr> {
+ return get_gpc()->GetTaskRunner(m_ptr_);
+ }
+
+ auto ListenEvent(EventIdentifier event) -> bool {
+ return get_gpc()->ListenEvent(GetModuleIdentifier(), std::move(event));
+ }
+
+ [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier {
+ return identifier_;
+ }
+
+ void SetGPC(GlobalModuleContext* gpc) { gpc_ = gpc; }
+
+ private:
+ GlobalModuleContext* gpc_{};
+ Module* m_ptr_;
+ const ModuleIdentifier identifier_;
+ const ModuleVersion version_;
+ const ModuleMetaData meta_data_;
+
+ auto get_gpc() -> GlobalModuleContext* {
+ if (gpc_ == nullptr) {
+ throw std::runtime_error("module is not registered by module manager");
+ }
+ return gpc_;
+ }
+};
+
+Module::Module(ModuleIdentifier id, ModuleVersion version,
+ const ModuleMetaData& meta_data)
+ : p_(SecureCreateUniqueObject<Impl>(this, id, version, meta_data)) {}
+
+Module::~Module() = default;
+
+auto Module::getChannel() -> int { return p_->GetChannel(); }
+
+auto Module::getDefaultChannel() -> int { return p_->GetDefaultChannel(); }
+
+auto Module::getTaskRunner() -> TaskRunnerPtr {
+ return p_->GetTaskRunner().value_or(nullptr);
+}
+
+auto Module::listenEvent(EventIdentifier event) -> bool {
+ return p_->ListenEvent(std::move(event));
+}
+
+auto Module::GetModuleIdentifier() const -> ModuleIdentifier {
+ return p_->GetModuleIdentifier();
+}
+
+void Module::SetGPC(GlobalModuleContext* gpc) { p_->SetGPC(gpc); }
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/Module.h b/src/core/module/Module.h
new file mode 100644
index 00000000..2a5b54e7
--- /dev/null
+++ b/src/core/module/Module.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/module/Event.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Module {
+
+class Module;
+class GlobalModuleContext;
+class ModuleManager;
+
+using ModuleIdentifier = QString;
+using ModuleVersion = QString;
+using ModuleMetaData = std::map<QString, QString>;
+using ModulePtr = std::shared_ptr<Module>;
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class GPGFRONTEND_CORE_EXPORT Module : public QObject {
+ Q_OBJECT
+ public:
+ Module(ModuleIdentifier, ModuleVersion, const ModuleMetaData&);
+
+ ~Module();
+
+ virtual auto Register() -> bool = 0;
+
+ virtual auto Active() -> bool = 0;
+
+ virtual auto Exec(EventRefrernce) -> int = 0;
+
+ virtual auto Deactive() -> bool = 0;
+
+ [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier;
+
+ void SetGPC(GlobalModuleContext*);
+
+ protected:
+ auto getChannel() -> int;
+
+ auto getDefaultChannel() -> int;
+
+ auto getTaskRunner() -> TaskRunnerPtr;
+
+ auto listenEvent(EventIdentifier) -> bool;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp
new file mode 100644
index 00000000..83e7c1ff
--- /dev/null
+++ b/src/core/module/ModuleManager.cpp
@@ -0,0 +1,184 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "ModuleManager.h"
+
+#include <memory>
+
+#include "GpgConstants.h"
+#include "core/module/GlobalModuleContext.h"
+#include "core/module/GlobalRegisterTable.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
+#include "function/SecureMemoryAllocator.h"
+#include "function/basic/GpgFunctionObject.h"
+#include "thread/TaskRunnerGetter.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class ModuleManager::Impl {
+ public:
+ Impl()
+ : gmc_(GpgFrontend::SecureCreateUniqueObject<GlobalModuleContext>()),
+ grt_(GpgFrontend::SecureCreateUniqueObject<GlobalRegisterTable>()) {}
+
+ ~Impl() = default;
+
+ void RegisterModule(const ModulePtr& module) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](GpgFrontend::DataObjectPtr) -> int {
+ module->SetGPC(gmc_.get());
+ gmc_->RegisterModule(module);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ void TriggerEvent(const EventRefrernce& event) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](const GpgFrontend::DataObjectPtr&) -> int {
+ gmc_->TriggerEvent(event);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ void ActiveModule(const ModuleIdentifier& identifier) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](const GpgFrontend::DataObjectPtr&) -> int {
+ gmc_->ActiveModule(identifier);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ auto GetTaskRunner(ModuleIdentifier module_id)
+ -> std::optional<TaskRunnerPtr> {
+ return gmc_->GetTaskRunner(std::move(module_id));
+ }
+
+ auto UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
+ return grt_->PublishKV(n, k, v);
+ }
+
+ auto RetrieveRTValue(Namespace n, Key k) -> std::optional<std::any> {
+ return grt_->LookupKV(n, k);
+ }
+
+ auto ListenPublish(QObject* o, Namespace n, Key k, LPCallback c) -> bool {
+ return grt_->ListenPublish(o, n, k, c);
+ }
+
+ auto ListRTChildKeys(const QString& n, const QString& k) -> std::vector<Key> {
+ return grt_->ListChildKeys(n, k);
+ }
+
+ auto IsModuleActivated(ModuleIdentifier id) -> bool {
+ return gmc_->IsModuleActivated(id);
+ }
+
+ private:
+ static ModuleMangerPtr global_module_manager;
+ SecureUniquePtr<GlobalModuleContext> gmc_;
+ SecureUniquePtr<GlobalRegisterTable> grt_;
+};
+
+auto IsModuleAcivate(ModuleIdentifier id) -> bool {
+ return ModuleManager::GetInstance().IsModuleActivated(id);
+}
+
+auto UpsertRTValue(const QString& namespace_, const QString& key,
+ const std::any& value) -> bool {
+ return ModuleManager::GetInstance().UpsertRTValue(namespace_, key,
+ std::any(value));
+}
+
+auto ListenRTPublishEvent(QObject* o, Namespace n, Key k, LPCallback c)
+ -> bool {
+ return ModuleManager::GetInstance().ListenRTPublish(o, n, k, c);
+}
+
+auto ListRTChildKeys(const QString& namespace_, const QString& key)
+ -> std::vector<Key> {
+ return ModuleManager::GetInstance().ListRTChildKeys(namespace_, key);
+}
+
+ModuleManager::ModuleManager(int channel)
+ : SingletonFunctionObject<ModuleManager>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+ModuleManager::~ModuleManager() = default;
+
+void ModuleManager::RegisterModule(ModulePtr module) {
+ return p_->RegisterModule(module);
+}
+
+void ModuleManager::TriggerEvent(EventRefrernce event) {
+ return p_->TriggerEvent(event);
+}
+
+void ModuleManager::ActiveModule(ModuleIdentifier id) {
+ return p_->ActiveModule(id);
+}
+
+auto ModuleManager::GetTaskRunner(ModuleIdentifier id)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(std::move(id));
+}
+
+auto ModuleManager::UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
+ return p_->UpsertRTValue(n, k, v);
+}
+
+auto ModuleManager::RetrieveRTValue(Namespace n, Key k)
+ -> std::optional<std::any> {
+ return p_->RetrieveRTValue(n, k);
+}
+
+auto ModuleManager::ListenRTPublish(QObject* o, Namespace n, Key k,
+ LPCallback c) -> bool {
+ return p_->ListenPublish(o, n, k, c);
+}
+
+auto ModuleManager::ListRTChildKeys(const QString& n, const QString& k)
+ -> std::vector<Key> {
+ return p_->ListRTChildKeys(n, k);
+}
+
+auto ModuleManager::IsModuleActivated(ModuleIdentifier id) -> bool {
+ return p_->IsModuleActivated(id);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h
new file mode 100644
index 00000000..93b89e95
--- /dev/null
+++ b/src/core/module/ModuleManager.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <mutex>
+#include <vector>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/module/Event.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend::Thread {
+class TaskRunner;
+}
+
+namespace GpgFrontend::Module {
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class Event;
+class Module;
+class GlobalModuleContext;
+class ModuleManager;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using ModuleIdentifier = QString;
+using ModulePtr = std::shared_ptr<Module>;
+using ModuleMangerPtr = std::shared_ptr<ModuleManager>;
+using GMCPtr = std::shared_ptr<GlobalModuleContext>;
+using Namespace = QString;
+using Key = QString;
+using LPCallback = std::function<void(Namespace, Key, int, std::any)>;
+
+class GPGFRONTEND_CORE_EXPORT ModuleManager
+ : public SingletonFunctionObject<ModuleManager> {
+ public:
+ explicit ModuleManager(int channel);
+
+ virtual ~ModuleManager() override;
+
+ void RegisterModule(ModulePtr);
+
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
+
+ void TriggerEvent(EventRefrernce);
+
+ void ActiveModule(ModuleIdentifier);
+
+ void DeactiveModule(ModuleIdentifier);
+
+ auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
+
+ auto UpsertRTValue(Namespace, Key, std::any) -> bool;
+
+ auto RetrieveRTValue(Namespace, Key) -> std::optional<std::any>;
+
+ auto ListenRTPublish(QObject*, Namespace, Key, LPCallback) -> bool;
+
+ auto ListRTChildKeys(const QString&, const QString&) -> std::vector<Key>;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename T, typename... Args>
+void RegisterModule(Args&&... args) {
+ ModuleManager::GetInstance().RegisterModule(
+ GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...));
+}
+
+template <typename T, typename... Args>
+void RegisterAndActivateModule(Args&&... args) {
+ auto& manager = ModuleManager::GetInstance();
+ auto module =
+ GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...);
+ manager.RegisterModule(module);
+ manager.ActiveModule(module->GetModuleIdentifier());
+}
+
+template <typename... Args>
+void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
+ Event::EventCallback e_cb = nullptr) {
+ ModuleManager::GetInstance().TriggerEvent(
+ std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT IsModuleAcivate(ModuleIdentifier) -> bool;
+
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @param value
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT UpsertRTValue(const QString& namespace_,
+ const QString& key,
+ const std::any& value) -> bool;
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
+ LPCallback) -> bool;
+
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @return std::vector<Key>
+ */
+auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const QString& namespace_,
+ const QString& key)
+ -> std::vector<Key>;
+
+template <typename T>
+auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
+ -> std::optional<T> {
+ auto any_value =
+ ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
+ if (any_value && any_value->type() == typeid(T)) {
+ return std::any_cast<T>(*any_value);
+ }
+ return std::nullopt;
+}
+
+template <typename T>
+auto RetrieveRTValueTypedOrDefault(const QString& namespace_,
+ const QString& key, const T& defaultValue)
+ -> T {
+ auto any_value =
+ ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
+ if (any_value && any_value->type() == typeid(T)) {
+ return std::any_cast<T>(*any_value);
+ }
+ return defaultValue;
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/thread/CtxCheckTask.cpp b/src/core/thread/CtxCheckTask.cpp
deleted file mode 100644
index 9735fcaa..00000000
--- a/src/core/thread/CtxCheckTask.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "core/thread/CtxCheckTask.h"
-
-#include "core/GpgContext.h"
-#include "core/GpgCoreInit.h"
-#include "core/common/CoreCommonUtil.h"
-#include "core/function/gpg/GpgKeyGetter.h"
-#include "thread/Task.h"
-
-GpgFrontend::Thread::CtxCheckTask::CtxCheckTask() : Task("ctx_check_task") {
- connect(this, &CtxCheckTask::SignalGnupgNotInstall,
- CoreCommonUtil::GetInstance(),
- &CoreCommonUtil::SignalGnupgNotInstall);
-}
-
-void GpgFrontend::Thread::CtxCheckTask::Run() {
- // Init GpgFrontend Core
- init_gpgfrontend_core();
-
- // Create & Check Gnupg Context Status
- if (!GpgContext::GetInstance().good()) {
- emit SignalGnupgNotInstall();
- }
- // Try flushing key cache
- else
- GpgFrontend::GpgKeyGetter::GetInstance().FlushKeyCache();
-
- SPDLOG_DEBUG("ctx check task runnable done");
-}
diff --git a/src/core/thread/FileReadTask.cpp b/src/core/thread/FileReadTask.cpp
index 73954d28..49a3f540 100644
--- a/src/core/thread/FileReadTask.cpp
+++ b/src/core/thread/FileReadTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,8 +19,10 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
@@ -28,58 +30,52 @@
namespace GpgFrontend::UI {
-FileReadTask::FileReadTask(std::string path) : Task("file_read_task") {
- connect(this, &FileReadTask::SignalFileBytesReadNext, this,
- &FileReadTask::read_bytes);
+constexpr size_t kBufferSize = 8192;
-#ifdef WINDOWS
- std::filesystem::path read_file_path(
- QString::fromStdString(path).toStdU16String());
-#else
- std::filesystem::path read_file_path(
- QString::fromStdString(path).toStdString());
-#endif
- read_file_path_ = read_file_path;
+FileReadTask::FileReadTask(QString path)
+ : Task("file_read_task"), read_file_path_(std::move(path)) {
+ HoldOnLifeCycle(true);
+ connect(this, &FileReadTask::SignalFileBytesReadNext, this,
+ &FileReadTask::slot_read_bytes);
}
-void FileReadTask::Run() {
- SetFinishAfterRun(false);
-
- if (is_regular_file(read_file_path_)) {
- SPDLOG_DEBUG("read open file: {}", read_file_path_.u8string());
+auto FileReadTask::Run() -> int {
+ if (QFileInfo(read_file_path_).isFile()) {
+ GF_CORE_LOG_DEBUG("read open file: {}", read_file_path_);
- target_file_.setFileName(
- QString::fromStdString(read_file_path_.u8string()));
+ target_file_.setFileName(read_file_path_);
target_file_.open(QIODevice::ReadOnly);
if (!(target_file_.isOpen() && target_file_.isReadable())) {
- SPDLOG_ERROR("file not open or not readable");
+ GF_CORE_LOG_ERROR("file not open or not readable");
if (target_file_.isOpen()) target_file_.close();
- return;
+ return -1;
}
- SPDLOG_DEBUG("started reading: {}", read_file_path_.u8string());
- read_bytes();
+ GF_CORE_LOG_DEBUG("started reading: {}", read_file_path_);
+ slot_read_bytes();
} else {
emit SignalFileBytesReadEnd();
}
+ return 0;
}
-void FileReadTask::read_bytes() {
+void FileReadTask::slot_read_bytes() {
QByteArray read_buffer;
- if (!target_file_.atEnd() &&
- (read_buffer = target_file_.read(buffer_size_)).size() > 0) {
- SPDLOG_DEBUG("read bytes: {}", read_buffer.size());
+ if (QByteArray read_buffer;
+ !target_file_.atEnd() &&
+ (read_buffer = target_file_.read(kBufferSize)).size() > 0) {
+ GF_CORE_LOG_DEBUG("io thread read bytes: {}", read_buffer.size());
emit SignalFileBytesRead(std::move(read_buffer));
} else {
- SPDLOG_DEBUG("read bytes end");
+ GF_CORE_LOG_DEBUG("io thread read bytes end");
emit SignalFileBytesReadEnd();
// announce finish task
- emit SignalTaskRunnableEnd(0);
+ emit SignalTaskShouldEnd(0);
}
}
FileReadTask::~FileReadTask() {
- SPDLOG_DEBUG("close file: {}", read_file_path_.u8string());
+ GF_CORE_LOG_DEBUG("close file: {}", read_file_path_);
if (target_file_.isOpen()) target_file_.close();
}
diff --git a/src/core/thread/FileReadTask.h b/src/core/thread/FileReadTask.h
index d4e61cbe..22be33ef 100644
--- a/src/core/thread/FileReadTask.h
+++ b/src/core/thread/FileReadTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,13 +19,14 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_FILEREADTHREAD_H
-#define GPGFRONTEND_FILEREADTHREAD_H
+#pragma once
#include "core/GpgFrontendCore.h"
#include "core/thread/Task.h"
@@ -39,11 +40,11 @@ namespace GpgFrontend::UI {
class GPGFRONTEND_CORE_EXPORT FileReadTask : public GpgFrontend::Thread::Task {
Q_OBJECT
public:
- explicit FileReadTask(std::string path);
+ explicit FileReadTask(QString path);
virtual ~FileReadTask() override;
- void Run() override;
+ int Run() override;
signals:
void SignalFileBytesRead(QByteArray bytes);
@@ -51,15 +52,12 @@ class GPGFRONTEND_CORE_EXPORT FileReadTask : public GpgFrontend::Thread::Task {
void SignalFileBytesReadNext();
private:
- std::filesystem::path read_file_path_;
+ QString read_file_path_;
QFile target_file_;
- const size_t buffer_size_ = 4096;
QEventLoop looper;
private slots:
- void read_bytes();
+ void slot_read_bytes();
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_FILEREADTHREAD_H
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 7173b69e..dc0cfe94 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,209 +19,237 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/Task.h"
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_generators.hpp>
-#include <boost/uuid/uuid_io.hpp>
-#include <functional>
-#include <string>
-#include <utility>
+#include <qscopedpointer.h>
-#include "core/thread/TaskRunner.h"
+#include "utils/MemoryUtils.h"
-const std::string GpgFrontend::Thread::Task::DEFAULT_TASK_NAME = "default-task";
+namespace GpgFrontend::Thread {
-GpgFrontend::Thread::Task::Task(std::string name)
- : uuid_(generate_uuid()), name_(name) {
- SPDLOG_TRACE("task {}/ created", GetFullID());
- init();
-}
+class Task::Impl {
+ public:
+ Impl(Task *parent, QString name)
+ : parent_(parent), uuid_(generate_uuid()), name_(std::move(name)) {
+ GF_CORE_LOG_TRACE("task {} created", GetFullID());
+ init();
+ }
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
- DataObjectPtr data_object, bool sequency)
- : uuid_(generate_uuid()),
- name_(name),
- runnable_(std::move(runnable)),
- callback_(std::move([](int, const std::shared_ptr<DataObject> &) {})),
- callback_thread_(QThread::currentThread()),
- data_object_(data_object),
- sequency_(sequency) {
- SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
- init();
-}
+ Impl(Task *parent, TaskRunnable runnable, QString name,
+ DataObjectPtr data_object)
+ : parent_(parent),
+ uuid_(generate_uuid()),
+ name_(std::move(name)),
+ runnable_(std::move(runnable)),
+ callback_([](int, const DataObjectPtr &) {}),
+ callback_thread_(QThread::currentThread()),
+ data_object_(std::move(data_object)) {
+ GF_CORE_LOG_TRACE("task {} created with runnable, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
+ init();
+ }
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
- DataObjectPtr data_object,
- TaskCallback callback, bool sequency)
- : uuid_(generate_uuid()),
- name_(name),
- runnable_(std::move(runnable)),
- callback_(std::move(callback)),
- callback_thread_(QThread::currentThread()),
- data_object_(data_object),
- sequency_(sequency) {
- init();
- SPDLOG_TRACE(
- "task {} created with runnable and callback, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
-}
+ Impl(Task *parent, TaskRunnable runnable, QString name,
+ DataObjectPtr data_object, TaskCallback callback)
+ : parent_(parent),
+ uuid_(generate_uuid()),
+ name_(std::move(name)),
+ runnable_(std::move(runnable)),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()),
+ data_object_(std::move(data_object)) {
+ GF_CORE_LOG_TRACE(
+ "task {} created with runnable and callback, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
+ init();
+ }
-GpgFrontend::Thread::Task::~Task() {
- SPDLOG_TRACE("task {} destroyed", GetFullID());
-}
+ ~Impl() { GF_CORE_LOG_TRACE("task {} destroyed", GetFullID()); }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetFullID() const -> QString {
+ return uuid_ + "/" + name_;
+ }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetUUID() const -> QString { return uuid_; }
+
+ /**
+ * @brief
+ *
+ * @return int
+ */
+ auto Run() -> int {
+ GF_CORE_LOG_TRACE("task {} is in classical runnable and callback mode",
+ GetFullID());
+
+ if (runnable_) return runnable_(data_object_);
+
+ GF_CORE_LOG_WARN("no runnable in task, do callback operation, task: {}",
+ GetFullID());
+ return 0;
+ }
+
+ /**
+ * @brief Set the Finish After Run object
+ *
+ * @param finish_after_run
+ */
+ void HoldOnLifeCycle(bool hold_on) { parent_->setAutoDelete(!hold_on); }
+
+ /**
+ * @brief
+ *
+ * @param rtn
+ */
+ void SetRTN(int rtn) { this->rtn_ = rtn; }
+
+ /**
+ * @brief
+ *
+ * @return auto
+ */
+ [[nodiscard]] auto GetRTN() const { return this->rtn_; }
+
+ private:
+ Task *const parent_;
+ const QString uuid_;
+ const QString name_;
+ TaskRunnable runnable_; ///<
+ TaskCallback callback_; ///<
+ int rtn_ = -99; ///<
+ QThread *callback_thread_ = nullptr; ///<
+ DataObjectPtr data_object_ = nullptr; ///<
+
+ void init() {
+ GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_,
+ static_cast<void *>(parent_), static_cast<void *>(this));
+
+ //
+ HoldOnLifeCycle(false);
+
+ //
+ connect(parent_, &Task::SignalRun, parent_, &Task::slot_exception_safe_run);
+
+ auto *callback_thread = callback_thread_ != nullptr
+ ? callback_thread_
+ : QCoreApplication::instance()->thread();
+ //
+ connect(parent_, &Task::SignalTaskShouldEnd, callback_thread,
+ [this](int rtn) {
+ // set task returning code
+ SetRTN(rtn);
+ try {
+ if (callback_) {
+ GF_CORE_LOG_TRACE(
+ "task callback {} is starting with runnerable rtn: {}",
+ GetFullID(), rtn);
+
+ callback_(rtn_, data_object_);
+ GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}",
+ GetFullID(), rtn);
+ }
+ } catch (...) {
+ GF_CORE_LOG_ERROR("task {} callback caught exception, rtn: {}",
+ GetFullID(), rtn);
+ }
+ emit parent_->SignalTaskEnd();
+ });
+
+ //
+ connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater);
+ }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ static auto generate_uuid() -> QString {
+ return QUuid::createUuid().toString();
+ }
+};
+
+Task::Task(QString name) : p_(new Impl(this, name)) {}
+
+Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object)
+ : p_(SecureCreateUniqueObject<Impl>(this, runnable, name, data_object)) {}
+
+Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object,
+ TaskCallback callback)
+ : p_(SecureCreateUniqueObject<Impl>(this, runnable, name, data_object,
+ callback)) {}
+
+Task::~Task() = default;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::Thread::Task::GetFullID() const {
- return uuid_ + "/" + name_;
-}
-
-std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; }
+QString Task::GetFullID() const { return p_->GetFullID(); }
-bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; }
+QString Task::GetUUID() const { return p_->GetUUID(); }
-void GpgFrontend::Thread::Task::SetFinishAfterRun(
- bool run_callback_after_runnable_finished) {
- this->run_callback_after_runnable_finished_ =
- run_callback_after_runnable_finished;
-}
+void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); }
-void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; }
-
-void GpgFrontend::Thread::Task::init() {
- // after runnable finished, running callback
- connect(this, &Task::SignalTaskRunnableEnd, this,
- &Task::slot_task_run_callback);
-}
+void Task::setRTN(int rtn) { p_->SetRTN(rtn); }
-void GpgFrontend::Thread::Task::slot_task_run_callback(int rtn) {
- SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn);
- // set return value
- this->SetRTN(rtn);
+void Task::SafelyRun() { emit SignalRun(); }
- try {
- if (callback_) {
- if (callback_thread_ == QThread::currentThread()) {
- SPDLOG_DEBUG("callback thread is the same thread");
- if (!QMetaObject::invokeMethod(callback_thread_,
- [callback = callback_, rtn = rtn_,
- data_object = data_object_, this]() {
- callback(rtn, data_object);
- // do cleaning work
- emit SignalTaskEnd();
- })) {
- SPDLOG_ERROR("failed to invoke callback");
- }
- // just finished, let callack thread to raise SignalTaskEnd
- return;
- } else {
- // waiting for callback to finish
- if (!QMetaObject::invokeMethod(
- callback_thread_,
- [callback = callback_, rtn = rtn_,
- data_object = data_object_]() { callback(rtn, data_object); },
- Qt::BlockingQueuedConnection)) {
- SPDLOG_ERROR("failed to invoke callback");
- }
- }
- }
- } catch (std::exception &e) {
- SPDLOG_ERROR("exception caught: {}", e.what());
- } catch (...) {
- SPDLOG_ERROR("unknown exception caught");
- }
+int Task::Run() { return p_->Run(); }
- // raise signal, announcing this task come to an end
- SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID());
- emit SignalTaskEnd();
+void Task::run() {
+ GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}",
+ GetFullID(), QThread::currentThread()->currentThreadId());
+ this->SafelyRun();
}
-void GpgFrontend::Thread::Task::run() {
- SPDLOG_TRACE("task {} starting", GetFullID());
+Task::TaskHandler::TaskHandler(Task *task) : task_(task) {}
- // build runnable package for running
- auto runnable_package = [=, id = GetFullID()]() {
- SPDLOG_DEBUG("task {} runnable start runing", id);
- // Run() will set rtn by itself
- Run();
- // raise signal to anounce after runnable returned
- if (run_callback_after_runnable_finished_) emit SignalTaskRunnableEnd(rtn_);
- };
-
- if (thread() != QThread::currentThread()) {
- SPDLOG_DEBUG("task running thread is not object living thread");
- // if running sequently
- if (sequency_) {
- // running in another thread, blocking until returned
- if (!QMetaObject::invokeMethod(thread(), runnable_package,
- Qt::BlockingQueuedConnection)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- } else {
- // running in another thread, non-blocking
- if (!QMetaObject::invokeMethod(thread(), runnable_package)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- }
- } else {
- if (!QMetaObject::invokeMethod(this, runnable_package)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- }
+void Task::TaskHandler::Start() {
+ if (task_ != nullptr) task_->SafelyRun();
}
-void GpgFrontend::Thread::Task::SlotRun() { run(); }
-
-void GpgFrontend::Thread::Task::Run() {
- if (runnable_) {
- SetRTN(runnable_(data_object_));
- } else {
- SPDLOG_WARN("no runnable in task, do callback operation");
- }
+void Task::TaskHandler::Cancel() {
+ if (task_ != nullptr) emit task_->SignalTaskEnd();
}
-GpgFrontend::Thread::Task::DataObject::Destructor *
-GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) {
- Destructor *dstr_ptr = new Destructor();
- dstr_ptr->p_obj = malloc(bytes_size);
- return dstr_ptr;
+auto Task::TaskHandler::GetTask() -> Task * {
+ if (task_ != nullptr) return task_;
+ return nullptr;
}
-GpgFrontend::Thread::Task::DataObject::~DataObject() {
- if (!data_objects_.empty())
- SPDLOG_WARN("data_objects_ is not empty",
- "address:", static_cast<void *>(this));
- while (!data_objects_.empty()) {
- free_heap_ptr(data_objects_.top());
- data_objects_.pop();
- }
-}
+void Task::slot_exception_safe_run() noexcept {
+ auto rtn = p_->GetRTN();
+ try {
+ GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID());
-size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() {
- return data_objects_.size();
-}
+ // Run() will set rtn by itself
+ rtn = this->Run();
-void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) {
- SPDLOG_TRACE("p_obj: {} data object: {}",
- static_cast<const void *>(ptr->p_obj),
- static_cast<void *>(this));
- if (ptr->destroy != nullptr) {
- ptr->destroy(ptr->p_obj);
+ GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID());
+ } catch (...) {
+ GF_CORE_LOG_ERROR("exception was caught at task: {}", GetFullID());
}
- free(const_cast<void *>(ptr->p_obj));
- delete ptr;
-}
-std::string GpgFrontend::Thread::Task::generate_uuid() {
- return boost::uuids::to_string(boost::uuids::random_generator()());
+ // raise signal to anounce after runnable returned
+ if (this->autoDelete()) emit this->SignalTaskShouldEnd(rtn);
}
+auto Task::GetRTN() { return p_->GetRTN(); }
+} // namespace GpgFrontend::Thread \ No newline at end of file
diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h
index ce354697..97a14949 100644
--- a/src/core/thread/Task.h
+++ b/src/core/thread/Task.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,17 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASK_H
-#define GPGFRONTEND_TASK_H
-
-#include <functional>
-#include <memory>
-#include <stack>
-#include <string>
-#include <type_traits>
-#include <utility>
+#pragma once
#include "core/GpgFrontendCore.h"
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/model/DataObject.h"
namespace GpgFrontend::Thread {
@@ -45,253 +39,136 @@ class TaskRunner;
class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
Q_OBJECT
public:
- class DataObject;
- using DataObjectPtr = std::shared_ptr<DataObject>; ///<
+ friend class TaskRunner;
+
using TaskRunnable = std::function<int(DataObjectPtr)>; ///<
using TaskCallback = std::function<void(int, DataObjectPtr)>; ///<
- static const std::string DEFAULT_TASK_NAME;
-
- friend class TaskRunner;
-
- /**
- * @brief DataObject to be passed to the callback function.
- *
- */
- class GPGFRONTEND_CORE_EXPORT DataObject {
+ class TaskHandler {
public:
- struct Destructor {
- const void *p_obj;
- void (*destroy)(const void *);
- };
-
- /**
- * @brief Get the Objects Size
- *
- * @return size_t
- */
- size_t GetObjectSize();
-
- /**
- * @brief
- *
- * @tparam T
- * @param ptr
- */
- template <typename T>
- void AppendObject(T &&obj) {
- SPDLOG_TRACE("append object: {}", static_cast<void *>(this));
- auto *obj_dstr = this->get_heap_ptr(sizeof(T));
- new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj));
+ explicit TaskHandler(Task*);
- if (std::is_class_v<T>) {
- auto destructor = [](const void *x) {
- static_cast<const T *>(x)->~T();
- };
- obj_dstr->destroy = destructor;
- } else {
- obj_dstr->destroy = nullptr;
- }
+ void Start();
- data_objects_.push(obj_dstr);
- }
+ void Cancel();
- /**
- * @brief
- *
- * @tparam T
- * @param ptr
- */
- template <typename T>
- void AppendObject(T *obj) {
- SPDLOG_TRACE("called: {}", static_cast<void *>(this));
- auto *obj_dstr = this->get_heap_ptr(sizeof(T));
- auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
- if (std::is_class_v<T>) {
- SPDLOG_TRACE("is class");
- auto destructor = [](const void *x) {
- static_cast<const T *>(x)->~T();
- };
- obj_dstr->destroy = destructor;
- } else {
- obj_dstr->destroy = nullptr;
- }
- data_objects_.push(std::move(obj_dstr));
- }
-
- /**
- * @brief
- *
- * @tparam T
- * @return std::shared_ptr<T>
- */
- template <typename T>
- T PopObject() {
- SPDLOG_TRACE("pop object: {}", static_cast<void *>(this));
- if (data_objects_.empty()) throw std::runtime_error("No object to pop");
- auto *obj_dstr = data_objects_.top();
- auto *heap_ptr = (T *)obj_dstr->p_obj;
- auto obj = std::move(*(T *)(heap_ptr));
- this->free_heap_ptr(obj_dstr);
- data_objects_.pop();
- return obj;
- }
-
- /**
- * @brief Destroy the Data Object object
- *
- */
- ~DataObject();
+ auto GetTask() -> Task*;
private:
- std::stack<Destructor *> data_objects_; ///<
-
- /**
- * @brief Get the heap ptr object
- *
- * @param bytes_size
- * @return void*
- */
- Destructor *get_heap_ptr(size_t bytes_size);
-
- /**
- * @brief
- *
- * @param heap_ptr
- */
- void free_heap_ptr(Destructor *);
+ QPointer<Task> task_;
};
/**
* @brief Construct a new Task object
*
*/
- Task(std::string name = DEFAULT_TASK_NAME);
+ explicit Task(QString name);
/**
* @brief Construct a new Task object
*
* @param callback The callback function to be executed.
*/
- explicit Task(TaskRunnable runnable, std::string name = DEFAULT_TASK_NAME,
- DataObjectPtr data_object = nullptr, bool sequency = true);
+ explicit Task(TaskRunnable runnable, QString name,
+ DataObjectPtr data_object = nullptr);
/**
* @brief Construct a new Task object
*
* @param runnable
*/
- explicit Task(
- TaskRunnable runnable, std::string name, DataObjectPtr data,
- TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {},
- bool sequency = true);
+ explicit Task(TaskRunnable runnable, QString name, DataObjectPtr data,
+ TaskCallback callback);
/**
* @brief Destroy the Task object
*
*/
- virtual ~Task() override;
+ ~Task() override;
/**
- * @brief Run - run the task
+ * @brief
*
+ * @return QString
*/
- virtual void Run();
+ [[nodiscard]] auto GetUUID() const -> QString;
/**
- * @brief
+ * @brief Get the Full I D object
*
- * @return std::string
+ * @return QString
*/
- std::string GetUUID() const;
+ [[nodiscard]] auto GetFullID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @param hold_on
*/
- std::string GetFullID() const;
+ void HoldOnLifeCycle(bool hold_on);
/**
- * @brief
+ * @brief can be overwrite by subclass
*
- * @return std::string
+ * @return int
*/
- bool GetSequency() const;
-
- public slots:
+ virtual auto Run() -> int;
/**
* @brief
*
+ * @return auto
*/
- void SlotRun();
+ [[nodiscard]] auto GetRTN();
- signals:
- /**
- * @brief announce runnable finished
- *
- */
- void SignalTaskRunnableEnd(int rtn);
+ public slots:
/**
- * @brief runnable and callabck all finished
+ * @brief shouldn't be overwrite by subclass
*
*/
- void SignalTaskEnd();
+ void SafelyRun();
- protected:
- /**
- * @brief Set the Finish After Run object
- *
- * @param finish_after_run
- */
- void SetFinishAfterRun(bool finish_after_run);
+ signals:
/**
* @brief
*
- * @param rtn
*/
- void SetRTN(int rtn);
-
- private:
- const std::string uuid_;
- const std::string name_;
- const bool sequency_ = true; ///< must run in the same thread
- TaskCallback callback_; ///<
- TaskRunnable runnable_; ///<
- bool run_callback_after_runnable_finished_ = true; ///<
- int rtn_ = 0; ///<
- QThread *callback_thread_ = nullptr; ///<
- DataObjectPtr data_object_ = nullptr; ///<
+ void SignalRun();
/**
* @brief
*
*/
- void init();
+ void SignalTaskShouldEnd(int);
/**
* @brief
*
*/
- virtual void run() override;
+ void SignalTaskEnd();
+ protected:
/**
* @brief
*
- * @return std::string
+ * @param rtn
*/
- static std::string generate_uuid();
+ void setRTN(int rtn);
private slots:
+
/**
* @brief
*
*/
- void slot_task_run_callback(int rtn);
+ void slot_exception_safe_run() noexcept;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+
+ void run() override;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASK_H \ No newline at end of file
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index 461d5fb5..8e381384 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,128 +19,132 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/TaskRunner.h"
#include "core/thread/Task.h"
-#include "spdlog/spdlog.h"
-GpgFrontend::Thread::TaskRunner::TaskRunner() = default;
+namespace GpgFrontend::Thread {
+
+class TaskRunner::Impl : public QThread {
+ public:
+ Impl() : QThread(nullptr) {}
-GpgFrontend::Thread::TaskRunner::~TaskRunner() = default;
+ void PostTask(Task* task) {
+ if (task == nullptr) {
+ GF_CORE_LOG_ERROR("task posted is null");
+ return;
+ }
-void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
- if (task == nullptr) {
- SPDLOG_ERROR("task posted is null");
- return;
+ task->setParent(nullptr);
+ task->moveToThread(this);
+
+ GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(),
+ this->currentThreadId());
+ task->SafelyRun();
}
- SPDLOG_TRACE("post task: {}", task->GetFullID());
+ auto RegisterTask(const QString& name, const Task::TaskRunnable& runnerable,
+ const Task::TaskCallback& cb, DataObjectPtr params)
+ -> Task::TaskHandler {
+ auto* raw_task = new Task(runnerable, name, std::move(params), cb);
+ raw_task->setParent(nullptr);
+ raw_task->moveToThread(this);
+
+ connect(raw_task, &Task::SignalRun, this, [this, raw_task]() {
+ pending_tasks_[raw_task->GetFullID()] = raw_task;
+ });
- task->setParent(nullptr);
- task->moveToThread(this);
+ connect(raw_task, &Task::SignalTaskEnd, this, [this, raw_task]() {
+ pending_tasks_.remove(raw_task->GetFullID());
+ });
- {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- tasks.push(task);
+ GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}",
+ raw_task->GetFullID(), this->currentThreadId());
+
+ return Task::TaskHandler(raw_task);
}
- quit();
-}
-void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task,
- size_t seconds) {
- if (task == nullptr) return;
- // TODO
-}
+ void PostTask(const QString& name, const Task::TaskRunnable& runnerable,
+ const Task::TaskCallback& cb, DataObjectPtr params) {
+ PostTask(new Task(runnerable, name, std::move(params), cb));
+ }
-[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() {
- SPDLOG_TRACE("task runner runing, thread id: {}", QThread::currentThreadId());
- while (true) {
- if (tasks.empty()) {
- SPDLOG_TRACE("no tasks to run, trapping into event loop...");
- exec();
- } else {
- SPDLOG_TRACE("start to run task(s), queue size: {}", tasks.size());
-
- Task* task = nullptr;
- {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- task = std::move(tasks.front());
- tasks.pop();
- pending_tasks_.insert({task->GetUUID(), task});
- }
-
- if (task != nullptr) {
- try {
- // triger
- SPDLOG_TRACE("running task {}, sequency: {}", task->GetFullID(),
- task->GetSequency());
-
- // when a signal SignalTaskEnd raise, do unregister work
- connect(task, &Task::SignalTaskEnd, this, [this, task]() {
- unregister_finished_task(task->GetUUID());
- });
-
- if (!task->GetSequency()) {
- // if it need to run concurrently, we should create a new thread to
- // run it.
- auto* concurrent_thread = new QThread(nullptr);
- task->setParent(nullptr);
- task->moveToThread(concurrent_thread);
- // start thread
- concurrent_thread->start();
-
- connect(task, &Task::SignalTaskEnd, concurrent_thread,
- &QThread::quit);
- // concurrent thread is responsible for deleting the task
- connect(concurrent_thread, &QThread::finished, task,
- &Task::deleteLater);
- }
-
- // run the task
- task->run();
- } catch (const std::exception& e) {
- SPDLOG_ERROR("task runner: exception in task {}, exception: {}",
- task->GetFullID(), e.what());
- // if any exception caught, destroy the task, remove the task from the
- // pending tasks
- unregister_finished_task(task->GetUUID());
- } catch (...) {
- SPDLOG_ERROR("task runner: unknown exception in task: {}",
- task->GetFullID());
- // if any exception caught, destroy the task, remove the task from the
- // pending tasks
- unregister_finished_task(task->GetUUID());
- }
- }
+ void PostConcurrentTask(Task* task) {
+ if (task == nullptr) {
+ GF_CORE_LOG_ERROR("task posted is null");
+ return;
}
+
+ auto* concurrent_thread = new QThread(this);
+
+ task->setParent(nullptr);
+ task->moveToThread(concurrent_thread);
+
+ connect(task, &Task::SignalTaskEnd, concurrent_thread, &QThread::quit);
+ connect(concurrent_thread, &QThread::finished, concurrent_thread,
+ &QThread::deleteLater);
+
+ concurrent_thread->start();
+
+ GF_CORE_LOG_TRACE("runner starts task concurrenctly: {}",
+ task->GetFullID());
+ task->SafelyRun();
}
-}
-/**
- * @brief
- *
- */
-void GpgFrontend::Thread::TaskRunner::unregister_finished_task(
- std::string task_uuid) {
- SPDLOG_DEBUG("cleaning task {}", task_uuid);
- // search in map
- auto pending_task = pending_tasks_.find(task_uuid);
- if (pending_task == pending_tasks_.end()) {
- SPDLOG_ERROR("cannot find task in pending list: {}", task_uuid);
- return;
- } else {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- // if thread runs sequenctly, that means the thread is living in this
- // thread, so we can delete it. Or, its living thread need to delete it.
- if (pending_task->second->GetSequency())
- pending_task->second->deleteLater();
- pending_tasks_.erase(pending_task);
+ void PostScheduleTask(Task* task, size_t seconds) {
+ if (task == nullptr) return;
+ // TODO
}
- SPDLOG_DEBUG("clean task {} done", task_uuid);
+ private:
+ QMap<QString, Task*> pending_tasks_;
+};
+
+TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject<Impl>()) {}
+
+TaskRunner::~TaskRunner() {
+ if (p_->isRunning()) {
+ Stop();
+ }
+}
+
+void TaskRunner::PostTask(Task* task) { p_->PostTask(task); }
+
+void TaskRunner::PostTask(const QString& name, const Task::TaskRunnable& runner,
+ const Task::TaskCallback& cb, DataObjectPtr params) {
+ p_->PostTask(name, runner, cb, std::move(params));
+}
+
+void TaskRunner::PostConcurrentTask(Task* task) {
+ p_->PostConcurrentTask(task);
+}
+
+void TaskRunner::PostScheduleTask(Task* task, size_t seconds) {
+ p_->PostScheduleTask(task, seconds);
+}
+
+void TaskRunner::Start() { p_->start(); }
+
+void TaskRunner::Stop() {
+ p_->quit();
+ p_->wait();
+}
+
+auto TaskRunner::GetThread() -> QThread* { return p_.get(); }
+
+auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); }
+
+auto TaskRunner::RegisterTask(const QString& name,
+ const Task::TaskRunnable& runnable,
+ const Task::TaskCallback& cb, DataObjectPtr p_pbj)
+ -> Task::TaskHandler {
+ return p_->RegisterTask(name, runnable, cb, p_pbj);
}
+} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h
index 35cd1a30..8a93ad0b 100644
--- a/src/core/thread/TaskRunner.h
+++ b/src/core/thread/TaskRunner.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,25 +19,22 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASKRUNNER_H
-#define GPGFRONTEND_TASKRUNNER_H
-
-#include <cstddef>
-#include <mutex>
-#include <queue>
+#pragma once
#include "core/GpgFrontendCore.h"
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/thread/Task.h"
namespace GpgFrontend::Thread {
-class Task;
-
-class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
+class GPGFRONTEND_CORE_EXPORT TaskRunner : public QObject {
Q_OBJECT
public:
/**
@@ -50,13 +47,34 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
* @brief Destroy the Task Runner object
*
*/
- virtual ~TaskRunner() override;
+ ~TaskRunner() override;
+
+ /**
+ * @brief
+ *
+ */
+ void Start();
/**
* @brief
*
*/
- [[noreturn]] void run() override;
+ void Stop();
+
+ /**
+ * @brief Get the Thread object
+ *
+ * @return QThread*
+ */
+ auto GetThread() -> QThread*;
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto IsRunning() -> bool;
public slots:
@@ -70,23 +88,38 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
/**
* @brief
*
- * @param task
- * @param seconds
+ * @param runner
+ * @param cb
*/
- void PostScheduleTask(Task* task, size_t seconds);
+ void PostTask(const QString&, const Task::TaskRunnable&,
+ const Task::TaskCallback&, DataObjectPtr);
- private:
- std::queue<Task*> tasks; ///< The task queue
- std::map<std::string, Task*> pending_tasks_; ///< The pending tasks
- std::mutex tasks_mutex_; ///< The task queue mutex
- QThreadPool thread_pool_{this}; ///< run non-sequency task
+ /**
+ * @brief
+ *
+ * @return std::tuple<QPointer<Task>, TaskTrigger>
+ */
+ auto RegisterTask(const QString&, const Task::TaskRunnable&,
+ const Task::TaskCallback&, DataObjectPtr)
+ -> Task::TaskHandler;
+
+ /**
+ * @brief
+ *
+ * @param task
+ */
+ void PostConcurrentTask(Task* task);
/**
* @brief
*
+ * @param task
+ * @param seconds
*/
- void unregister_finished_task(std::string);
+ void PostScheduleTask(Task* task, size_t seconds);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASKRUNNER_H \ No newline at end of file
diff --git a/src/core/thread/TaskRunnerGetter.cpp b/src/core/thread/TaskRunnerGetter.cpp
index 186483ec..bdcd89d0 100644
--- a/src/core/thread/TaskRunnerGetter.cpp
+++ b/src/core/thread/TaskRunnerGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,28 +19,46 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::Thread::TaskRunnerGetter::TaskRunnerGetter(int channel)
- : SingletonFunctionObject<TaskRunnerGetter>(channel) {}
+#include <mutex>
+
+#include "core/GpgConstants.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Thread {
-GpgFrontend::Thread::TaskRunner*
-GpgFrontend::Thread::TaskRunnerGetter::GetTaskRunner(
- TaskRunnerType runner_type) {
+TaskRunnerGetter::TaskRunnerGetter(int)
+ : SingletonFunctionObject<TaskRunnerGetter>(kGpgFrontendDefaultChannel) {}
+
+auto TaskRunnerGetter::GetTaskRunner(TaskRunnerType runner_type)
+ -> TaskRunnerPtr {
+ std::lock_guard<std::mutex> lock_guard(task_runners_map_lock_);
while (true) {
auto it = task_runners_.find(runner_type);
if (it != task_runners_.end()) {
return it->second;
- } else {
- auto runner = new TaskRunner();
- task_runners_[runner_type] = runner;
- runner->start();
- continue;
+ }
+
+ auto runner = GpgFrontend::SecureCreateSharedObject<TaskRunner>();
+ task_runners_[runner_type] = runner;
+ runner->Start();
+ }
+}
+
+void TaskRunnerGetter::StopAllTeakRunner() {
+ for (const auto& [key, value] : task_runners_) {
+ if (value->IsRunning()) {
+ value->Stop();
}
}
}
+
+} // namespace GpgFrontend::Thread \ No newline at end of file
diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h
index 80b25c3e..49ed25c0 100644
--- a/src/core/thread/TaskRunnerGetter.h
+++ b/src/core/thread/TaskRunnerGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,20 +19,25 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASKRUNNERGETTER_H
-#define GPGFRONTEND_TASKRUNNERGETTER_H
+#pragma once
+
+#include <mutex>
#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
#include "core/thread/TaskRunner.h"
namespace GpgFrontend::Thread {
+using TaskRunnerPtr = std::shared_ptr<TaskRunner>;
+
class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
: public GpgFrontend::SingletonFunctionObject<TaskRunnerGetter> {
public:
@@ -41,18 +46,21 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
kTaskRunnerType_GPG,
kTaskRunnerType_IO,
kTaskRunnerType_Network,
+ kTaskRunnerType_Module,
kTaskRunnerType_External_Process,
};
- TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit TaskRunnerGetter(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
- TaskRunner *GetTaskRunner(
- TaskRunnerType runner_type = kTaskRunnerType_Default);
+ auto GetTaskRunner(TaskRunnerType runner_type = kTaskRunnerType_Default)
+ -> TaskRunnerPtr;
+
+ void StopAllTeakRunner();
private:
- std::map<TaskRunnerType, TaskRunner *> task_runners_;
+ std::map<TaskRunnerType, TaskRunnerPtr> task_runners_;
+ std::mutex task_runners_map_lock_;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASKRUNNERGETTER_H \ No newline at end of file
diff --git a/src/core/thread/ThreadingModel.h b/src/core/thread/ThreadingModel.h
index eb6c9039..2fcc11c8 100644
--- a/src/core/thread/ThreadingModel.h
+++ b/src/core/thread/ThreadingModel.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,14 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_THREADINGMODEL_H
-#define GPGFRONTEND_THREADINGMODEL_H
+#pragma once
#include "core/thread/Task.h"
#include "core/thread/TaskRunner.h"
#include "core/thread/TaskRunnerGetter.h"
-
-#endif // GPGFRONTEND_THREADINGMODEL_H \ No newline at end of file
diff --git a/src/core/typedef/CoreTypedef.h b/src/core/typedef/CoreTypedef.h
new file mode 100644
index 00000000..51c6d11a
--- /dev/null
+++ b/src/core/typedef/CoreTypedef.h
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend {
+
+using GFError = uint32_t;
+using ByteArray = QByteArray; ///<
+using ByteArrayPtr = std::shared_ptr<ByteArray>; ///<
+using StdBypeArrayPtr = std::shared_ptr<ByteArray>; ///<
+using BypeArrayRef = ByteArray&; ///<
+using ConstBypeArrayRef = const ByteArray&; ///<
+using BypeArrayConstRef = const ByteArray&; ///<
+using StringArgsPtr = std::unique_ptr<std::vector<QString>>; ///<
+using StringArgsRef = std::vector<QString>&; ///<
+ ///
+ ///
+
+using OperaRunnable = std::function<GFError(DataObjectPtr)>;
+using OperationCallback = std::function<void(GFError, DataObjectPtr)>;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h
new file mode 100644
index 00000000..cf0887bf
--- /dev/null
+++ b/src/core/typedef/GpgTypedef.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <tuple>
+
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend {
+
+class GpgKey; ///< forward declaration
+class GpgSubKey;
+class GpgSignature;
+class GpgTOFUInfo;
+
+using GpgError = gpgme_error_t; ///< gpgme error
+using GpgErrorCode = gpg_err_code_t;
+using GpgErrorDesc = std::pair<QString, QString>;
+
+using KeyId = QString; ///<
+using SubkeyId = QString; ///<
+using KeyIdArgsList = std::vector<KeyId>; ///<
+using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; ///<
+using UIDArgsList = std::vector<QString>; ///<
+using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; ///<
+using SignIdArgsList = std::vector<std::pair<QString, QString>>; ///<
+using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; ///<
+using KeyFprArgsListPtr = std::unique_ptr<std::vector<QString>>; ///<
+using KeyArgsList = std::vector<GpgKey>; ///<
+using KeyListPtr = std::shared_ptr<KeyArgsList>; ///<
+using GpgKeyLinkList = std::list<GpgKey>; ///<
+using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///<
+using KeyPtr = std::unique_ptr<GpgKey>; ///<
+using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///<
+
+using GpgSignMode = gpgme_sig_mode_t;
+
+using GpgOperaRunnable = std::function<GpgError(DataObjectPtr)>;
+using GpgOperationCallback = std::function<void(GpgError, DataObjectPtr)>;
+using GpgOperationFuture = std::future<std::tuple<GpgError, DataObjectPtr>>;
+
+enum GpgOperation {
+ kENCRYPT,
+ kDECRYPT,
+ kSIGN,
+ kVERIFY,
+ kENCRYPT_SIGN,
+ kDECRYPT_VERIFY
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp
new file mode 100644
index 00000000..9ce94247
--- /dev/null
+++ b/src/core/utils/AsyncUtils.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "AsyncUtils.h"
+
+#include "core/module/ModuleManager.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "model/DataObject.h"
+
+namespace GpgFrontend {
+
+auto RunGpgOperaAsync(const GpgOperaRunnable& runnable,
+ const GpgOperationCallback& callback,
+ const QString& operation, const QString& minial_version)
+ -> Thread::Task::TaskHandler {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", minial_version);
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
+ gnupg_version, operation);
+
+ if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) {
+ GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
+ operation, gnupg_version);
+ callback(GPG_ERR_NOT_SUPPORTED, TransferParams());
+ return Thread::Task::TaskHandler(nullptr);
+ }
+
+ auto handler =
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
+ ->RegisterTask(
+ operation,
+ [=](const DataObjectPtr& data_object) -> int {
+ auto custom_data_object = TransferParams();
+ auto err = runnable(custom_data_object);
+ data_object->Swap({err, custom_data_object});
+ return 0;
+ },
+ [=](int rtn, const DataObjectPtr& data_object) {
+ if (rtn < 0) {
+ callback(GPG_ERR_USER_1,
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ } else {
+ callback(ExtractParams<GpgError>(data_object, 0),
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ }
+ },
+ TransferParams());
+ handler.Start();
+ return handler;
+}
+
+auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation,
+ const QString& minial_version)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", minial_version);
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
+ gnupg_version, operation);
+
+ if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) {
+ GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
+ operation, gnupg_version);
+ return {GPG_ERR_NOT_SUPPORTED, TransferParams()};
+ }
+
+ auto data_object = TransferParams();
+ auto err = runnable(data_object);
+ return {err, data_object};
+}
+
+auto RunIOOperaAsync(const OperaRunnable& runnable,
+ const OperationCallback& callback,
+ const QString& operation) -> Thread::Task::TaskHandler {
+ auto handler =
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_IO)
+ ->RegisterTask(
+ operation,
+ [=](const DataObjectPtr& data_object) -> int {
+ auto custom_data_object = TransferParams();
+ GpgError err = runnable(custom_data_object);
+
+ data_object->Swap({err, custom_data_object});
+ return 0;
+ },
+ [=](int rtn, const DataObjectPtr& data_object) {
+ if (rtn < 0) {
+ callback(-1, ExtractParams<DataObjectPtr>(data_object, 1));
+ } else {
+ callback(ExtractParams<GFError>(data_object, 0),
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ }
+ },
+ TransferParams());
+ handler.Start();
+ return handler;
+}
+
+auto RunOperaAsync(const OperaRunnable& runnable,
+ const OperationCallback& callback, const QString& operation)
+ -> Thread::Task::TaskHandler {
+ auto handler =
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->RegisterTask(
+ operation,
+ [=](const DataObjectPtr& data_object) -> int {
+ auto custom_data_object = TransferParams();
+ GpgError err = runnable(custom_data_object);
+
+ data_object->Swap({err, custom_data_object});
+ return 0;
+ },
+ [=](int rtn, const DataObjectPtr& data_object) {
+ if (rtn < 0) {
+ callback(-1, ExtractParams<DataObjectPtr>(data_object, 1));
+ } else {
+ callback(ExtractParams<GFError>(data_object, 0),
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ }
+ },
+ TransferParams());
+ handler.Start();
+ return handler;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/AsyncUtils.h b/src/core/utils/AsyncUtils.h
new file mode 100644
index 00000000..c16fc122
--- /dev/null
+++ b/src/core/utils/AsyncUtils.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCore.h"
+#include "core/thread/Task.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param callback
+ * @param operation
+ * @param minial_version
+ */
+auto GPGFRONTEND_CORE_EXPORT
+RunGpgOperaAsync(const GpgOperaRunnable& runnable,
+ const GpgOperationCallback& callback, const QString& operation,
+ const QString& minial_version) -> Thread::Task::TaskHandler;
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param operation
+ * @param minial_version
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+auto GPGFRONTEND_CORE_EXPORT RunGpgOperaSync(const GpgOperaRunnable& runnable,
+ const QString& operation,
+ const QString& minial_version)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param callback
+ * @param operation
+ */
+auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(const OperaRunnable& runnable,
+ const OperationCallback& callback,
+ const QString& operation)
+ -> Thread::Task::TaskHandler;
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param callback
+ * @param operation
+ * @return Thread::Task::TaskHandler
+ */
+auto GPGFRONTEND_CORE_EXPORT RunOperaAsync(const OperaRunnable& runnable,
+ const OperationCallback& callback,
+ const QString& operation)
+ -> Thread::Task::TaskHandler;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CacheUtils.cpp b/src/core/utils/CacheUtils.cpp
new file mode 100644
index 00000000..e521870c
--- /dev/null
+++ b/src/core/utils/CacheUtils.cpp
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CacheUtils.h"
+
+#include "core/function/CacheManager.h"
+
+namespace GpgFrontend {
+
+void SetCacheValue(const QString& key, QString value) {
+ CacheManager::GetInstance().SaveCache(key, std::move(value));
+}
+
+auto GetCacheValue(const QString& key) -> QString {
+ return CacheManager::GetInstance().LoadCache(key);
+}
+
+void ResetCacheValue(const QString& key) {
+ CacheManager::GetInstance().ResetCache(key);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CacheUtils.h b/src/core/utils/CacheUtils.h
new file mode 100644
index 00000000..48b9ac4b
--- /dev/null
+++ b/src/core/utils/CacheUtils.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief set a temp cache under a certain key
+ *
+ */
+void GPGFRONTEND_CORE_EXPORT SetCacheValue(const QString &key, QString value);
+
+/**
+ * @brief after get the temp cache, its value will be imediately ease in
+ * storage
+ *
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetCacheValue(const QString &key) -> QString;
+
+/**
+ * @brief imediately ease temp cache in storage
+ *
+ * @return QString
+ */
+void GPGFRONTEND_CORE_EXPORT ResetCacheValue(const QString &);
+
+} // namespace GpgFrontend
diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp
new file mode 100644
index 00000000..0b182241
--- /dev/null
+++ b/src/core/utils/CommonUtils.cpp
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CommonUtils.h"
+
+namespace GpgFrontend {
+
+auto BeautifyFingerprint(QString fingerprint) -> QString {
+ auto len = fingerprint.size();
+ QString buffer;
+ QTextStream out(&buffer);
+ decltype(len) count = 0;
+ while (count < len) {
+ if ((count != 0U) && ((count % 5) == 0)) out << " ";
+ out << fingerprint[count];
+ count++;
+ }
+ return out.readAll();
+}
+
+auto CompareSoftwareVersion(const QString& a, const QString& b) -> int {
+ auto remove_prefix = [](const QString& version) {
+ return version.startsWith('v') ? version.mid(1) : version;
+ };
+
+ auto real_version_a = remove_prefix(a);
+ auto real_version_b = remove_prefix(b);
+
+ QStringList split_a = real_version_a.split('.');
+ QStringList split_b = real_version_b.split('.');
+
+ const auto min_depth = std::min(split_a.size(), split_b.size());
+
+ for (int i = 0; i < min_depth; ++i) {
+ int const num_a = split_a[i].toInt();
+ int const num_b = split_b[i].toInt();
+
+ if (num_a != num_b) {
+ return (num_a > num_b) ? 1 : -1;
+ }
+ }
+
+ if (split_a.size() != split_b.size()) {
+ return (split_a.size() > split_b.size()) ? 1 : -1;
+ }
+
+ return 0;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h
new file mode 100644
index 00000000..a45c6056
--- /dev/null
+++ b/src/core/utils/CommonUtils.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/typedef/CoreTypedef.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param fingerprint
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint)
+ -> QString;
+
+/**
+ * @brief
+ *
+ * @param a
+ * @param b
+ * @return int
+ */
+auto GPGFRONTEND_CORE_EXPORT CompareSoftwareVersion(const QString& a,
+ const QString& b) -> int;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/FilesystemUtils.cpp b/src/core/utils/FilesystemUtils.cpp
new file mode 100644
index 00000000..9e531955
--- /dev/null
+++ b/src/core/utils/FilesystemUtils.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "FilesystemUtils.h"
+
+namespace GpgFrontend {
+
+auto GetOnlyFileNameWithPath(const QString &path) -> QString {
+ // Create a path object from given string
+ QFileInfo file_info(path);
+ // Check if file name in the path object has extension
+ if (!file_info.fileName().isEmpty()) {
+ // Fetch the extension from path object and return
+ return file_info.path() + "/" + file_info.baseName();
+ }
+ // In case of no extension return empty string
+ return {};
+}
+
+auto GetFileExtension(const QString &path) -> QString {
+ return QFileInfo(path).suffix();
+}
+
+/**
+ * @brief
+ *
+ */
+auto GetFileSizeByPath(const QString &path, const QString &filename_pattern)
+ -> int64_t {
+ auto dir = QDir(path);
+ QFileInfoList const file_list =
+ dir.entryInfoList(QStringList() << filename_pattern, QDir::Files);
+ qint64 total_size = 0;
+
+ for (const QFileInfo &file_info : file_list) {
+ total_size += file_info.size();
+ }
+ return total_size;
+}
+
+/**
+ * @brief
+ *
+ */
+auto GetHumanFriendlyFileSize(int64_t size) -> QString {
+ auto num = static_cast<double>(size);
+ QStringList list;
+ list << "KB"
+ << "MB"
+ << "GB"
+ << "TB";
+
+ QStringListIterator i(list);
+ QString unit("bytes");
+
+ while (num >= 1024.0 && i.hasNext()) {
+ unit = i.next();
+ num /= 1024.0;
+ }
+ return (QString().setNum(num, 'f', 2) + " " + unit);
+}
+
+/**
+ * @brief
+ *
+ */
+void DeleteAllFilesByPattern(const QString &path,
+ const QString &filename_pattern) {
+ auto dir = QDir(path);
+
+ QStringList const log_files =
+ dir.entryList(QStringList() << filename_pattern, QDir::Files);
+
+ for (const auto &file : log_files) {
+ QFile::remove(dir.absoluteFilePath(file));
+ }
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/FilesystemUtils.h b/src/core/utils/FilesystemUtils.h
new file mode 100644
index 00000000..0b58bbb7
--- /dev/null
+++ b/src/core/utils/FilesystemUtils.h
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief Get the file extension object
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFileExtension(const QString& path) -> QString;
+
+/**
+ * @brief Get the only file name with path object
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetOnlyFileNameWithPath(const QString& path)
+ -> QString;
+
+/**
+ * @brief Get the File Size By Path object
+ *
+ * @param path The path of the file
+ * @param filename_pattern The pattern of the file name, e.g. "*.txt"
+ * @return int64_t
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFileSizeByPath(
+ const QString& path, const QString& filename_pattern)
+ -> int64_t;
+
+/**
+ * @brief Get the Human Readable File Size object
+ *
+ * @param size
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetHumanFriendlyFileSize(int64_t size) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param filename_pattern
+ */
+void GPGFRONTEND_CORE_EXPORT DeleteAllFilesByPattern(
+ const QString& path, const QString& filename_pattern);
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
new file mode 100644
index 00000000..db3513eb
--- /dev/null
+++ b/src/core/utils/GpgUtils.cpp
@@ -0,0 +1,167 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgUtils.h"
+
+namespace GpgFrontend {
+
+inline auto Trim(QString& s) -> QString { return s.trimmed(); }
+
+auto GetGpgmeErrorString(size_t buffer_size, gpgme_error_t err) -> QString {
+ std::vector<char> buffer(buffer_size);
+
+ gpgme_error_t const ret = gpgme_strerror_r(err, buffer.data(), buffer.size());
+ if (ret == ERANGE && buffer_size < 1024) {
+ return GetGpgmeErrorString(buffer_size * 2, err);
+ }
+
+ return {buffer.data()};
+}
+
+auto GetGpgmeErrorString(gpgme_error_t err) -> QString {
+ return GetGpgmeErrorString(64, err);
+}
+
+auto CheckGpgError(GpgError err) -> GpgError {
+ auto err_code = gpg_err_code(err);
+ if (err_code != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR(
+ "gpg operation failed [error code: {}], source: {} description: {}",
+ err_code, gpgme_strsource(err), GetGpgmeErrorString(err));
+ }
+ return err_code;
+}
+
+auto CheckGpgError2ErrCode(GpgError err, GpgError predict) -> GpgErrorCode {
+ auto err_code = gpg_err_code(err);
+ if (err_code != gpg_err_code(predict)) {
+ if (err_code == GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err),
+ GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ } else {
+ GF_CORE_LOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err),
+ GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ }
+ }
+ return err_code;
+}
+
+auto DescribeGpgErrCode(GpgError err) -> GpgErrorDesc {
+ return {gpgme_strsource(err), GetGpgmeErrorString(err)};
+}
+
+auto CheckGpgError(GpgError err, const QString& /*comment*/) -> GpgError {
+ if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_WARN("[Error {}] Source: {} description: {}", gpg_err_code(err),
+ gpgme_strsource(err), GetGpgmeErrorString(err));
+ }
+ return err;
+}
+
+auto TextIsSigned(QString text) -> int {
+ auto trim_text = Trim(text);
+ if (trim_text.startsWith(PGP_SIGNED_BEGIN) &&
+ trim_text.endsWith(PGP_SIGNED_END)) {
+ return 2;
+ }
+ if (text.contains(PGP_SIGNED_BEGIN) && text.contains(PGP_SIGNED_END)) {
+ return 1;
+ }
+ return 0;
+}
+
+auto SetExtensionOfOutputFile(const QString& path, GpgOperation opera,
+ bool ascii) -> QString {
+ QString new_extension;
+ QString current_extension = QFileInfo(path).suffix();
+
+ if (ascii) {
+ switch (opera) {
+ case kENCRYPT:
+ case kSIGN:
+ case kENCRYPT_SIGN:
+ new_extension = current_extension + ".asc";
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ new_extension = current_extension + ".gpg";
+ break;
+ case kSIGN:
+ new_extension = current_extension + ".sig";
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!new_extension.isEmpty()) {
+ return QFileInfo(path).path() + "/" + QFileInfo(path).completeBaseName() +
+ "." + new_extension;
+ }
+
+ return path;
+}
+
+auto SetExtensionOfOutputFileForArchive(const QString& path, GpgOperation opera,
+ bool ascii) -> QString {
+ QString extension;
+
+ if (ascii) {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ extension = ".tar.asc";
+ return path + extension;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ extension = ".tar.gpg";
+ return path + extension;
+ break;
+ default:
+ break;
+ }
+ }
+
+ auto file_info = QFileInfo(path);
+ return file_info.absolutePath() + "/" + file_info.baseName();
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/utils/GpgUtils.h b/src/core/utils/GpgUtils.h
new file mode 100644
index 00000000..e6a466dc
--- /dev/null
+++ b/src/core/utils/GpgUtils.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+// Error Info Printer
+
+/**
+ * @brief
+ *
+ * @param err
+ * @return GpgError
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError(GpgError err) -> GpgError;
+
+/**
+ * @brief
+ *
+ * @param gpgmeError
+ * @param comment
+ * @return GpgError
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError(GpgError gpgmeError,
+ const QString& comment) -> GpgError;
+
+/**
+ * @brief
+ *
+ * @param err
+ * @param predict
+ * @return gpg_err_code_t
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError2ErrCode(
+ gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR)
+ -> gpg_err_code_t;
+
+/**
+ * @brief
+ *
+ * @param err
+ * @return GpgErrorDesc
+ */
+auto GPGFRONTEND_CORE_EXPORT DescribeGpgErrCode(GpgError err) -> GpgErrorDesc;
+
+// Check
+
+/**
+ * @brief
+ *
+ * @param text
+ * @return int
+ */
+auto GPGFRONTEND_CORE_EXPORT TextIsSigned(BypeArrayRef text) -> int;
+
+/**
+ * @brief
+ *
+ * @param opera
+ * @param ascii
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT SetExtensionOfOutputFile(const QString& path,
+ GpgOperation opera,
+ bool ascii) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param opera
+ * @param ascii
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT SetExtensionOfOutputFileForArchive(
+ const QString& path, GpgOperation opera, bool ascii) -> QString;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp
new file mode 100644
index 00000000..1541d726
--- /dev/null
+++ b/src/core/utils/IOUtils.cpp
@@ -0,0 +1,178 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "IOUtils.h"
+
+#include "core/GpgModel.h"
+#include "core/utils/FilesystemUtils.h"
+
+namespace GpgFrontend {
+
+auto GetFileChecksum(const QString& file_name,
+ QCryptographicHash::Algorithm hashAlgorithm)
+ -> QByteArray {
+ QFile f(file_name);
+ if (f.open(QFile::ReadOnly)) {
+ QCryptographicHash hash(hashAlgorithm);
+ if (hash.addData(&f)) {
+ return hash.result();
+ }
+ }
+ return {};
+}
+
+auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
+ QFile file(file_name);
+ if (!file.open(QIODevice::ReadOnly)) {
+ GF_CORE_LOG_ERROR("failed to open file: {}", file_name);
+ return false;
+ }
+ data = file.readAll();
+ file.close();
+ return true;
+}
+
+auto WriteFile(const QString& file_name, const QByteArray& data) -> bool {
+ QFile file(file_name);
+ if (!file.open(QIODevice::WriteOnly)) {
+ GF_CORE_LOG_ERROR("failed to open file for writing: {}", file_name);
+ return false;
+ }
+ file.write(data);
+ file.close();
+ return true;
+}
+
+auto ReadFileGFBuffer(const QString& file_name) -> std::tuple<bool, GFBuffer> {
+ QByteArray byte_data;
+ const bool res = ReadFile(file_name, byte_data);
+
+ return {res, GFBuffer(byte_data)};
+}
+
+auto WriteFileGFBuffer(const QString& file_name, GFBuffer data) -> bool {
+ return WriteFile(file_name, data.ConvertToQByteArray());
+}
+
+auto CalculateHash(const QString& file_path) -> QString {
+ // Returns empty QByteArray() on failure.
+ QFileInfo const info(file_path);
+ QString buffer;
+ QTextStream ss(&buffer);
+
+ if (info.isFile() && info.isReadable()) {
+ ss << "# " << QObject::tr("File Hash Information") << Qt::endl;
+ ss << "- " << QObject::tr("Filename") << QObject::tr(": ")
+ << info.fileName() << Qt::endl;
+
+ // read all data
+ ss << "- " << QObject::tr("File Size (bytes)") << QObject::tr(": ")
+ << QString::number(info.size()) << Qt::endl;
+
+ ss << "- " << QObject::tr("File Size") << QObject::tr(": ")
+ << GetHumanFriendlyFileSize(info.size()) << Qt::endl;
+
+ // md5
+ ss << "- "
+ << "MD5" << QObject::tr(": ")
+ << GetFileChecksum(file_path, QCryptographicHash::Md5).toHex()
+ << Qt::endl;
+
+ // sha1
+ ss << "- "
+ << "SHA1" << QObject::tr(": ")
+ << GetFileChecksum(file_path, QCryptographicHash::Sha1).toHex()
+ << Qt::endl;
+
+ // sha1
+ ss << "- "
+ << "SHA256" << QObject::tr(": ")
+ << GetFileChecksum(file_path, QCryptographicHash::Sha256).toHex()
+ << Qt::endl;
+
+ ss << Qt::endl;
+
+ } else {
+ ss << "# " << QObject::tr("Error: cannot read target file") << Qt::endl;
+ ss << "- " << QObject::tr("Filename") << QObject::tr(": ")
+ << info.fileName() << Qt::endl;
+ }
+
+ return ss.readAll();
+}
+
+auto GetTempFilePath() -> QString {
+ QString const temp_dir = QDir::tempPath();
+ QString const filename = QUuid::createUuid().toString() + ".data";
+ return temp_dir + "/" + filename;
+}
+
+auto CreateTempFileAndWriteData(const QString& data) -> QString {
+ auto temp_file = GetTempFilePath();
+ WriteFile(temp_file, data.toUtf8());
+ return temp_file;
+}
+
+auto CreateTempFileAndWriteData(const GFBuffer& data) -> QString {
+ auto temp_file = GetTempFilePath();
+ WriteFile(temp_file, data.ConvertToQByteArray());
+ return temp_file;
+}
+
+auto TargetFilePreCheck(const QString& path, bool read)
+ -> std::tuple<bool, QString> {
+ QFileInfo const file_info(path);
+
+ if (read) {
+ if (!file_info.exists()) {
+ return {false, QObject::tr("target path doesn't exists")};
+ }
+ } else {
+ QFileInfo const path_info(file_info.absolutePath());
+ if (!path_info.isWritable()) {
+ return {false, QObject::tr("do NOT have permission to write path")};
+ }
+ }
+
+ if (read ? !file_info.isReadable() : false) {
+ return {false, QObject::tr("do NOT have permission to read/write file")};
+ }
+
+ return {true, QObject::tr("Success")};
+}
+
+auto GetFullExtension(const QString& path) -> QString {
+ QString const filename = QFileInfo(path).fileName();
+
+ auto const dot_index = filename.indexOf('.');
+ if (dot_index == -1) return {};
+
+ return filename.mid(dot_index);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/IOUtils.h b/src/core/utils/IOUtils.h
new file mode 100644
index 00000000..2c48f38c
--- /dev/null
+++ b/src/core/utils/IOUtils.h
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GFBuffer.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param file_name
+ * @return GFBuffer
+ */
+auto GPGFRONTEND_CORE_EXPORT ReadFileGFBuffer(const QString &file_name)
+ -> std::tuple<bool, GFBuffer>;
+
+/**
+ * @brief
+ *
+ * @param file_name
+ * @param data
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteFileGFBuffer(const QString &file_name,
+ GFBuffer data) -> bool;
+
+/**
+ * @brief read file content
+ *
+ * @param file_name file name
+ * @param data data read from file
+ * @return true if success
+ * @return false if failed
+ */
+auto GPGFRONTEND_CORE_EXPORT ReadFile(const QString &file_name,
+ QByteArray &data) -> bool;
+
+/**
+ * @brief write file content
+ *
+ * @param file_name file name
+ * @param data data to write to file
+ * @return true if success
+ * @return false if failed
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteFile(const QString &file_name,
+ const QByteArray &data) -> bool;
+
+/**
+ * calculate the hash of a file
+ * @param file_path
+ * @return
+ */
+auto GPGFRONTEND_CORE_EXPORT CalculateHash(const QString &file_path) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param out_buffer
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteBufferToFile(const QString &path,
+ const QString &out_buffer)
+ -> bool;
+
+/**
+ * @brief
+ *
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetTempFilePath() -> QString;
+
+/**
+ * @brief
+ *
+ * @param data
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT CreateTempFileAndWriteData(const QString &data)
+ -> QString;
+
+/**
+ * @brief
+ *
+ * @param data
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT CreateTempFileAndWriteData(const GFBuffer &data)
+ -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param read
+ * @return std::tuple<bool, QString>
+ */
+auto GPGFRONTEND_CORE_EXPORT TargetFilePreCheck(const QString &path, bool read)
+ -> std::tuple<bool, QString>;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFullExtension(QString path) -> QString;
+
+} // namespace GpgFrontend
diff --git a/src/core/function/CharsetOperator.h b/src/core/utils/LocalizedUtils.cpp
index 41ce62f4..6c020ed7 100644
--- a/src/core/function/CharsetOperator.h
+++ b/src/core/utils/LocalizedUtils.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,28 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CHARSETDETECTOR_H
-#define GPGFRONTEND_CHARSETDETECTOR_H
+#include "LocalizedUtils.h"
-#include "core/GpgFrontendCore.h"
+#include "core/utils/LogUtils.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT CharsetOperator {
- public:
- using CharsetInfo = std::tuple<std::string, std::string, int>;
-
- static CharsetInfo Detect(const std::string &buffer);
-
- static bool Convert2Utf8(const std::string &buffer, std::string &out_buffer,
- std::string from_charset_name);
-};
+auto GetFormatedDateByTimestamp(time_t timestamp) -> QString {
+ return QLocale().toString(QDateTime::fromSecsSinceEpoch(timestamp));
+}
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CHARSETDETECTOR_H
diff --git a/src/core/utils/LocalizedUtils.h b/src/core/utils/LocalizedUtils.h
new file mode 100644
index 00000000..d7aaf0c8
--- /dev/null
+++ b/src/core/utils/LocalizedUtils.h
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+auto GPGFRONTEND_CORE_EXPORT GetFormatedDateByTimestamp(time_t) -> QString;
+
+} \ No newline at end of file
diff --git a/src/core/utils/LogUtils.cpp b/src/core/utils/LogUtils.cpp
new file mode 100644
index 00000000..fbf0c8d3
--- /dev/null
+++ b/src/core/utils/LogUtils.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "LogUtils.h"
+
+#include "core/function/LoggerManager.h"
+
+namespace GpgFrontend {
+
+auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetDefaultLogger();
+}
+
+auto GetCoreLogger() -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetInstance().GetLogger("core");
+}
+
+auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetInstance().GetLogger(id);
+}
+
+void SetDefaultLogLevel(spdlog::level::level_enum level) {
+ return LoggerManager::SetDefaultLogLevel(level);
+}
+
+void RegisterAsyncLogger(const QString& id, spdlog::level::level_enum level) {
+ LoggerManager::GetInstance().RegisterAsyncLogger(id, level);
+}
+
+void RegisterSyncLogger(const QString& id, spdlog::level::level_enum level) {
+ LoggerManager::GetInstance().RegisterSyncLogger(id, level);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/LogUtils.h b/src/core/utils/LogUtils.h
new file mode 100644
index 00000000..a1a5685a
--- /dev/null
+++ b/src/core/utils/LogUtils.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetDefaultLogger()
+ -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetCoreLogger() -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString &)
+ -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief Set the Default Log Level object
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT SetDefaultLogLevel(spdlog::level::level_enum);
+
+/**
+ * @brief
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString &,
+ spdlog::level::level_enum);
+
+/**
+ * @brief
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString &,
+ spdlog::level::level_enum);
+
+} // namespace GpgFrontend
+
+#define GF_DEFAULT_LOG_TRACE(...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_DEBUG(...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_INFO(...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_WARN(...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_ERROR(...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+
+#define GF_CORE_LOG_TRACE(...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_DEBUG(...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_INFO(...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_WARN(...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_ERROR(...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+
+#define GF_LOG_TRACE(ID, ...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_DEBUG(ID, ...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_INFO(ID, ...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_WARN(ID, ...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_ERROR(ID, ...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__)
diff --git a/src/core/utils/MemoryUtils.cpp b/src/core/utils/MemoryUtils.cpp
new file mode 100644
index 00000000..f002fd87
--- /dev/null
+++ b/src/core/utils/MemoryUtils.cpp
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "MemoryUtils.h"
+
+namespace GpgFrontend {
+
+auto SecureMalloc(std::size_t size) -> void * {
+ return SecureMemoryAllocator::Allocate(size);
+}
+
+auto SecureRealloc(void *ptr, std::size_t size) -> void * {
+ return SecureMemoryAllocator::Reallocate(ptr, size);
+}
+
+void SecureFree(void *ptr) { SecureMemoryAllocator::Deallocate(ptr); }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/MemoryUtils.h b/src/core/utils/MemoryUtils.h
new file mode 100644
index 00000000..76c75fc6
--- /dev/null
+++ b/src/core/utils/MemoryUtils.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/function/SecureMemoryAllocator.h"
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr, _set, _len) \
+ do { \
+ volatile char *_vptr = (volatile char *)(_ptr); \
+ size_t _vlen = (_len); \
+ while (_vlen) { \
+ *_vptr = (_set); \
+ _vptr++; \
+ _vlen--; \
+ } \
+ } while (0)
+#define wipememory(_ptr, _len) wipememory2(_ptr, 0, _len)
+#define wipe(_ptr, _len) wipememory2(_ptr, 0, _len)
+
+#define xtoi_1(p) \
+ (*(p) <= '9' ? (*(p) - '0') \
+ : *(p) <= 'F' ? (*(p) - 'A' + 10) \
+ : (*(p) - 'a' + 10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p) + 1))
+
+namespace GpgFrontend {
+
+template <typename T>
+class PointerConverter {
+ public:
+ explicit PointerConverter(void *ptr) : ptr_(ptr) {}
+
+ auto AsType() const -> T * { return static_cast<T *>(ptr_); }
+
+ private:
+ void *ptr_;
+};
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+auto GPGFRONTEND_CORE_EXPORT SecureMalloc(std::size_t) -> void *;
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+auto GPGFRONTEND_CORE_EXPORT SecureRealloc(void *, std::size_t) -> void *;
+
+/**
+ * @brief
+ *
+ * @tparam T
+ * @return T*
+ */
+template <typename T>
+auto SecureMallocAsType(std::size_t size) -> T * {
+ return PointerConverter<T>(SecureMemoryAllocator::Allocate(size)).AsType();
+}
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+template <typename T>
+auto SecureReallocAsType(T *ptr, std::size_t size) -> T * {
+ return PointerConverter<T>(SecureMemoryAllocator::Reallocate(ptr, size))
+ .AsType();
+}
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_CORE_EXPORT SecureFree(void *);
+
+template <typename T, typename... Args>
+static auto SecureCreateObject(Args &&...args) -> T * {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) return nullptr;
+
+ try {
+ return new (mem) T(std::forward<Args>(args)...);
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T>
+static void SecureDestroyObject(T *obj) {
+ if (!obj) return;
+ obj->~T();
+ SecureMemoryAllocator::Deallocate(obj);
+}
+
+template <typename T, typename... Args>
+static auto SecureCreateUniqueObject(Args &&...args)
+ -> std::unique_ptr<T, SecureObjectDeleter<T>> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ return std::unique_ptr<T, SecureObjectDeleter<T>>(
+ new (mem) T(std::forward<Args>(args)...));
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T, typename... Args>
+auto SecureCreateSharedObject(Args &&...args) -> std::shared_ptr<T> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ T *obj = new (mem) T(std::forward<Args>(args)...);
+ return std::shared_ptr<T>(obj, [](T *ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ });
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T, typename... Args>
+auto SecureCreateQSharedObject(Args &&...args) -> QSharedPointer<T> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ T *obj = new (mem) T(std::forward<Args>(args)...);
+ return QSharedPointer<T>(obj, [](T *ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ });
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/aes/aes_ssl.h b/src/core/utils/aes/aes_ssl.h
index e75b68dd..5c3ac935 100644
--- a/src/core/function/aes/aes_ssl.h
+++ b/src/core/utils/aes/aes_ssl.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_AES_SSL_H
-#define GPGFRONTEND_AES_SSL_H
+#pragma once
#include <openssl/aes.h>
#include <openssl/evp.h>
@@ -70,5 +69,3 @@ uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len);
uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len);
} // namespace GpgFrontend::RawAPI
-
-#endif // GPGFRONTEND_AES_SSL_H
diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/utils/aes/aes_ssl_cbc.cpp
index 3aa80ef5..3aa80ef5 100644
--- a/src/core/function/aes/aes_ssl_cbc.cpp
+++ b/src/core/utils/aes/aes_ssl_cbc.cpp