diff options
49 files changed, 630 insertions, 486 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index 97f9f68a..09b3a0ec 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -35,13 +35,15 @@ #include <boost/date_time.hpp> #include "core/function/GlobalSettingStation.h" -#include "core/function/basic/GpgFunctionObject.h" #include "core/function/gpg/GpgAdvancedOperator.h" #include "core/function/gpg/GpgContext.h" #include "core/module/ModuleManager.h" #include "core/thread/Task.h" #include "core/thread/TaskRunner.h" #include "core/thread/TaskRunnerGetter.h" +#include "core/utils/MemoryUtils.h" +#include "function/basic/ChannelObject.h" +#include "function/basic/SingletonStorage.h" namespace GpgFrontend { @@ -57,16 +59,19 @@ void InitCoreLoggingSystem(spdlog::level::level_enum level) { // 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)); + sinks.push_back(GpgFrontend::SecureCreateSharedObject< + spdlog::sinks::stderr_color_sink_mt>()); + sinks.push_back(GpgFrontend::SecureCreateSharedObject< + 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()); + auto core_logger = + GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>( + "core", begin(sinks), end(sinks), spdlog::thread_pool()); core_logger->set_pattern( "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)"); @@ -75,7 +80,7 @@ void InitCoreLoggingSystem(spdlog::level::level_enum level) { // flush policy #ifdef DEBUG - core_logger->flush_on(spdlog::level::debug); + core_logger->flush_on(spdlog::level::trace); #else core_logger->flush_on(spdlog::level::err); #endif @@ -175,7 +180,7 @@ void InitGpgFrontendCore() { // init default channel auto& default_ctx = GpgFrontend::GpgContext::CreateInstance( - kGpgfrontendDefaultChannel, [=]() -> std::unique_ptr<ChannelObject> { + kGpgfrontendDefaultChannel, [=]() -> ChannelObjectPtr { GpgFrontend::GpgContextInitArgs args; // set key database path @@ -192,8 +197,8 @@ void InitGpgFrontendCore() { 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, kGpgfrontendDefaultChannel)); + return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>( + args, kGpgFrontendDefaultChannel)); }); // exit if failed @@ -201,15 +206,14 @@ void InitGpgFrontendCore() { SPDLOG_ERROR("default gnupg context init error"); }; - // async init no-ascii channel + // async init no-ascii(binary output) channel Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) ->PostTask(new Thread::Task( [=](const DataObjectPtr& /*data_obj*/) -> int { // init non-ascii channel auto& ctx = GpgFrontend::GpgContext::CreateInstance( - kGpgfrontendNonAsciiChannel, - [=]() -> std::unique_ptr<ChannelObject> { + kGpgfrontendNonAsciiChannel, [=]() -> ChannelObjectPtr { GpgFrontend::GpgContextInitArgs args; args.ascii = false; @@ -229,8 +233,9 @@ void InitGpgFrontendCore() { 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, kGpgfrontendDefaultChannel)); + return ConvertToChannelObjectPtr<>( + SecureCreateUniqueObject<GpgContext>( + args, kGpgfrontendNonAsciiChannel)); }); if (!ctx.Good()) SPDLOG_ERROR("no-ascii channel init error"); @@ -257,13 +262,4 @@ void InitGpgFrontendCore() { 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, kGpgFrontendDefaultChannel)); - }); -} - } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h index 910e0562..0a10a639 100644 --- a/src/core/GpgCoreInit.h +++ b/src/core/GpgCoreInit.h @@ -63,12 +63,4 @@ void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore(); */ void reset_gpgfrontend_core(); -/** - * @brief - * - * @param channel - */ -void new_default_settings_channel( - int channel = GpgFrontend::kGpgfrontendDefaultChannel); - } // namespace GpgFrontend diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h index 89f2dee6..1d00aac6 100644 --- a/src/core/GpgFrontendCore.h +++ b/src/core/GpgFrontendCore.h @@ -34,7 +34,6 @@ // std #include <cstdint> #include <filesystem> -#include <memory> #include <string> #include <vector> diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp index a5eac78e..c6926c89 100644 --- a/src/core/function/CacheManager.cpp +++ b/src/core/function/CacheManager.cpp @@ -34,6 +34,7 @@ #include <utility> #include "core/function/DataObjectOperator.h" +#include "core/utils/MemoryUtils.h" namespace GpgFrontend { @@ -45,13 +46,13 @@ class ThreadSafeMap { void insert(const Key& key, const Value& value) { std::unique_lock lock(mutex_); - map_[key] = value; + (*map_)[key] = value; } auto get(const Key& key) -> std::optional<Value> { std::shared_lock lock(mutex_); - auto it = map_.find(key); - if (it != map_.end()) { + auto it = map_->find(key); + if (it != map_->end()) { return it->second; } return std::nullopt; @@ -59,32 +60,34 @@ class ThreadSafeMap { auto exists(const Key& key) -> bool { std::shared_lock lock(mutex_); - return map_.count(key) > 0; + return map_->count(key) > 0; } - auto begin() -> IteratorType { return map_mirror_.begin(); } + auto begin() -> IteratorType { return map_mirror_->begin(); } - auto end() -> IteratorType { return map_mirror_.end(); } + auto end() -> IteratorType { return map_mirror_->end(); } auto mirror() -> ThreadSafeMap& { std::shared_lock lock(mutex_); - map_mirror_ = map_; + *map_mirror_ = *map_; return *this; } auto remove(std::string key) -> bool { std::unique_lock lock(mutex_); - auto it = map_.find(key); - if (it != map_.end()) { - map_.erase(it); + auto it = map_->find(key); + if (it != map_->end()) { + map_->erase(it); return true; } return false; } private: - MapType map_mirror_; - MapType map_; + 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_; }; diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp index a6040231..40a70cee 100644 --- a/src/core/function/gpg/GpgContext.cpp +++ b/src/core/function/gpg/GpgContext.cpp @@ -243,7 +243,6 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> { static auto CustomPassphraseCb(void *hook, const char *uid_hint, const char *passphrase_info, int last_was_bad, int fd) -> gpgme_error_t { - auto *p_ctx = static_cast<GpgContext *>(hook); std::string passphrase; SPDLOG_DEBUG( diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp index 0b1c7c44..5215f34b 100644 --- a/src/core/function/gpg/GpgKeyGetter.cpp +++ b/src/core/function/gpg/GpgKeyGetter.cpp @@ -203,6 +203,8 @@ GpgKeyGetter::GpgKeyGetter(int channel) SPDLOG_DEBUG("called channel: {}", channel); } +GpgKeyGetter::~GpgKeyGetter() = default; + auto GpgKeyGetter::GetKey(const std::string& key_id, bool use_cache) -> GpgKey { return p_->GetKey(key_id, use_cache); } diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h index 287c062a..b3e6523e 100644 --- a/src/core/function/gpg/GpgKeyGetter.h +++ b/src/core/function/gpg/GpgKeyGetter.h @@ -48,6 +48,12 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter explicit GpgKeyGetter(int channel = kGpgFrontendDefaultChannel); /** + * @brief Destroy the Gpg Key Getter object + * + */ + ~GpgKeyGetter(); + + /** * @brief Get the Key object * * @param fpr diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 751d4f51..1c4c78a5 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -29,26 +29,25 @@ #include "GpgKeyOpera.h" #include <gpg-error.h> -#include <qeventloop.h> #include <boost/algorithm/string.hpp> #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 "core/GpgConstants.h" #include "core/GpgModel.h" #include "core/function/gpg/GpgCommandExecutor.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/result_analyse/GpgResultAnalyse.h" +#include "core/model/DataObject.h" #include "core/model/GpgGenKeyInfo.h" #include "core/module/ModuleManager.h" -#include "core/thread/Task.h" -#include "core/thread/TaskRunnerGetter.h" +#include "core/utils/AsyncUtils.h" #include "core/utils/CommonUtils.h" #include "core/utils/GpgUtils.h" -#include "model/DataObject.h" +#include "typedef/GpgTypedef.h" namespace GpgFrontend { @@ -165,78 +164,46 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key, * @param params key generation args * @return error information */ -auto GpgKeyOpera::GenerateKey(const std::unique_ptr<GenKeyInfo>& params, - GpgGenKeyResult& result) -> GpgError { - 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; - expires = - to_time_t(boost::posix_time::ptime(params->GetExpireTime())) - - std::chrono::system_clock::to_time_t(std::chrono ::system_clock::now()); - - GpgError err; - - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"}); - SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version); - - if (CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0) { - 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; - - SPDLOG_DEBUG("args: {}", userid, algo, expires, flags); - - err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags); - - } 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); - } - - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { - auto temp_result = NewResult(gpgme_op_genkey_result(ctx_)); - std::swap(temp_result, result); - } - - return CheckGpgError(err); +void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, + const GpgOperationCallback& callback) { + RunGpgOperaAsync( + [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { + 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; + expires = to_time_t(boost::posix_time::ptime(params->GetExpireTime())) - + std::chrono::system_clock::to_time_t( + std::chrono ::system_clock::now()); + + 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; + + SPDLOG_DEBUG("key generation args: {}", userid, algo, expires, flags); + err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); + + GpgGenKeyResult result; + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + auto temp_result = NewResult(gpgme_op_genkey_result(ctx)); + std::swap(temp_result, result); + } + data_object->Swap({result}); + + return CheckGpgError(err); + }, + callback, "gpgme_op_passwd", "2.1.0"); } /** @@ -245,65 +212,50 @@ auto GpgKeyOpera::GenerateKey(const std::unique_ptr<GenKeyInfo>& params, * @param params opera args * @return error info */ -auto GpgKeyOpera::GenerateSubkey(const GpgKey& key, - const std::unique_ptr<GenKeyInfo>& params) - -> GpgError { - 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; - - expires = - to_time_t(boost::posix_time::ptime(params->GetExpireTime())) - - std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - - 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; - - SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags); - - auto err = gpgme_op_createsubkey(ctx_, static_cast<gpgme_key_t>(key), algo, 0, - expires, flags); - return CheckGpgError(err); +void GpgKeyOpera::GenerateSubkey(const GpgKey& key, + const std::shared_ptr<GenKeyInfo>& params, + const GpgOperationCallback& callback) { + RunGpgOperaAsync( + [key = key.Copy(), &ctx = ctx_, + params](const DataObjectPtr&) -> GpgError { + 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; + + expires = to_time_t(boost::posix_time::ptime(params->GetExpireTime())) - + std::chrono::system_clock::to_time_t( + std::chrono::system_clock::now()); + + 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; + + SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags); + + auto err = gpgme_op_createsubkey(ctx, static_cast<gpgme_key_t>(key), + algo, 0, expires, flags); + return CheckGpgError(err); + }, + callback, "gpgme_op_createsubkey", "2.1.13"); } void GpgKeyOpera::ModifyPassword(const GpgKey& key, - std::function<void(gpgme_error_t)> callback) { - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"}); - SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version); - - if (CompareSoftwareVersion(gnupg_version, "2.0.15") < 0) { - SPDLOG_ERROR("operator not support"); - callback(GPG_ERR_NOT_SUPPORTED); - return; - } - - auto* task = new Thread::Task( - [&](const DataObjectPtr& data_object) -> int { - auto err = gpgme_op_passwd(ctx_, static_cast<gpgme_key_t>(key), 0); - data_object->Swap({err}); - return 0; + const GpgOperationCallback& callback) { + RunGpgOperaAsync( + [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError { + return gpgme_op_passwd(ctx, static_cast<gpgme_key_t>(key), 0); }, - "gpgme_op_passwd", TransferParams(), - [=](int, const DataObjectPtr& data_object) { - SPDLOG_DEBUG("callback called"); - callback(ExtractParams<gpgme_error_t>(data_object, 0)); - }); - - Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) - ->PostTask(task); + callback, "gpgme_op_passwd", "2.0.15"); } auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key, diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index dd2ee60d..34bcd976 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -31,7 +31,6 @@ #include <functional> #include "core/function/gpg/GpgContext.h" -#include "core/function/result_analyse/GpgResultAnalyse.h" #include "core/typedef/GpgTypedef.h" namespace boost::posix_time { @@ -100,7 +99,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param key * @return GpgFrontend::GpgError */ - void ModifyPassword(const GpgKey& key, std::function<void(gpgme_error_t)>); + void ModifyPassword(const GpgKey& key, const GpgOperationCallback&); /** * @brief @@ -118,8 +117,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param result * @return GpgFrontend::GpgError */ - auto GenerateKey(const std::unique_ptr<GenKeyInfo>& params, - GpgGenKeyResult& result) -> GpgFrontend::GpgError; + void GenerateKey(const std::shared_ptr<GenKeyInfo>&, + const GpgOperationCallback&); /** * @brief @@ -128,9 +127,9 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param params * @return GpgFrontend::GpgError */ - auto GenerateSubkey(const GpgKey& key, - const std::unique_ptr<GenKeyInfo>& params) - -> GpgFrontend::GpgError; + void GenerateSubkey(const GpgKey& key, + const std::shared_ptr<GenKeyInfo>& params, + const GpgOperationCallback&); private: GpgContext& ctx_ = diff --git a/src/core/model/DataObject.h b/src/core/model/DataObject.h index b1b41283..b5c4fa5a 100644 --- a/src/core/model/DataObject.h +++ b/src/core/model/DataObject.h @@ -31,6 +31,7 @@ #include <any> #include "core/GpgFrontendCoreExport.h" +#include "core/utils/MemoryUtils.h" namespace GpgFrontend { @@ -77,7 +78,8 @@ class GPGFRONTEND_CORE_EXPORT DataObject { template <typename... Args> auto TransferParams(Args&&... args) -> std::shared_ptr<DataObject> { - return std::make_shared<DataObject>(DataObject{std::forward<Args>(args)...}); + return GpgFrontend::SecureCreateSharedObject<DataObject>( + DataObject{std::forward<Args>(args)...}); } template <typename T> diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp index a183c240..8a7f5a6e 100644 --- a/src/core/model/GpgKey.cpp +++ b/src/core/model/GpgKey.cpp @@ -41,6 +41,30 @@ auto GpgKey::operator=(GpgKey &&k) noexcept -> GpgKey & { return *this; } +GpgKey::GpgKey(const GpgKey &key) noexcept { + { + const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex_); + gpgme_key_ref(key.key_ref_.get()); + } + auto *new_key_ref = key_ref_.get(); + this->key_ref_ = KeyRefHandler(std::move(new_key_ref)); +} + +auto GpgKey::operator=(const GpgKey &key) -> GpgKey & { + if (this == &key) { + return *this; + } + + { + const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex_); + gpgme_key_ref(key.key_ref_.get()); + } + auto *new_key_ref = key_ref_.get(); + this->key_ref_ = KeyRefHandler(std::move(new_key_ref)); + + return *this; +} + auto GpgKey::operator==(const GpgKey &o) const -> bool { return o.GetId() == this->GetId(); } diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h index 6dfd5cb7..5fc3961b 100644 --- a/src/core/model/GpgKey.h +++ b/src/core/model/GpgKey.h @@ -299,7 +299,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { * * @param k */ - GpgKey(GpgKey&& k) noexcept; + GpgKey(GpgKey&&) noexcept; /** * @brief @@ -307,7 +307,22 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { * @param k * @return GpgKey& */ - auto operator=(GpgKey&& k) noexcept -> GpgKey&; + auto operator=(GpgKey&&) noexcept -> GpgKey&; + + /** + * @brief Construct a new Gpg Key object + * + * @param k + */ + GpgKey(const GpgKey&) noexcept; + + /** + * @brief + * + * @param k + * @return GpgKey& + */ + auto operator=(const GpgKey&) -> GpgKey&; /** * @brief @@ -315,7 +330,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { * @param key * @return GpgKey& */ - auto operator=(const gpgme_key_t& key) -> GpgKey& = delete; + auto operator=(const gpgme_key_t&) -> GpgKey& = delete; /** * @brief @@ -324,7 +339,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { * @return true * @return false */ - auto operator==(const GpgKey& o) const -> bool; + auto operator==(const GpgKey&) const -> bool; /** * @brief @@ -333,7 +348,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { * @return true * @return false */ - auto operator<=(const GpgKey& o) const -> bool; + auto operator<=(const GpgKey&) const -> bool; /** * @brief diff --git a/src/core/module/Event.h b/src/core/module/Event.h index fa583774..49ae3299 100644 --- a/src/core/module/Event.h +++ b/src/core/module/Event.h @@ -90,7 +90,7 @@ 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 std::make_shared<Event>(event_id, params, e_cb); + 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 index cb459f65..4195d719 100644 --- a/src/core/module/GlobalModuleContext.cpp +++ b/src/core/module/GlobalModuleContext.cpp @@ -119,7 +119,8 @@ class GlobalModuleContext::Impl { ModuleRegisterInfo register_info; register_info.module = module; register_info.channel = acquire_new_unique_channel(); - register_info.task_runner = std::make_shared<Thread::TaskRunner>(); + register_info.task_runner = + GpgFrontend::SecureCreateSharedObject<Thread::TaskRunner>(); register_info.task_runner->Start(); // move module to its task runner' thread @@ -128,7 +129,8 @@ class GlobalModuleContext::Impl { // Register the module with its identifier. module_register_table_[module->GetModuleIdentifier()] = - std::make_shared<ModuleRegisterInfo>(std::move(register_info)); + GpgFrontend::SecureCreateSharedObject<ModuleRegisterInfo>( + std::move(register_info)); SPDLOG_DEBUG("successfully registered module: {}", module->GetModuleIdentifier()); diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp index 4400a92d..5e2aa994 100644 --- a/src/core/module/ModuleManager.cpp +++ b/src/core/module/ModuleManager.cpp @@ -44,9 +44,11 @@ ModuleMangerPtr ModuleManager::g_ = nullptr; class ModuleManager::Impl { public: Impl() - : task_runner_(std::make_shared<Thread::TaskRunner>()), - gmc_(std::make_shared<GlobalModuleContext>(task_runner_)), - grt_(std::make_shared<GlobalRegisterTable>()) { + : task_runner_( + GpgFrontend::SecureCreateSharedObject<Thread::TaskRunner>()), + gmc_(GpgFrontend::SecureCreateSharedObject<GlobalModuleContext>( + task_runner_)), + grt_(GpgFrontend::SecureCreateSharedObject<GlobalRegisterTable>()) { task_runner_->Start(); } diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h index cf845f96..76d6c042 100644 --- a/src/core/module/ModuleManager.h +++ b/src/core/module/ModuleManager.h @@ -91,13 +91,14 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager : public QObject { template <typename T, typename... Args> void RegisterModule(Args&&... args) { ModuleManager::GetInstance()->RegisterModule( - std::make_shared<T>(std::forward<Args>(args)...)); + GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...)); } template <typename T, typename... Args> void RegisterAndActivateModule(Args&&... args) { auto manager = ModuleManager::GetInstance(); - auto module = std::make_shared<T>(std::forward<Args>(args)...); + auto module = + GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...); manager->RegisterModule(module); manager->ActiveModule(module->GetModuleIdentifier()); } diff --git a/src/core/thread/TaskRunnerGetter.cpp b/src/core/thread/TaskRunnerGetter.cpp index 2e4de859..639a142c 100644 --- a/src/core/thread/TaskRunnerGetter.cpp +++ b/src/core/thread/TaskRunnerGetter.cpp @@ -42,7 +42,7 @@ TaskRunnerPtr GpgFrontend::Thread::TaskRunnerGetter::GetTaskRunner( if (it != task_runners_.end()) { return it->second; } else { - auto runner = std::make_shared<TaskRunner>(); + auto runner = GpgFrontend::SecureCreateSharedObject<TaskRunner>(); task_runners_[runner_type] = runner; runner->Start(); continue; diff --git a/src/init.cpp b/src/init.cpp index ad07425c..91d02ac8 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -37,11 +37,11 @@ #include <filesystem> #include <string> -#include "GpgFrontend.h" -#include "GpgFrontendBuildInfo.h" #include "core/GpgCoreInit.h" #include "core/function/GlobalSettingStation.h" +#include "core/utils/MemoryUtils.h" #include "module/GpgFrontendModuleInit.h" +#include "spdlog/logger.h" #include "ui/GpgFrontendUIInit.h" // main @@ -62,23 +62,27 @@ int setenv(const char *name, const char *value, int overwrite) { void InitMainLoggingSystem(spdlog::level::level_enum level) { // sinks std::vector<spdlog::sink_ptr> sinks; - sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>()); - - // thread pool - spdlog::init_thread_pool(1024, 2); + sinks.push_back(GpgFrontend::SecureCreateSharedObject< + spdlog::sinks::stderr_color_sink_mt>()); // logger - auto main_logger = std::make_shared<spdlog::async_logger>( - "main", begin(sinks), end(sinks), spdlog::thread_pool()); + auto main_logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>( + "main", begin(sinks), end(sinks)); main_logger->set_pattern( "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)"); // set the level of logger main_logger->set_level(level); +#ifdef DEBUG + // flush policy + main_logger->flush_on(spdlog::level::trace); +#else // flush policy main_logger->flush_on(spdlog::level::err); - spdlog::flush_every(std::chrono::seconds(5)); +#endif + + spdlog::flush_every(std::chrono::seconds(3)); // register it as default logger spdlog::set_default_logger(main_logger); diff --git a/src/module/integrated/version_checking_module/VersionCheckTask.cpp b/src/module/integrated/version_checking_module/VersionCheckTask.cpp index 9e080605..85eb07c4 100644 --- a/src/module/integrated/version_checking_module/VersionCheckTask.cpp +++ b/src/module/integrated/version_checking_module/VersionCheckTask.cpp @@ -30,7 +30,6 @@ #include <QMetaType> #include <QtNetwork> -#include <memory> #include <nlohmann/json.hpp> #include "GpgFrontendBuildInfo.h" diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.h b/src/module/integrated/version_checking_module/VersionCheckingModule.h index 4ee56009..0a215588 100644 --- a/src/module/integrated/version_checking_module/VersionCheckingModule.h +++ b/src/module/integrated/version_checking_module/VersionCheckingModule.h @@ -30,8 +30,6 @@ #include <module/sdk/GpgFrontendModuleSDK.h> -#include <memory> - #include "SoftwareVersion.h" namespace GpgFrontend::Module::Integrated::VersionCheckingModule { diff --git a/src/module/sdk/Log.cpp b/src/module/sdk/Log.cpp index 1132826b..4d6620ff 100644 --- a/src/module/sdk/Log.cpp +++ b/src/module/sdk/Log.cpp @@ -45,16 +45,19 @@ void InitModuleLoggingSystem(spdlog::level::level_enum level) { // 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>( + 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.u8string(), 1048576 * 32, 32)); // thread pool spdlog::init_thread_pool(1024, 2); // logger - auto module_logger = std::make_shared<spdlog::async_logger>( - "module", begin(sinks), end(sinks), spdlog::thread_pool()); + auto module_logger = + GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>( + "module", begin(sinks), end(sinks), spdlog::thread_pool()); module_logger->set_pattern( "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)"); diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp index a1dbc5f6..454e0e2a 100644 --- a/src/ui/GpgFrontendUIInit.cpp +++ b/src/ui/GpgFrontendUIInit.cpp @@ -207,15 +207,17 @@ void InitUILoggingSystem(spdlog::level::level_enum level) { // 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, 32)); + sinks.push_back(GpgFrontend::SecureCreateSharedObject< + spdlog::sinks::stderr_color_sink_mt>()); + sinks.push_back(GpgFrontend::SecureCreateSharedObject< + spdlog::sinks::rotating_file_sink_mt>(logfile_path.u8string(), + 1048576 * 32, 32)); // thread pool spdlog::init_thread_pool(1024, 2); // logger - auto ui_logger = std::make_shared<spdlog::async_logger>( + auto ui_logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>( "ui", begin(sinks), end(sinks), spdlog::thread_pool()); ui_logger->set_pattern( "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)"); diff --git a/src/ui/UISignalStation.cpp b/src/ui/UISignalStation.cpp index 9370bcf4..8357cb06 100644 --- a/src/ui/UISignalStation.cpp +++ b/src/ui/UISignalStation.cpp @@ -28,10 +28,6 @@ #include "UISignalStation.h" -#include <memory> - -#include "core/function/CoreSignalStation.h" - namespace GpgFrontend::UI { std::unique_ptr<UISignalStation> UISignalStation::instance = nullptr; diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index dabdf657..04c6feb3 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -28,6 +28,8 @@ #include "UserInterfaceUtils.h" +#include <gpg-error.h> + #include <QtNetwork> #include <string> #include <utility> @@ -41,7 +43,9 @@ #include "core/thread/Task.h" #include "core/thread/TaskRunner.h" #include "core/thread/TaskRunnerGetter.h" +#include "core/typedef/GpgTypedef.h" #include "core/utils/CacheUtils.h" +#include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" #include "ui/UISignalStation.h" #include "ui/dialog/WaitingDialog.h" @@ -214,6 +218,44 @@ CommonUtils::CommonUtils() : QWidget(nullptr) { }); } +void CommonUtils::WaitForOpera(QWidget *parent, + const std::string &waiting_dialog_title, + const OperaWaitingCb &opera) { + QEventLoop looper; + auto *dialog = new WaitingDialog(_("Generating"), parent); + connect(dialog, &QDialog::finished, &looper, &QEventLoop::quit); + + opera([dialog]() { dialog->accept(); }); + + dialog->show(); + looper.exec(); +} + +void CommonUtils::RaiseMessageBox(QWidget *parent, GpgError err) { + GpgErrorDesc desc = DescribeGpgErrCode(err); + GpgErrorCode err_code = CheckGpgError2ErrCode(err); + + if (err_code == GPG_ERR_NO_ERROR) { + QMessageBox::information(parent, _("Success"), + QString::fromStdString(_("Operation succeed."))); + } else { + RaiseFailureMessageBox(parent, err); + } +} + +void CommonUtils::RaiseFailureMessageBox(QWidget *parent, GpgError err) { + GpgErrorDesc desc = DescribeGpgErrCode(err); + GpgErrorCode err_code = CheckGpgError2ErrCode(err); + + QMessageBox::critical( + parent, _("Failure"), + QString::fromStdString( + (boost::format(_("Operation failed.\n\nError code: %1%\nSource: " + " %2%\nDEscription: %3%")) % + err_code % desc.first % desc.second) + .str())); +} + void CommonUtils::SlotImportKeys(QWidget *parent, const std::string &in_buffer) { GpgImportInformation result = GpgKeyImportExporter::GetInstance().ImportKey( diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index 3746526a..a1719016 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -28,6 +28,8 @@ #pragma once +#include <qwidget.h> + #include "core/function/result_analyse/GpgVerifyResultAnalyse.h" #include "core/model/GpgKey.h" #include "core/thread/ThreadingModel.h" @@ -43,6 +45,9 @@ namespace GpgFrontend::UI { class InfoBoardWidget; class TextEdit; +using OperaWaitingHd = std::function<void()>; +using OperaWaitingCb = const std::function<void(OperaWaitingHd)>; + /** * @brief * @@ -148,6 +153,28 @@ class CommonUtils : public QWidget { /** * @brief * + * @param err + */ + static void WaitForOpera(QWidget* parent, const std::string&, + const OperaWaitingCb&); + + /** + * @brief + * + * @param err + */ + static void RaiseMessageBox(QWidget* parent, GpgError err); + + /** + * @brief + * + * @param err + */ + static void RaiseFailureMessageBox(QWidget* parent, GpgError err); + + /** + * @brief + * */ bool isApplicationNeedRestart(); diff --git a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp b/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp index a985c861..57e972cd 100644 --- a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp +++ b/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp @@ -39,7 +39,7 @@ namespace GpgFrontend::UI { GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent) : GeneralDialog("GnuPGControllerDialog", parent), - ui_(std::make_shared<Ui_GnuPGControllerDialog>()) { + ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGControllerDialog>()) { ui_->setupUi(this); ui_->generalBox->setTitle(_("General")); diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp index 260ca29d..cd48d2a8 100644 --- a/src/ui/dialog/help/GnupgTab.cpp +++ b/src/ui/dialog/help/GnupgTab.cpp @@ -41,7 +41,8 @@ #include "ui_GnuPGInfo.h" GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_GnuPGInfo>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGInfo>()) { ui_->setupUi(this); QStringList components_column_titles; @@ -233,5 +234,4 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { } } // ui_->configurationDetailsTable->resizeColumnsToContents(); - } diff --git a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp index 854152ae..4b616741 100644 --- a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp +++ b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp @@ -38,7 +38,7 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( KeyIdArgsListPtr key_ids, QWidget* parent) : GeneralDialog(typeid(ExportKeyPackageDialog).name(), parent), - ui_(std::make_shared<Ui_exportKeyPackageDialog>()), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_exportKeyPackageDialog>()), key_ids_(std::move(key_ids)) { ui_->setupUi(this); diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp index 0d9c1311..cc438364 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.cpp +++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp @@ -61,7 +61,7 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, } void KeyUploadDialog::SlotUpload() { - auto out_data = std::make_shared<ByteArray>(); + auto out_data = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgKeyImportExporter::GetInstance().ExportKeys(*m_keys_, out_data); slot_upload_key_to_server(*out_data); diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp index a70e27d1..f4c80065 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.cpp +++ b/src/ui/dialog/key_generate/KeygenDialog.cpp @@ -28,14 +28,19 @@ #include "KeygenDialog.h" +#include <qdialog.h> +#include <qeventloop.h> #include <qobject.h> #include "core/GpgModel.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyOpera.h" -#include "core/utils/CacheUtils.h" +#include "core/model/DataObject.h" +#include "core/typedef/GpgTypedef.h" +#include "core/utils/GpgUtils.h" #include "dialog/WaitingDialog.h" #include "ui/UISignalStation.h" +#include "ui/UserInterfaceUtils.h" namespace GpgFrontend::UI { @@ -48,12 +53,6 @@ KeyGenDialog::KeyGenDialog(QWidget* parent) GlobalSettingStation::GetInstance().LookupSettings( "general.longer_expiration_date", false); - bool use_pinentry_as_password_input_dialog = - GlobalSettingStation::GetInstance().LookupSettings( - "general.use_pinentry_as_password_input_dialog", false); - - use_pinentry_ = use_pinentry_as_password_input_dialog; - max_date_time_ = longer_expiration_date ? QDateTime::currentDateTime().toLocalTime().addYears(30) : QDateTime::currentDateTime().toLocalTime().addYears(2); @@ -71,15 +70,15 @@ KeyGenDialog::KeyGenDialog(QWidget* parent) void KeyGenDialog::generate_key_dialog() { key_usage_group_box_ = create_key_usage_group_box(); - auto* groupGrid = new QGridLayout(this); - groupGrid->addWidget(create_basic_info_group_box(), 0, 0); - groupGrid->addWidget(key_usage_group_box_, 1, 0); + auto* group_grid = new QGridLayout(this); + group_grid->addWidget(create_basic_info_group_box(), 0, 0); + group_grid->addWidget(key_usage_group_box_, 1, 0); - auto* nameList = new QWidget(this); - nameList->setLayout(groupGrid); + auto* name_list = new QWidget(this); + name_list->setLayout(group_grid); auto* vbox2 = new QVBoxLayout(); - vbox2->addWidget(nameList); + vbox2->addWidget(name_list); vbox2->addWidget(error_label_); vbox2->addWidget(button_box_); @@ -98,11 +97,11 @@ void KeyGenDialog::slot_key_gen_accept() { */ if ((name_edit_->text()).size() < 5) { error_stream << " " << _("Name must contain at least five characters.") - << std::endl; + << '\n'; } if (email_edit_->text().isEmpty() || !check_email_address(email_edit_->text())) { - error_stream << " " << _("Please give a email address.") << std::endl; + error_stream << " " << _("Please give a email address.") << '\n'; } /** @@ -110,12 +109,7 @@ void KeyGenDialog::slot_key_gen_accept() { * in the future) */ if (date_edit_->dateTime() > max_date_time_) { - error_stream << " " << _("Expiration time too long.") << std::endl; - } - - if (!use_pinentry_ && passphrase_edit_->isEnabled() && - passphrase_edit_->text().size() == 0) { - error_stream << " " << _("Password is empty.") << std::endl; + error_stream << " " << _("Expiration time too long.") << '\n'; } auto err_string = error_stream.str(); @@ -130,7 +124,7 @@ void KeyGenDialog::slot_key_gen_accept() { gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - if (expire_check_box_->checkState()) { + if (expire_check_box_->checkState() != 0U) { gen_key_info_->SetNonExpired(true); } else { #ifdef GPGFRONTEND_GUI_QT6 @@ -142,49 +136,21 @@ void KeyGenDialog::slot_key_gen_accept() { #endif } - if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) { - SetTempCacheValue("__key_passphrase", - this->passphrase_edit_->text().toStdString()); - } - - GpgGenKeyResult result; - gpgme_error_t error = false; - auto thread = QThread::create([&]() { - error = GpgKeyOpera::GetInstance().GenerateKey(gen_key_info_, result); - }); - thread->start(); - - auto* dialog = new WaitingDialog(_("Generating"), this); - dialog->show(); - - while (thread->isRunning()) { - QCoreApplication::processEvents(); - } - - dialog->close(); - - if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) { - ResetTempCacheValue("__key_passphrase"); - } + CommonUtils::WaitForOpera( + this, _("Generating"), + [this, gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) { + GpgKeyOpera::GetInstance().GenerateKey( + gen_key_info, [this, hd](GpgError err, const DataObjectPtr&) { + GpgGenKeyResult result; + CommonUtils::RaiseMessageBox(this, err); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + emit SignalKeyGenerated(); + } + hd(); + }); + }); SPDLOG_DEBUG("key generation done"); - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - auto* msg_box = new QMessageBox(qobject_cast<QWidget*>(this->parent())); - msg_box->setAttribute(Qt::WA_DeleteOnClose); - msg_box->setStandardButtons(QMessageBox::Ok); - msg_box->setWindowTitle(_("Success")); - msg_box->setText(_("The new key pair has been generated.")); - msg_box->setModal(true); - msg_box->open(); - - SPDLOG_DEBUG("key generate successful"); - - emit SignalKeyGenerated(); - } else { - QMessageBox::critical(this, _("Failure"), _("Key generation failed.")); - } - this->done(0); } else { @@ -210,21 +176,21 @@ void KeyGenDialog::slot_expire_box_changed() { } QGroupBox* KeyGenDialog::create_key_usage_group_box() { - auto* groupBox = new QGroupBox(this); + auto* group_box = new QGroupBox(this); auto* grid = new QGridLayout(this); - groupBox->setTitle(_("Key Usage")); + group_box->setTitle(_("Key Usage")); - auto* encrypt = new QCheckBox(_("Encryption"), groupBox); + auto* encrypt = new QCheckBox(_("Encryption"), group_box); encrypt->setTristate(false); - auto* sign = new QCheckBox(_("Signing"), groupBox); + auto* sign = new QCheckBox(_("Signing"), group_box); sign->setTristate(false); - auto* cert = new QCheckBox(_("Certification"), groupBox); + auto* cert = new QCheckBox(_("Certification"), group_box); cert->setTristate(false); - auto* auth = new QCheckBox(_("Authentication"), groupBox); + auto* auth = new QCheckBox(_("Authentication"), group_box); auth->setTristate(false); key_usage_check_boxes_.push_back(encrypt); @@ -237,9 +203,9 @@ QGroupBox* KeyGenDialog::create_key_usage_group_box() { grid->addWidget(cert, 1, 0); grid->addWidget(auth, 1, 1); - groupBox->setLayout(grid); + group_box->setLayout(grid); - return groupBox; + return group_box; } void KeyGenDialog::slot_encryption_box_changed(int state) { @@ -285,50 +251,59 @@ void KeyGenDialog::slot_activated_key_type(int index) { } void KeyGenDialog::refresh_widgets_state() { - if (gen_key_info_->IsAllowEncryption()) + if (gen_key_info_->IsAllowEncryption()) { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeEncryption()) + if (gen_key_info_->IsAllowChangeEncryption()) { key_usage_check_boxes_[0]->setDisabled(false); - else + } else { key_usage_check_boxes_[0]->setDisabled(true); + } - if (gen_key_info_->IsAllowSigning()) + if (gen_key_info_->IsAllowSigning()) { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeSigning()) + if (gen_key_info_->IsAllowChangeSigning()) { key_usage_check_boxes_[1]->setDisabled(false); - else + } else { key_usage_check_boxes_[1]->setDisabled(true); + } - if (gen_key_info_->IsAllowCertification()) + if (gen_key_info_->IsAllowCertification()) { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeCertification()) + if (gen_key_info_->IsAllowChangeCertification()) { key_usage_check_boxes_[2]->setDisabled(false); - else + } else { key_usage_check_boxes_[2]->setDisabled(true); + } - if (gen_key_info_->IsAllowAuthentication()) + if (gen_key_info_->IsAllowAuthentication()) { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeAuthentication()) + if (gen_key_info_->IsAllowChangeAuthentication()) { key_usage_check_boxes_[3]->setDisabled(false); - else + } else { key_usage_check_boxes_[3]->setDisabled(true); + } - if (gen_key_info_->IsAllowNoPassPhrase()) + if (gen_key_info_->IsAllowNoPassPhrase()) { no_pass_phrase_check_box_->setDisabled(false); - else + } else { no_pass_phrase_check_box_->setDisabled(true); + } key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), gen_key_info_->GetSuggestMaxKeySize()); @@ -360,7 +335,6 @@ void KeyGenDialog::set_signal_slot() { connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, [this](int state) -> void { gen_key_info_->SetNonPassPhrase(state != 0); - passphrase_edit_->setDisabled(state != 0); }); } @@ -375,9 +349,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { comment_edit_ = new QLineEdit(this); key_size_spin_box_ = new QSpinBox(this); key_type_combo_box_ = new QComboBox(this); - passphrase_edit_ = new QLineEdit(this); - for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { + for (const auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { key_type_combo_box_->addItem(QString::fromStdString(algo.first)); } if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { @@ -395,9 +368,6 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { expire_check_box_ = new QCheckBox(this); expire_check_box_->setCheckState(Qt::Unchecked); - passphrase_edit_->setEchoMode(QLineEdit::Password); - passphrase_edit_->setHidden(use_pinentry_); - no_pass_phrase_check_box_ = new QCheckBox(this); no_pass_phrase_check_box_->setCheckState(Qt::Unchecked); @@ -410,9 +380,7 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 3, 3); vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 4, 0); vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 5, 0); - if (!use_pinentry_) - vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 6, 0); - vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 6, 3); + vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 6, 0); vbox1->addWidget(name_edit_, 0, 1, 1, 3); vbox1->addWidget(email_edit_, 1, 1, 1, 3); @@ -421,14 +389,13 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { vbox1->addWidget(expire_check_box_, 3, 2); vbox1->addWidget(key_size_spin_box_, 4, 1); vbox1->addWidget(key_type_combo_box_, 5, 1); - if (!use_pinentry_) vbox1->addWidget(passphrase_edit_, 6, 1); - vbox1->addWidget(no_pass_phrase_check_box_, 6, 2); + vbox1->addWidget(no_pass_phrase_check_box_, 6, 1); - auto basicInfoGroupBox = new QGroupBox(); - basicInfoGroupBox->setLayout(vbox1); - basicInfoGroupBox->setTitle(_("Basic Information")); + auto* basic_info_group_box = new QGroupBox(); + basic_info_group_box->setLayout(vbox1); + basic_info_group_box->setTitle(_("Basic Information")); - return basicInfoGroupBox; + return basic_info_group_box; } } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/KeygenDialog.h b/src/ui/dialog/key_generate/KeygenDialog.h index 0debae68..e4feb7a3 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.h +++ b/src/ui/dialog/key_generate/KeygenDialog.h @@ -28,8 +28,10 @@ #pragma once -#include "core/function/gpg/GpgContext.h" +#include <memory> + #include "core/model/GpgGenKeyInfo.h" +#include "core/utils/MemoryUtils.h" #include "ui/GpgFrontendUI.h" #include "ui/dialog/GeneralDialog.h" @@ -87,24 +89,22 @@ class KeyGenDialog : public GeneralDialog { */ QStringList error_messages_; ///< List of errors occurring when checking ///< entries of line edits - std::unique_ptr<GenKeyInfo> gen_key_info_ = - std::make_unique<GenKeyInfo>(); ///< - QDialogButtonBox* button_box_; ///< Box for standard buttons - QLabel* error_label_{}; ///< Label containing error message - QLineEdit* name_edit_{}; ///< Line edit for the keys name - QLineEdit* email_edit_{}; ///< Line edit for the keys email - QLineEdit* comment_edit_{}; ///< Line edit for the keys comment - QLineEdit* passphrase_edit_{}; ///< - QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) - QComboBox* key_type_combo_box_{}; ///< Combobox for Key type - QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date - QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire + std::shared_ptr<GenKeyInfo> gen_key_info_ = + SecureCreateSharedObject<GenKeyInfo>(); ///< + QDialogButtonBox* button_box_; ///< Box for standard buttons + QLabel* error_label_{}; ///< Label containing error message + QLineEdit* name_edit_{}; ///< Line edit for the keys name + QLineEdit* email_edit_{}; ///< Line edit for the keys email + QLineEdit* comment_edit_{}; ///< Line edit for the keys comment + QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) + QComboBox* key_type_combo_box_{}; ///< Combobox for Key type + QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date + QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire QCheckBox* no_pass_phrase_check_box_{}; QGroupBox* key_usage_group_box_{}; ///< Group of Widgets detecting the usage ///< of the Key QDateTime max_date_time_; ///< std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH - bool use_pinentry_ = false; /** * @brief diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp index d0fac22c..9a4b9f6d 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp @@ -28,15 +28,16 @@ #include "SubkeyGenerateDialog.h" +#include <boost/format/format_fwd.hpp> #include <cassert> #include <cstddef> #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyOpera.h" -#include "core/utils/CacheUtils.h" #include "core/utils/GpgUtils.h" #include "ui/UISignalStation.h" +#include "ui/UserInterfaceUtils.h" #include "ui/dialog/WaitingDialog.h" namespace GpgFrontend::UI { @@ -48,12 +49,6 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent) GlobalSettingStation::GetInstance().LookupSettings( "general.longer_expiration_date", false); - bool use_pinentry_as_password_input_dialog = - GlobalSettingStation::GetInstance().LookupSettings( - "general.use_pinentry_as_password_input_dialog", false); - - use_pinentry_ = use_pinentry_as_password_input_dialog; - max_date_time_ = longer_expiration_date ? QDateTime::currentDateTime().toLocalTime().addYears(30) : QDateTime::currentDateTime().toLocalTime().addYears(2); @@ -84,30 +79,26 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent) this->setLayout(vbox2); this->setModal(true); - connect(this, &SubkeyGenerateDialog::SignalSubKeyGenerated, - UISignalStation::GetInstance(), - &UISignalStation::SignalKeyDatabaseRefresh); - set_signal_slot(); refresh_widgets_state(); } QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() { - auto* groupBox = new QGroupBox(this); + auto* group_box = new QGroupBox(this); auto* grid = new QGridLayout(this); - groupBox->setTitle(_("Key Usage")); + group_box->setTitle(_("Key Usage")); - auto* encrypt = new QCheckBox(_("Encryption"), groupBox); + auto* encrypt = new QCheckBox(_("Encryption"), group_box); encrypt->setTristate(false); - auto* sign = new QCheckBox(_("Signing"), groupBox); + auto* sign = new QCheckBox(_("Signing"), group_box); sign->setTristate(false); - auto* cert = new QCheckBox(_("Certification"), groupBox); + auto* cert = new QCheckBox(_("Certification"), group_box); cert->setTristate(false); - auto* auth = new QCheckBox(_("Authentication"), groupBox); + auto* auth = new QCheckBox(_("Authentication"), group_box); auth->setTristate(false); key_usage_check_boxes_.push_back(encrypt); @@ -120,9 +111,9 @@ QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() { grid->addWidget(cert, 1, 0); grid->addWidget(auth, 1, 1); - groupBox->setLayout(grid); + group_box->setLayout(grid); - return groupBox; + return group_box; } QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { @@ -130,9 +121,8 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { key_size_spin_box_ = new QSpinBox(this); key_type_combo_box_ = new QComboBox(this); no_pass_phrase_check_box_ = new QCheckBox(this); - passphrase_edit_ = new QLineEdit(this); - for (auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) { + for (const auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) { key_type_combo_box_->addItem(QString::fromStdString(algo.first)); } if (!GenKeyInfo::GetSupportedSubkeyAlgo().empty()) { @@ -150,31 +140,25 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { expire_check_box_ = new QCheckBox(this); expire_check_box_->setCheckState(Qt::Unchecked); - passphrase_edit_->setEchoMode(QLineEdit::Password); - passphrase_edit_->setHidden(use_pinentry_); - auto* vbox1 = new QGridLayout; vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 0, 0); vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0); vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 2, 0); vbox1->addWidget(new QLabel(QString(_("Never Expire"))), 2, 3); - if (!use_pinentry_) - vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 3, 0); - vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 3, 3); + vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 3, 0); vbox1->addWidget(key_type_combo_box_, 0, 1); vbox1->addWidget(key_size_spin_box_, 1, 1); vbox1->addWidget(date_edit_, 2, 1); vbox1->addWidget(expire_check_box_, 2, 2); - if (!use_pinentry_) vbox1->addWidget(passphrase_edit_, 3, 1); - vbox1->addWidget(no_pass_phrase_check_box_, 3, 2); + vbox1->addWidget(no_pass_phrase_check_box_, 3, 1); - auto basicInfoGroupBox = new QGroupBox(); - basicInfoGroupBox->setLayout(vbox1); - basicInfoGroupBox->setTitle(_("Basic Information")); + auto* basic_info_group_box = new QGroupBox(); + basic_info_group_box->setLayout(vbox1); + basic_info_group_box->setTitle(_("Basic Information")); - return basicInfoGroupBox; + return basic_info_group_box; } void SubkeyGenerateDialog::set_signal_slot() { @@ -201,12 +185,11 @@ void SubkeyGenerateDialog::set_signal_slot() { connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, [this](int state) -> void { gen_key_info_->SetNonPassPhrase(state != 0); - passphrase_edit_->setDisabled(state != 0); }); } void SubkeyGenerateDialog::slot_expire_box_changed() { - if (expire_check_box_->checkState()) { + if (expire_check_box_->checkState() != 0U) { date_edit_->setEnabled(false); } else { date_edit_->setEnabled(true); @@ -214,45 +197,53 @@ void SubkeyGenerateDialog::slot_expire_box_changed() { } void SubkeyGenerateDialog::refresh_widgets_state() { - if (gen_key_info_->IsAllowEncryption()) + if (gen_key_info_->IsAllowEncryption()) { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeEncryption()) + if (gen_key_info_->IsAllowChangeEncryption()) { key_usage_check_boxes_[0]->setDisabled(false); - else + } else { key_usage_check_boxes_[0]->setDisabled(true); + } - if (gen_key_info_->IsAllowSigning()) + if (gen_key_info_->IsAllowSigning()) { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeSigning()) + if (gen_key_info_->IsAllowChangeSigning()) { key_usage_check_boxes_[1]->setDisabled(false); - else + } else { key_usage_check_boxes_[1]->setDisabled(true); + } - if (gen_key_info_->IsAllowCertification()) + if (gen_key_info_->IsAllowCertification()) { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeCertification()) + if (gen_key_info_->IsAllowChangeCertification()) { key_usage_check_boxes_[2]->setDisabled(false); - else + } else { key_usage_check_boxes_[2]->setDisabled(true); + } - if (gen_key_info_->IsAllowAuthentication()) + if (gen_key_info_->IsAllowAuthentication()) { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked); - else + } else { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked); + } - if (gen_key_info_->IsAllowChangeAuthentication()) + if (gen_key_info_->IsAllowChangeAuthentication()) { key_usage_check_boxes_[3]->setDisabled(false); - else + } else { key_usage_check_boxes_[3]->setDisabled(true); + } key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), gen_key_info_->GetSuggestMaxKeySize()); @@ -271,17 +262,12 @@ void SubkeyGenerateDialog::slot_key_gen_accept() { err_stream << " " << _("Expiration time no more than 2 years.") << " "; } - if (!use_pinentry_ && passphrase_edit_->isEnabled() && - passphrase_edit_->text().size() == 0) { - err_stream << " " << _("Password is empty.") << std::endl; - } - auto err_string = err_stream.str(); if (err_string.empty()) { gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - if (expire_check_box_->checkState()) { + if (expire_check_box_->checkState() != 0U) { gen_key_info_->SetNonExpired(true); } else { #ifdef GPGFRONTEND_GUI_QT6 @@ -293,45 +279,22 @@ void SubkeyGenerateDialog::slot_key_gen_accept() { #endif } - if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) { - SetTempCacheValue("__key_passphrase", - this->passphrase_edit_->text().toStdString()); - } - - GpgError error; - // TODO: remove plain qt thread usage - auto thread = QThread::create([&]() { - SPDLOG_DEBUG("thread started"); - error = GpgKeyOpera::GetInstance().GenerateSubkey(key_, gen_key_info_); - }); - thread->start(); - - auto* waiting_dialog = new WaitingDialog(_("Generating"), this); - waiting_dialog->show(); - - while (thread->isRunning()) { - QCoreApplication::processEvents(); - } - waiting_dialog->close(); - - if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) { - ResetTempCacheValue("__key_passphrase"); - } - - if (CheckGpgError(error) == GPG_ERR_NO_ERROR) { - auto* msg_box = new QMessageBox(qobject_cast<QWidget*>(this->parent())); - msg_box->setAttribute(Qt::WA_DeleteOnClose); - msg_box->setStandardButtons(QMessageBox::Ok); - msg_box->setWindowTitle(_("Success")); - msg_box->setText(_("The new subkey has been generated.")); - msg_box->setModal(true); - msg_box->open(); - - emit SignalSubKeyGenerated(); - this->close(); - } else { - QMessageBox::critical(this, _("Failure"), _("Failed to generate key.")); - } + CommonUtils::WaitForOpera( + this, _("Generating"), + [this, key = this->key_, + gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) { + GpgKeyOpera::GetInstance().GenerateSubkey( + key, gen_key_info, + [this, hd](GpgError err, const DataObjectPtr&) { + GpgGenKeyResult result; + CommonUtils::RaiseMessageBox(this, err); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + emit UISignalStation::GetInstance() + ->SignalKeyDatabaseRefresh(); + } + hd(); + }); + }); } else { /** diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h index 9a121286..be39669c 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h @@ -28,10 +28,13 @@ #pragma once +#include <memory> + #include "core/function/gpg/GpgContext.h" #include "core/model/GpgGenKeyInfo.h" #include "core/model/GpgKey.h" #include "core/typedef/GpgTypedef.h" +#include "core/utils/MemoryUtils.h" #include "ui/GpgFrontendUI.h" #include "ui/dialog/GeneralDialog.h" @@ -52,18 +55,11 @@ class SubkeyGenerateDialog : public GeneralDialog { */ explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent); - signals: - /** - * @brief - * - */ - void SignalSubKeyGenerated(); - private: GpgKey key_; ///< - std::unique_ptr<GenKeyInfo> gen_key_info_ = - std::make_unique<GenKeyInfo>(true); ///< + std::shared_ptr<GenKeyInfo> gen_key_info_ = + SecureCreateSharedObject<GenKeyInfo>(true); ///< QGroupBox* key_usage_group_box_{}; QDialogButtonBox* button_box_; ///< Box for standard buttons @@ -73,11 +69,9 @@ class SubkeyGenerateDialog : public GeneralDialog { QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire QCheckBox* no_pass_phrase_check_box_{}; ///< Checkbox, if key should expire - QLineEdit* passphrase_edit_{}; std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH QDateTime max_date_time_; ///< - bool use_pinentry_ = false; /** * @brief Create a key usage group box object diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp index 6f1bde9c..f7a8fb62 100644 --- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp @@ -306,7 +306,7 @@ void KeyPairOperaTab::slot_export_private_key() { } void KeyPairOperaTab::slot_modify_edit_datetime() { - auto dialog = new KeySetExpireDateDialog(m_key_.GetId(), this); + auto* dialog = new KeySetExpireDateDialog(m_key_.GetId(), this); dialog->show(); } @@ -330,8 +330,16 @@ void KeyPairOperaTab::slot_gen_revoke_cert() { auto literal = QString("%1 (*.rev)").arg(_("Revocation Certificates")); QString m_output_file_name; - QFileDialog dialog(this, "Generate revocation certificate", QString(), - literal); +#ifndef WINDOWS + auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" + + m_key_.GetId() + ").rev"; +#else + auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" + + m_key_.GetId() + ").rev"; +#endif + + QFileDialog dialog(this, "Generate revocation certificate", + QString::fromStdString(file_string), literal); dialog.setDefaultSuffix(".rev"); dialog.setAcceptMode(QFileDialog::AcceptSave); @@ -344,12 +352,14 @@ void KeyPairOperaTab::slot_gen_revoke_cert() { } void KeyPairOperaTab::slot_modify_password() { - GpgKeyOpera::GetInstance().ModifyPassword(m_key_, [this](GpgError err) { - if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { - QMessageBox::critical(this, _("Not Successful"), - QString(_("Modify password not successfully."))); - } - }); + GpgKeyOpera::GetInstance().ModifyPassword( + m_key_, [this](GpgError err, const DataObjectPtr&) { + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + QMessageBox::critical( + this, _("Not Successful"), + QString(_("Modify password not successfully."))); + } + }); } void KeyPairOperaTab::slot_modify_tofu_policy() { diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp index 969381bc..7730b25b 100644 --- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp +++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp @@ -42,7 +42,8 @@ namespace GpgFrontend::UI { KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, QWidget* parent) : GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent), - ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()), + ui_(GpgFrontend::SecureCreateSharedObject< + Ui_ModifiedExpirationDateTime>()), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { init(); } @@ -51,7 +52,8 @@ KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, std::string subkey_fpr, QWidget* parent) : GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent), - ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()), + ui_(GpgFrontend::SecureCreateSharedObject< + Ui_ModifiedExpirationDateTime>()), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)), m_subkey_(std::move(subkey_fpr)) { init(); diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp index 0d4f2b19..84d79f17 100644 --- a/src/ui/dialog/settings/SettingsAppearance.cpp +++ b/src/ui/dialog/settings/SettingsAppearance.cpp @@ -35,7 +35,8 @@ namespace GpgFrontend::UI { AppearanceTab::AppearanceTab(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_AppearanceSettings>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_AppearanceSettings>()) { ui_->setupUi(this); ui_->iconSizeBox->setTitle(_("Icon Size")); diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp index 25c318a3..eb698468 100644 --- a/src/ui/dialog/settings/SettingsGeneral.cpp +++ b/src/ui/dialog/settings/SettingsGeneral.cpp @@ -43,7 +43,8 @@ namespace GpgFrontend::UI { GeneralTab::GeneralTab(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_GeneralSettings>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_GeneralSettings>()) { ui_->setupUi(this); ui_->cacheBox->setTitle(_("Cache")); diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp index 7905192d..784721bf 100644 --- a/src/ui/dialog/settings/SettingsKeyServer.cpp +++ b/src/ui/dialog/settings/SettingsKeyServer.cpp @@ -40,7 +40,8 @@ namespace GpgFrontend::UI { KeyserverTab::KeyserverTab(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_KeyServerSettings>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyServerSettings>()) { ui_->setupUi(this); ui_->keyServerListTable->setSizeAdjustPolicy( QAbstractScrollArea::AdjustToContents); diff --git a/src/ui/dialog/settings/SettingsNetwork.cpp b/src/ui/dialog/settings/SettingsNetwork.cpp index 83b97ed2..46941062 100644 --- a/src/ui/dialog/settings/SettingsNetwork.cpp +++ b/src/ui/dialog/settings/SettingsNetwork.cpp @@ -33,7 +33,8 @@ #include "ui_NetworkSettings.h" GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent) - : QWidget(parent), ui_(std::make_shared<Ui_NetworkSettings>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_NetworkSettings>()) { ui_->setupUi(this); connect(ui_->enableProxyCheckBox, &QCheckBox::stateChanged, this, diff --git a/src/ui/function/GenerateRevokeCertification.cpp b/src/ui/function/GenerateRevokeCertification.cpp new file mode 100644 index 00000000..7d37e006 --- /dev/null +++ b/src/ui/function/GenerateRevokeCertification.cpp @@ -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 + * + */ + +#include "GenerateRevokeCertification.h" + +#include "core/function/gpg/GpgCommandExecutor.h" +#include "core/model/GpgKey.h" +#include "core/module/ModuleManager.h" + +namespace GpgFrontend::UI { + +GenerateRevokeCertification::GenerateRevokeCertification(QWidget* parent) + : QWidget(parent) {} + +auto GenerateRevokeCertification::Exec(const GpgKey& key, + const std::string& output_path) -> int { + const auto app_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.app_path", std::string{}); + // get all components + GpgCommandExecutor::ExecuteSync( + {app_path, + {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", + std::move(output_path), "--gen-revoke", key.GetFingerprint()}, + [=](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()); + } + }, + nullptr, + [](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"); + } + } + }}); +} + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/function/GenerateRevokeCertification.h b/src/ui/function/GenerateRevokeCertification.h new file mode 100644 index 00000000..0269a8a7 --- /dev/null +++ b/src/ui/function/GenerateRevokeCertification.h @@ -0,0 +1,44 @@ +/** + * 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/GpgModel.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class GenerateRevokeCertification : public QWidget { + Q_OBJECT + public: + explicit GenerateRevokeCertification(QWidget* parent); + + auto Exec(const GpgKey& key, const std::string& output_path) -> int; +}; + +} // namespace GpgFrontend::UI diff --git a/src/ui/function/RaisePinentry.cpp b/src/ui/function/RaisePinentry.cpp index 7ed98b93..65bae527 100644 --- a/src/ui/function/RaisePinentry.cpp +++ b/src/ui/function/RaisePinentry.cpp @@ -28,6 +28,8 @@ #include "RaisePinentry.h" +#include <qwidget.h> + #include "core/function/CoreSignalStation.h" #include "pinentry/pinentrydialog.h" @@ -43,7 +45,6 @@ auto RaisePinentry::Exec() -> int { SPDLOG_DEBUG("setting pinetry's arguments"); - pinentry->setPinentryInfo(new struct pinentry()); pinentry->setPrompt(QString::fromStdString(_("PIN:"))); pinentry->setDescription(QString()); pinentry->setRepeatErrorText( @@ -65,7 +66,7 @@ auto RaisePinentry::Exec() -> int { connect(pinentry, &PinEntryDialog::finished, this, [pinentry](int result) { bool ret = result != 0; - SPDLOG_DEBUG("PinEntryDialog finished, ret: {}", ret); + SPDLOG_DEBUG("pinentry finished, ret: {}", ret); if (!ret) { emit CoreSignalStation::GetInstance()->SignalUserInputPassphraseCallback( @@ -78,7 +79,9 @@ auto RaisePinentry::Exec() -> int { pin); return 0; }); + connect(pinentry, &PinEntryDialog::finished, this, &QWidget::deleteLater); pinentry->open(); + return 0; } } // namespace GpgFrontend::UI diff --git a/src/ui/function/RaisePinentry.h b/src/ui/function/RaisePinentry.h index b950d2b9..7cb0c2a1 100644 --- a/src/ui/function/RaisePinentry.h +++ b/src/ui/function/RaisePinentry.h @@ -28,10 +28,11 @@ #pragma once -#include <qwidget.h> +#include "ui/GpgFrontendUI.h" + namespace GpgFrontend::UI { -class RaisePinentry : QWidget { +class RaisePinentry : public QWidget { Q_OBJECT public: explicit RaisePinentry(QWidget *parent); diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 8998024f..7d0833c6 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -112,7 +112,7 @@ void MainWindow::slot_encrypt() { auto buffer = ExtractParams<std::string>(data_object, 0); try { GpgEncrResult result = nullptr; - auto tmp = std::make_shared<ByteArray>(); + auto tmp = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric( buffer, tmp, result); @@ -154,7 +154,7 @@ void MainWindow::slot_encrypt() { auto keys = ExtractParams<KeyListPtr>(data_object, 1); try { GpgEncrResult result = nullptr; - auto tmp = std::make_shared<ByteArray>(); + auto tmp = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt( std::move(keys), buffer, tmp, result); @@ -220,7 +220,7 @@ void MainWindow::slot_sign() { try { GpgSignResult result = nullptr; - auto tmp = std::make_shared<ByteArray>(); + auto tmp = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Sign( std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result); @@ -275,7 +275,7 @@ void MainWindow::slot_decrypt() { auto buffer = ExtractParams<std::string>(data_object, 0); try { GpgDecrResult result = nullptr; - auto decrypted = std::make_shared<ByteArray>(); + auto decrypted = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt( buffer, decrypted, result); @@ -444,7 +444,7 @@ void MainWindow::slot_encrypt_sign() { try { GpgEncrResult encr_result = nullptr; GpgSignResult sign_result = nullptr; - auto tmp = std::make_shared<ByteArray>(); + auto tmp = GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign( std::move(keys), std::move(signer_keys), buffer, tmp, encr_result, sign_result); @@ -511,7 +511,8 @@ void MainWindow::slot_decrypt_verify() { try { GpgDecrResult decrypt_result = nullptr; GpgVerifyResult verify_result = nullptr; - auto decrypted_buffer = std::make_shared<ByteArray>(); + auto decrypted_buffer = + GpgFrontend::SecureCreateSharedObject<ByteArray>(); GpgError error = GpgBasicOperator::GetInstance().DecryptVerify( buffer, decrypted_buffer, decrypt_result, verify_result); @@ -583,7 +584,7 @@ void MainWindow::slot_append_selected_keys() { return; } - auto exported = std::make_shared<ByteArray>(); + auto exported = GpgFrontend::SecureCreateSharedObject<ByteArray>(); auto key_ids = m_key_list_->GetSelected(); if (key_ids->empty()) { diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 65ead3ce..e0459955 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -229,8 +229,8 @@ void MainWindow::SetCryptoMenuStatus( } void MainWindow::SlotRaisePinentry() { - auto function = RaisePinentry(this); - function.Exec(); + auto* function = new RaisePinentry(this); + function->Exec(); } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index 073bd978..9f254ff8 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -40,7 +40,8 @@ namespace GpgFrontend::UI { FilePage::FilePage(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_FilePage>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_FilePage>()) { ui_->setupUi(this); first_parent_ = parent; diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 735ed7ba..c3369ff8 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -37,7 +37,8 @@ namespace GpgFrontend::UI { InfoBoardWidget::InfoBoardWidget(QWidget* parent) - : QWidget(parent), ui_(std::make_shared<Ui_InfoBoard>()) { + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_InfoBoard>()) { ui_->setupUi(this); ui_->actionButtonLayout->addStretch(); diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 751548ec..0e4bba5e 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -45,7 +45,7 @@ namespace GpgFrontend::UI { KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent) : QWidget(parent), - ui_(std::make_shared<Ui_KeyList>()), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyList>()), menu_ability_(menu_ability) { init(); } diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp index fa7e138b..1685e0e2 100644 --- a/src/ui/widgets/PlainTextEditorPage.cpp +++ b/src/ui/widgets/PlainTextEditorPage.cpp @@ -44,7 +44,7 @@ namespace GpgFrontend::UI { PlainTextEditorPage::PlainTextEditorPage(QString file_path, QWidget *parent) : QWidget(parent), - ui_(std::make_shared<Ui_PlainTextEditor>()), + ui_(GpgFrontend::SecureCreateSharedObject<Ui_PlainTextEditor>()), full_file_path_(std::move(file_path)) { ui_->setupUi(this); |