feat: standarized and speed up app env loading process
This commit is contained in:
parent
d0602f0956
commit
054e6e28cc
26
src/app.cpp
26
src/app.cpp
@ -79,7 +79,7 @@ auto StartApplication(InitArgs args) -> int {
|
|||||||
args.argc, args.argv, true);
|
args.argc, args.argv, true);
|
||||||
|
|
||||||
// init the logging system for main
|
// init the logging system for main
|
||||||
InitModules(args);
|
InitLoggingSystem(args);
|
||||||
|
|
||||||
// change path to search for related
|
// change path to search for related
|
||||||
InitGlobalPathEnv();
|
InitGlobalPathEnv();
|
||||||
@ -98,10 +98,18 @@ auto StartApplication(InitArgs args) -> int {
|
|||||||
int r = setjmp(recover_env);
|
int r = setjmp(recover_env);
|
||||||
#endif
|
#endif
|
||||||
if (!r) {
|
if (!r) {
|
||||||
// init ui library
|
// should load module system first
|
||||||
|
GpgFrontend::Module::ModuleInitArgs module_init_args;
|
||||||
|
module_init_args.log_level = args.log_level;
|
||||||
|
GpgFrontend::Module::LoadGpgFrontendModules(module_init_args);
|
||||||
|
|
||||||
|
// then load core
|
||||||
|
GpgFrontend::InitGpgFrontendCore();
|
||||||
|
|
||||||
|
// after that load ui library
|
||||||
GpgFrontend::UI::InitGpgFrontendUI(app);
|
GpgFrontend::UI::InitGpgFrontendUI(app);
|
||||||
|
|
||||||
// create main window
|
// finally create main window
|
||||||
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
|
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
|
||||||
} else {
|
} else {
|
||||||
SPDLOG_ERROR("recover from a crash");
|
SPDLOG_ERROR("recover from a crash");
|
||||||
@ -117,6 +125,16 @@ auto StartApplication(InitArgs args) -> int {
|
|||||||
return_from_event_loop_code = kCrashCode;
|
return_from_event_loop_code = kCrashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_DEBUG("try to destroy modules system and core");
|
||||||
|
|
||||||
|
// first should shutdown the module system
|
||||||
|
GpgFrontend::Module::ShutdownGpgFrontendModules();
|
||||||
|
|
||||||
|
// then shutdown the core
|
||||||
|
GpgFrontend::DestroyGpgFrontendCore();
|
||||||
|
|
||||||
|
SPDLOG_DEBUG("core and modules system destroyed");
|
||||||
|
|
||||||
restart_count++;
|
restart_count++;
|
||||||
|
|
||||||
SPDLOG_DEBUG("restart loop refresh, event loop code: {}, restart count: {}",
|
SPDLOG_DEBUG("restart loop refresh, event loop code: {}, restart count: {}",
|
||||||
@ -125,7 +143,7 @@ auto StartApplication(InitArgs args) -> int {
|
|||||||
restart_count < 3);
|
restart_count < 3);
|
||||||
|
|
||||||
// close logging system
|
// close logging system
|
||||||
ShutdownModules();
|
ShutdownLoggingSystem();
|
||||||
|
|
||||||
// log for debug
|
// log for debug
|
||||||
SPDLOG_INFO("GpgFrontend is about to exit.");
|
SPDLOG_INFO("GpgFrontend is about to exit.");
|
||||||
|
15
src/cmd.cpp
15
src/cmd.cpp
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
// GpgFrontend
|
// GpgFrontend
|
||||||
#include "GpgFrontendBuildInfo.h"
|
#include "GpgFrontendBuildInfo.h"
|
||||||
|
#include "spdlog/common.h"
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
@ -61,13 +62,19 @@ auto ParseLogLevel(const po::variables_map& vm) -> spdlog::level::level_enum {
|
|||||||
|
|
||||||
if (log_level == "trace") {
|
if (log_level == "trace") {
|
||||||
return spdlog::level::trace;
|
return spdlog::level::trace;
|
||||||
} else if (log_level == "debug") {
|
}
|
||||||
|
if (log_level == "debug") {
|
||||||
return spdlog::level::debug;
|
return spdlog::level::debug;
|
||||||
} else if (log_level == "info") {
|
}
|
||||||
|
if (log_level == "info") {
|
||||||
return spdlog::level::info;
|
return spdlog::level::info;
|
||||||
} else if (log_level == "warn") {
|
}
|
||||||
|
if (log_level == "warn") {
|
||||||
return spdlog::level::warn;
|
return spdlog::level::warn;
|
||||||
} else if (log_level == "error") {
|
}
|
||||||
|
if (log_level == "error") {
|
||||||
return spdlog::level::err;
|
return spdlog::level::err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return spdlog::level::info;
|
||||||
}
|
}
|
@ -27,6 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "GpgCoreInit.h"
|
#include "GpgCoreInit.h"
|
||||||
|
|
||||||
|
#include <gpgme.h>
|
||||||
#include <spdlog/async.h>
|
#include <spdlog/async.h>
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/sinks/rotating_file_sink.h>
|
#include <spdlog/sinks/rotating_file_sink.h>
|
||||||
@ -35,15 +36,19 @@
|
|||||||
#include <boost/date_time.hpp>
|
#include <boost/date_time.hpp>
|
||||||
|
|
||||||
#include "core/function/GlobalSettingStation.h"
|
#include "core/function/GlobalSettingStation.h"
|
||||||
|
#include "core/function/basic/ChannelObject.h"
|
||||||
|
#include "core/function/basic/SingletonStorage.h"
|
||||||
#include "core/function/gpg/GpgAdvancedOperator.h"
|
#include "core/function/gpg/GpgAdvancedOperator.h"
|
||||||
#include "core/function/gpg/GpgContext.h"
|
#include "core/function/gpg/GpgContext.h"
|
||||||
#include "core/module/ModuleManager.h"
|
#include "core/module/ModuleManager.h"
|
||||||
#include "core/thread/Task.h"
|
#include "core/thread/Task.h"
|
||||||
#include "core/thread/TaskRunner.h"
|
#include "core/thread/TaskRunner.h"
|
||||||
#include "core/thread/TaskRunnerGetter.h"
|
#include "core/thread/TaskRunnerGetter.h"
|
||||||
|
#include "core/utils/CommonUtils.h"
|
||||||
|
#include "core/utils/GpgUtils.h"
|
||||||
#include "core/utils/MemoryUtils.h"
|
#include "core/utils/MemoryUtils.h"
|
||||||
#include "function/basic/ChannelObject.h"
|
#include "function/CoreSignalStation.h"
|
||||||
#include "function/basic/SingletonStorage.h"
|
#include "function/gpg/GpgKeyGetter.h"
|
||||||
|
|
||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
|
|
||||||
@ -99,123 +104,206 @@ void ShutdownCoreLoggingSystem() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
|
void DestroyGpgFrontendCore() {
|
||||||
|
SingletonStorageCollection::Destroy();
|
||||||
|
ShutdownCoreLoggingSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto InitGpgME() -> bool {
|
||||||
|
// init gpgme subsystem and get gpgme library version
|
||||||
|
Module::UpsertRTValue("core", "gpgme.version",
|
||||||
|
std::string(gpgme_check_version(nullptr)));
|
||||||
|
|
||||||
void InitGpgFrontendCore() {
|
|
||||||
/* 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));
|
gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
|
||||||
#ifdef LC_MESSAGES
|
#ifdef LC_MESSAGES
|
||||||
gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
|
gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// read settings
|
gpgme_ctx_t p_ctx;
|
||||||
bool forbid_all_gnupg_connection =
|
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
|
||||||
"network.forbid_all_gnupg_connection", false);
|
|
||||||
|
|
||||||
bool auto_import_missing_key =
|
CheckGpgError(gpgme_new(&p_ctx));
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
|
||||||
"network.auto_import_missing_key", false);
|
|
||||||
|
|
||||||
bool use_custom_key_database_path =
|
// get engine info
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
auto* engine_info = gpgme_ctx_get_engine_info(p_ctx);
|
||||||
"general.use_custom_key_database_path", false);
|
// Check ENV before running
|
||||||
|
bool find_openpgp = false;
|
||||||
|
bool find_gpgconf = false;
|
||||||
|
bool find_cms = false;
|
||||||
|
|
||||||
std::string custom_key_database_path =
|
while (engine_info != nullptr) {
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
if (strcmp(engine_info->version, "1.0.0") == 0) {
|
||||||
"general.custom_key_database_path", std::string{});
|
engine_info = engine_info->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool use_custom_gnupg_install_path =
|
SPDLOG_DEBUG(
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
"gpg context engine info: {} {} {} {}",
|
||||||
"general.use_custom_gnupg_install_path", false);
|
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));
|
||||||
|
|
||||||
std::string custom_gnupg_install_path =
|
switch (engine_info->protocol) {
|
||||||
GlobalSettingStation::GetInstance().LookupSettings(
|
case GPGME_PROTOCOL_OpenPGP:
|
||||||
"general.custom_gnupg_install_path", std::string{});
|
find_openpgp = true;
|
||||||
|
|
||||||
bool use_pinentry_as_password_input_dialog =
|
Module::UpsertRTValue("core", "gpgme.engine.openpgp", "1");
|
||||||
GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
|
Module::UpsertRTValue("core", "gpgme.ctx.app_path",
|
||||||
"general.use_pinentry_as_password_input_dialog", false);
|
std::string(engine_info->file_name));
|
||||||
|
Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
|
||||||
|
std::string(engine_info->version));
|
||||||
|
Module::UpsertRTValue("core", "gpgme.ctx.database_path",
|
||||||
|
std::string(engine_info->home_dir == nullptr
|
||||||
|
? "default"
|
||||||
|
: 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",
|
||||||
|
std::string(engine_info->file_name));
|
||||||
|
|
||||||
SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
|
break;
|
||||||
use_custom_key_database_path);
|
case GPGME_PROTOCOL_GPGCONF:
|
||||||
SPDLOG_DEBUG("core loaded custom key databse path: {}",
|
find_gpgconf = true;
|
||||||
custom_key_database_path);
|
|
||||||
|
|
||||||
// check gpgconf path
|
Module::UpsertRTValue("core", "gpgme.engine.gpgconf", "1");
|
||||||
std::filesystem::path custom_gnupg_install_fs_path =
|
Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
|
||||||
custom_gnupg_install_path;
|
std::string(engine_info->file_name));
|
||||||
|
break;
|
||||||
|
case GPGME_PROTOCOL_ASSUAN:
|
||||||
|
|
||||||
|
Module::UpsertRTValue("core", "gpgme.engine.assuan", "1");
|
||||||
|
Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
|
||||||
|
std::string(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
|
||||||
|
"core", "gpgme.ctx.gnupg_version", std::string{"0.0.0"});
|
||||||
|
SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
|
||||||
|
|
||||||
|
// conditional check: only support gpg 2.1.x now
|
||||||
|
if (!(CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
|
||||||
|
find_openpgp && find_cms)) {
|
||||||
|
SPDLOG_ERROR("gpgme env check failed, abort");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Module::UpsertRTValue("core", "env.state.gpgme", std::string{"1"});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitGpgFrontendCore() {
|
||||||
|
// initialize global register table
|
||||||
|
Module::UpsertRTValue("core", "env.state.gpgme", std::string{"0"});
|
||||||
|
Module::UpsertRTValue("core", "env.state.ctx", std::string{"0"});
|
||||||
|
Module::UpsertRTValue("core", "env.state.gnupg", std::string{"0"});
|
||||||
|
Module::UpsertRTValue("core", "env.state.basic", std::string{"0"});
|
||||||
|
Module::UpsertRTValue("core", "env.state.all", std::string{"0"});
|
||||||
|
|
||||||
|
// initialize locale environment
|
||||||
|
SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
|
||||||
|
|
||||||
|
// initialize library gpgme
|
||||||
|
if (!InitGpgME()) {
|
||||||
|
CoreSignalStation::GetInstance()->SignalBadGnupgEnv();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the thread to check ctx and gnupg state
|
||||||
|
// it may take a few seconds or minutes
|
||||||
|
GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
|
||||||
|
.GetTaskRunner()
|
||||||
|
->PostTask(new Thread::Task(
|
||||||
|
[](const DataObjectPtr&) -> int {
|
||||||
|
// read settings from config file
|
||||||
|
auto forbid_all_gnupg_connection =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"network.forbid_all_gnupg_connection", false);
|
||||||
|
|
||||||
|
auto auto_import_missing_key =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"network.auto_import_missing_key", false);
|
||||||
|
|
||||||
|
auto use_custom_key_database_path =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"general.use_custom_key_database_path", false);
|
||||||
|
|
||||||
|
auto custom_key_database_path =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"general.custom_key_database_path", std::string{});
|
||||||
|
|
||||||
|
auto use_custom_gnupg_install_path =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"general.use_custom_gnupg_install_path", false);
|
||||||
|
|
||||||
|
auto custom_gnupg_install_path =
|
||||||
|
GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"general.custom_gnupg_install_path", std::string{});
|
||||||
|
|
||||||
|
auto use_pinentry_as_password_input_dialog =
|
||||||
|
GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
|
||||||
|
"general.use_pinentry_as_password_input_dialog", false);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// check gpgconf path
|
||||||
|
std::filesystem::path custom_gnupg_install_fs_path =
|
||||||
|
custom_gnupg_install_path;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
custom_gnupg_install_fs_path /= "gpgconf.exe";
|
custom_gnupg_install_fs_path /= "gpgconf.exe";
|
||||||
#else
|
#else
|
||||||
custom_gnupg_install_fs_path /= "gpgconf";
|
custom_gnupg_install_fs_path /= "gpgconf";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!custom_gnupg_install_fs_path.is_absolute() ||
|
if (!custom_gnupg_install_fs_path.is_absolute() ||
|
||||||
!std::filesystem::exists(custom_gnupg_install_fs_path) ||
|
!std::filesystem::exists(custom_gnupg_install_fs_path) ||
|
||||||
!std::filesystem::is_regular_file(custom_gnupg_install_fs_path)) {
|
!std::filesystem::is_regular_file(
|
||||||
use_custom_gnupg_install_path = false;
|
custom_gnupg_install_fs_path)) {
|
||||||
SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
|
use_custom_gnupg_install_path = false;
|
||||||
custom_gnupg_install_fs_path.u8string());
|
SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
|
||||||
} else {
|
custom_gnupg_install_fs_path.u8string());
|
||||||
SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
|
} else {
|
||||||
custom_gnupg_install_fs_path.u8string());
|
SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
|
||||||
}
|
custom_gnupg_install_fs_path.u8string());
|
||||||
|
}
|
||||||
|
|
||||||
// check key database path
|
// check key database path
|
||||||
std::filesystem::path custom_key_database_fs_path = custom_key_database_path;
|
std::filesystem::path custom_key_database_fs_path =
|
||||||
if (!custom_key_database_fs_path.is_absolute() ||
|
custom_key_database_path;
|
||||||
!std::filesystem::exists(custom_key_database_fs_path) ||
|
if (!custom_key_database_fs_path.is_absolute() ||
|
||||||
!std::filesystem::is_directory(custom_key_database_fs_path)) {
|
!std::filesystem::exists(custom_key_database_fs_path) ||
|
||||||
use_custom_key_database_path = false;
|
!std::filesystem::is_directory(custom_key_database_fs_path)) {
|
||||||
SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
|
use_custom_key_database_path = false;
|
||||||
custom_key_database_fs_path.u8string());
|
SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
|
||||||
} else {
|
custom_key_database_fs_path.u8string());
|
||||||
SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
|
} else {
|
||||||
custom_key_database_fs_path.u8string());
|
SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
|
||||||
}
|
custom_key_database_fs_path.u8string());
|
||||||
|
}
|
||||||
|
|
||||||
// init default channel
|
// init ctx, also checking the basical env
|
||||||
auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
|
|
||||||
kGpgfrontendDefaultChannel, [=]() -> ChannelObjectPtr {
|
|
||||||
GpgFrontend::GpgContextInitArgs args;
|
|
||||||
|
|
||||||
// set key database path
|
|
||||||
if (use_custom_key_database_path && !custom_key_database_path.empty()) {
|
|
||||||
args.db_path = custom_key_database_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>(
|
|
||||||
args, kGpgFrontendDefaultChannel));
|
|
||||||
});
|
|
||||||
|
|
||||||
// exit if failed
|
|
||||||
if (!default_ctx.Good()) {
|
|
||||||
SPDLOG_ERROR("default gnupg context init error");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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(
|
auto& ctx = GpgFrontend::GpgContext::CreateInstance(
|
||||||
kGpgfrontendNonAsciiChannel, [=]() -> ChannelObjectPtr {
|
kGpgfrontendDefaultChannel, [=]() -> ChannelObjectPtr {
|
||||||
GpgFrontend::GpgContextInitArgs args;
|
GpgFrontend::GpgContextInitArgs args;
|
||||||
args.ascii = false;
|
|
||||||
|
|
||||||
// set key database path
|
// set key database path
|
||||||
if (use_custom_key_database_path &&
|
if (use_custom_key_database_path &&
|
||||||
@ -223,6 +311,7 @@ void InitGpgFrontendCore() {
|
|||||||
args.db_path = custom_key_database_path;
|
args.db_path = custom_key_database_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set custom gnupg path
|
||||||
if (use_custom_gnupg_install_path) {
|
if (use_custom_gnupg_install_path) {
|
||||||
args.custom_gpgconf = true;
|
args.custom_gpgconf = true;
|
||||||
args.custom_gpgconf_path =
|
args.custom_gpgconf_path =
|
||||||
@ -235,31 +324,68 @@ void InitGpgFrontendCore() {
|
|||||||
|
|
||||||
return ConvertToChannelObjectPtr<>(
|
return ConvertToChannelObjectPtr<>(
|
||||||
SecureCreateUniqueObject<GpgContext>(
|
SecureCreateUniqueObject<GpgContext>(
|
||||||
args, kGpgfrontendNonAsciiChannel));
|
args, kGpgFrontendDefaultChannel));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!ctx.Good()) SPDLOG_ERROR("no-ascii channel init error");
|
// exit if failed
|
||||||
return ctx.Good() ? 0 : -1;
|
if (!ctx.Good()) {
|
||||||
},
|
SPDLOG_ERROR("default gnupg context init error, abort");
|
||||||
"default_channel_ctx_init"));
|
CoreSignalStation::GetInstance()->SignalBadGnupgEnv();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Module::UpsertRTValue("core", "env.state.ctx", std::string{"1"});
|
||||||
|
|
||||||
Module::TriggerEvent(
|
// if gnupg-info-gathering module activated
|
||||||
"GPGFRONTEND_CORE_INITLIZED",
|
if (Module::IsModuleAcivate("com.bktus.gpgfrontend.module."
|
||||||
[](const Module::EventIdentifier& /*e*/,
|
"integrated.gnupg-info-gathering")) {
|
||||||
const Module::Event::ListenerIdentifier& l_id, DataObjectPtr o) {
|
SPDLOG_DEBUG("gnupg-info-gathering is activated");
|
||||||
if (l_id ==
|
|
||||||
"com.bktus.gpgfrontend.module.integrated."
|
// gather external gnupg info
|
||||||
"gnupginfogathering") {
|
Module::TriggerEvent(
|
||||||
SPDLOG_DEBUG(
|
"GPGFRONTEND_CORE_INITLIZED",
|
||||||
"gnupg-info-gathering gnupg.gathering_done changed, restarting "
|
[](const Module::EventIdentifier& /*e*/,
|
||||||
"gpg "
|
const Module::Event::ListenerIdentifier& l_id,
|
||||||
"components");
|
DataObjectPtr o) {
|
||||||
// try to restart all components
|
SPDLOG_DEBUG(
|
||||||
GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
|
"received event GPGFRONTEND_CORE_INITLIZED callback "
|
||||||
}
|
"from module: {}",
|
||||||
});
|
l_id);
|
||||||
|
|
||||||
|
if (l_id ==
|
||||||
|
"com.bktus.gpgfrontend.module.integrated.gnupg-info-"
|
||||||
|
"gathering") {
|
||||||
|
SPDLOG_DEBUG(
|
||||||
|
"received callback from gnupg-info-gathering ");
|
||||||
|
|
||||||
|
// try to restart all components
|
||||||
|
GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
|
||||||
|
Module::UpsertRTValue("core", "env.state.gnupg",
|
||||||
|
std::string{"1"});
|
||||||
|
|
||||||
|
// announce that all checkings were finished
|
||||||
|
SPDLOG_INFO(
|
||||||
|
"all env checking finished, including gpgme, "
|
||||||
|
"ctx and "
|
||||||
|
"gnupg");
|
||||||
|
Module::UpsertRTValue("core", "env.state.all",
|
||||||
|
std::string{"1"});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
SPDLOG_DEBUG("gnupg-info-gathering is not activated");
|
||||||
|
Module::UpsertRTValue("core", "env.state.all", std::string{"1"});
|
||||||
|
}
|
||||||
|
|
||||||
|
GpgKeyGetter::GetInstance().FlushKeyCache();
|
||||||
|
SPDLOG_INFO(
|
||||||
|
"basic env checking finished, including gpgme, ctx, and key "
|
||||||
|
"infos");
|
||||||
|
Module::UpsertRTValue("core", "env.state.basic", std::string{"1"});
|
||||||
|
CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
"core_init_task"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); }
|
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
@ -49,7 +49,7 @@ void GPGFRONTEND_CORE_EXPORT ShutdownCoreLoggingSystem();
|
|||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
|
void GPGFRONTEND_CORE_EXPORT DestroyGpgFrontendCore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
@ -57,10 +57,4 @@ void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
|
|||||||
*/
|
*/
|
||||||
void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore();
|
void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void reset_gpgfrontend_core();
|
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
||||||
|
@ -66,7 +66,13 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
|
|||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SignalGnupgNotInstall();
|
void SignalBadGnupgEnv();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SignalGoodGnupgEnv();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
||||||
|
@ -79,7 +79,7 @@ class SingletonFunctionObject : public ChannelObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
|
static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
|
||||||
"T not derived from SingletonFunctionObject<T>");
|
"T not derived from SingletonFunctionObject<T>");
|
||||||
|
|
||||||
auto* p_storage =
|
auto* p_storage =
|
||||||
@ -123,7 +123,7 @@ class SingletonFunctionObject : public ChannelObject {
|
|||||||
*/
|
*/
|
||||||
static auto CreateInstance(
|
static auto CreateInstance(
|
||||||
int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
|
int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
|
||||||
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
|
static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
|
||||||
"T not derived from SingletonFunctionObject<T>");
|
"T not derived from SingletonFunctionObject<T>");
|
||||||
|
|
||||||
auto* p_storage =
|
auto* p_storage =
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "SingletonStorageCollection.h"
|
#include "SingletonStorageCollection.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "core/function/basic/SingletonStorage.h"
|
#include "core/function/basic/SingletonStorage.h"
|
||||||
@ -35,6 +36,10 @@
|
|||||||
|
|
||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
|
|
||||||
|
std::unique_ptr<SingletonStorageCollection,
|
||||||
|
SecureObjectDeleter<SingletonStorageCollection>>
|
||||||
|
instance = nullptr;
|
||||||
|
|
||||||
class SingletonStorageCollection::Impl {
|
class SingletonStorageCollection::Impl {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -43,17 +48,21 @@ class SingletonStorageCollection::Impl {
|
|||||||
* @return SingletonStorageCollection*
|
* @return SingletonStorageCollection*
|
||||||
*/
|
*/
|
||||||
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
|
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
|
||||||
static SingletonStorageCollection* instance = nullptr;
|
|
||||||
|
|
||||||
if (force_refresh || instance == nullptr) {
|
if (force_refresh || instance == nullptr) {
|
||||||
instance = new SingletonStorageCollection();
|
instance = SecureCreateUniqueObject<SingletonStorageCollection>();
|
||||||
SPDLOG_TRACE("new single storage collection created: {}",
|
SPDLOG_TRACE("a new single storage collection created, address: {}",
|
||||||
static_cast<void*>(instance));
|
static_cast<void*>(instance.get()));
|
||||||
}
|
}
|
||||||
|
return instance.get();
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Instance object
|
||||||
|
*
|
||||||
|
* @return SingletonStorageCollection*
|
||||||
|
*/
|
||||||
|
static void Destroy() { instance = nullptr; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Singleton Storage object
|
* @brief Get the Singleton Storage object
|
||||||
*
|
*
|
||||||
@ -95,14 +104,18 @@ SingletonStorageCollection::SingletonStorageCollection() noexcept
|
|||||||
|
|
||||||
SingletonStorageCollection::~SingletonStorageCollection() = default;
|
SingletonStorageCollection::~SingletonStorageCollection() = default;
|
||||||
|
|
||||||
|
auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
|
||||||
|
-> GpgFrontend::SingletonStorageCollection* {
|
||||||
|
return Impl::GetInstance(force_refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingletonStorageCollection::Destroy() {
|
||||||
|
return SingletonStorageCollection::Impl::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
auto SingletonStorageCollection::GetSingletonStorage(
|
auto SingletonStorageCollection::GetSingletonStorage(
|
||||||
const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
|
const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
|
||||||
return p_->GetSingletonStorage(type_id);
|
return p_->GetSingletonStorage(type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GpgFrontend::SingletonStorageCollection::GetInstance(
|
|
||||||
bool force_refresh = false) -> GpgFrontend::SingletonStorageCollection* {
|
|
||||||
return Impl::GetInstance(force_refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <core/function/SecureMemoryAllocator.h>
|
|
||||||
|
|
||||||
#include "core/function/SecureMemoryAllocator.h"
|
#include "core/function/SecureMemoryAllocator.h"
|
||||||
|
|
||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
@ -40,6 +38,18 @@ using SingletonStoragePtr =
|
|||||||
|
|
||||||
class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
|
class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
SingletonStorageCollection() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~SingletonStorageCollection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Instance object
|
* @brief Get the Instance object
|
||||||
*
|
*
|
||||||
@ -47,6 +57,12 @@ class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
|
|||||||
*/
|
*/
|
||||||
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
|
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void Destroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Singleton Storage object
|
* @brief Get the Singleton Storage object
|
||||||
*
|
*
|
||||||
@ -58,18 +74,6 @@ class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
|
|||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> p_;
|
std::unique_ptr<Impl> p_;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SingletonStorageCollection() noexcept;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
~SingletonStorageCollection();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
@ -52,13 +52,14 @@ auto GpgFrontend::GpgBasicOperator::Encrypt(
|
|||||||
GpgData data_in(in_buffer.data(), in_buffer.size());
|
GpgData data_in(in_buffer.data(), in_buffer.size());
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
gpgme_error_t err = CheckGpgError(gpgme_op_encrypt(
|
gpgme_error_t err = CheckGpgError(
|
||||||
ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
|
gpgme_op_encrypt(ctx_.DefaultContext(), recipients,
|
||||||
|
GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_));
|
auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
|
||||||
std::swap(result, temp_result);
|
std::swap(result, temp_result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -71,12 +72,13 @@ auto GpgFrontend::GpgBasicOperator::Decrypt(
|
|||||||
|
|
||||||
GpgData data_in(in_buffer.data(), in_buffer.size());
|
GpgData data_in(in_buffer.data(), in_buffer.size());
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
err = CheckGpgError(gpgme_op_decrypt(ctx_, data_in, data_out));
|
err =
|
||||||
|
CheckGpgError(gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
auto temp_result = NewResult(gpgme_op_decrypt_result(ctx_));
|
auto temp_result = NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext()));
|
||||||
std::swap(result, temp_result);
|
std::swap(result, temp_result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -93,12 +95,14 @@ auto GpgFrontend::GpgBasicOperator::Verify(BypeArrayRef& in_buffer,
|
|||||||
|
|
||||||
if (sig_buffer != nullptr && !sig_buffer->empty()) {
|
if (sig_buffer != nullptr && !sig_buffer->empty()) {
|
||||||
GpgData sig_data(sig_buffer->data(), sig_buffer->size());
|
GpgData sig_data(sig_buffer->data(), sig_buffer->size());
|
||||||
err = CheckGpgError(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
|
err = CheckGpgError(
|
||||||
|
gpgme_op_verify(ctx_.DefaultContext(), sig_data, data_in, nullptr));
|
||||||
} else {
|
} else {
|
||||||
err = CheckGpgError(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
|
err = CheckGpgError(
|
||||||
|
gpgme_op_verify(ctx_.DefaultContext(), data_in, nullptr, data_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto temp_result = NewResult(gpgme_op_verify_result(ctx_));
|
auto temp_result = NewResult(gpgme_op_verify_result(ctx_.DefaultContext()));
|
||||||
std::swap(result, temp_result);
|
std::swap(result, temp_result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -115,12 +119,13 @@ auto GpgFrontend::GpgBasicOperator::Sign(
|
|||||||
GpgData data_in(in_buffer.data(), in_buffer.size());
|
GpgData data_in(in_buffer.data(), in_buffer.size());
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
err = CheckGpgError(gpgme_op_sign(ctx_, data_in, data_out, mode));
|
err = CheckGpgError(
|
||||||
|
gpgme_op_sign(ctx_.DefaultContext(), data_in, data_out, mode));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
auto temp_result = NewResult(gpgme_op_sign_result(ctx_));
|
auto temp_result = NewResult(gpgme_op_sign_result(ctx_.DefaultContext()));
|
||||||
|
|
||||||
std::swap(result, temp_result);
|
std::swap(result, temp_result);
|
||||||
|
|
||||||
@ -136,15 +141,18 @@ auto GpgFrontend::GpgBasicOperator::DecryptVerify(
|
|||||||
GpgData data_in(in_buffer.data(), in_buffer.size());
|
GpgData data_in(in_buffer.data(), in_buffer.size());
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
err = CheckGpgError(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
|
err = CheckGpgError(
|
||||||
|
gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
auto temp_decr_result = NewResult(gpgme_op_decrypt_result(ctx_));
|
auto temp_decr_result =
|
||||||
|
NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext()));
|
||||||
std::swap(decrypt_result, temp_decr_result);
|
std::swap(decrypt_result, temp_decr_result);
|
||||||
|
|
||||||
auto temp_verify_result = NewResult(gpgme_op_verify_result(ctx_));
|
auto temp_verify_result =
|
||||||
|
NewResult(gpgme_op_verify_result(ctx_.DefaultContext()));
|
||||||
std::swap(verify_result, temp_verify_result);
|
std::swap(verify_result, temp_verify_result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -173,40 +181,43 @@ auto GpgFrontend::GpgBasicOperator::EncryptSign(
|
|||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
// If the last parameter isnt 0, a private copy of data is made
|
// If the last parameter isnt 0, a private copy of data is made
|
||||||
err = CheckGpgError(gpgme_op_encrypt_sign(
|
err = CheckGpgError(gpgme_op_encrypt_sign(ctx_.DefaultContext(), recipients,
|
||||||
ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
|
GPGME_ENCRYPT_ALWAYS_TRUST, data_in,
|
||||||
|
data_out));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
auto temp_encr_result = NewResult(gpgme_op_encrypt_result(ctx_));
|
auto temp_encr_result =
|
||||||
|
NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
|
||||||
swap(encr_result, temp_encr_result);
|
swap(encr_result, temp_encr_result);
|
||||||
auto temp_sign_result = NewResult(gpgme_op_sign_result(ctx_));
|
auto temp_sign_result =
|
||||||
|
NewResult(gpgme_op_sign_result(ctx_.DefaultContext()));
|
||||||
swap(sign_result, temp_sign_result);
|
swap(sign_result, temp_sign_result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
|
void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
|
||||||
gpgme_signers_clear(ctx_);
|
gpgme_signers_clear(ctx_.DefaultContext());
|
||||||
for (const GpgKey& key : signers) {
|
for (const GpgKey& key : signers) {
|
||||||
SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
|
SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
|
||||||
if (key.IsHasActualSigningCapability()) {
|
if (key.IsHasActualSigningCapability()) {
|
||||||
SPDLOG_DEBUG("signer");
|
SPDLOG_DEBUG("signer");
|
||||||
auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
|
auto error = gpgme_signers_add(ctx_.DefaultContext(), gpgme_key_t(key));
|
||||||
CheckGpgError(error);
|
CheckGpgError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (signers.size() != gpgme_signers_count(ctx_))
|
if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
|
||||||
SPDLOG_DEBUG("not all signers added");
|
SPDLOG_DEBUG("not all signers added");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GpgFrontend::GpgBasicOperator::GetSigners()
|
auto GpgFrontend::GpgBasicOperator::GetSigners()
|
||||||
-> std::unique_ptr<GpgFrontend::KeyArgsList> {
|
-> std::unique_ptr<GpgFrontend::KeyArgsList> {
|
||||||
auto count = gpgme_signers_count(ctx_);
|
auto count = gpgme_signers_count(ctx_.DefaultContext());
|
||||||
auto signers = std::make_unique<std::vector<GpgKey>>();
|
auto signers = std::make_unique<std::vector<GpgKey>>();
|
||||||
for (auto i = 0U; i < count; i++) {
|
for (auto i = 0U; i < count; i++) {
|
||||||
auto key = GpgKey(gpgme_signers_enum(ctx_, i));
|
auto key = GpgKey(gpgme_signers_enum(ctx_.DefaultContext(), i));
|
||||||
signers->push_back(GpgKey(std::move(key)));
|
signers->push_back(GpgKey(std::move(key)));
|
||||||
}
|
}
|
||||||
return signers;
|
return signers;
|
||||||
@ -219,15 +230,17 @@ auto GpgFrontend::GpgBasicOperator::EncryptSymmetric(
|
|||||||
GpgData data_in(in_buffer.data(), in_buffer.size());
|
GpgData data_in(in_buffer.data(), in_buffer.size());
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
gpgme_error_t err = CheckGpgError(gpgme_op_encrypt(
|
gpgme_error_t err = CheckGpgError(
|
||||||
ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
|
gpgme_op_encrypt(ctx_.DefaultContext(), nullptr, GPGME_ENCRYPT_SYMMETRIC,
|
||||||
|
data_in, data_out));
|
||||||
|
|
||||||
auto temp_data_out = data_out.Read2Buffer();
|
auto temp_data_out = data_out.Read2Buffer();
|
||||||
std::swap(temp_data_out, out_buffer);
|
std::swap(temp_data_out, out_buffer);
|
||||||
|
|
||||||
// TODO(Saturneric): maybe a bug of gpgme
|
// TODO(Saturneric): maybe a bug of gpgme
|
||||||
if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
|
if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
|
||||||
auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_));
|
auto temp_result =
|
||||||
|
NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
|
||||||
std::swap(result, temp_result);
|
std::swap(result, temp_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "core/module/Module.h"
|
#include "core/module/Module.h"
|
||||||
#include "core/thread/Task.h"
|
#include "core/thread/Task.h"
|
||||||
#include "core/thread/TaskRunnerGetter.h"
|
#include "core/thread/TaskRunnerGetter.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
|
|
||||||
@ -231,6 +232,9 @@ void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
|
|||||||
void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
|
void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
|
||||||
QEventLoop looper;
|
QEventLoop looper;
|
||||||
auto remaining_tasks = contexts.size();
|
auto remaining_tasks = contexts.size();
|
||||||
|
Thread::TaskRunnerPtr target_task_runner = nullptr;
|
||||||
|
|
||||||
|
bool need_looper = true;
|
||||||
|
|
||||||
for (auto &context : contexts) {
|
for (auto &context : contexts) {
|
||||||
const auto &cmd = context.cmd;
|
const auto &cmd = context.cmd;
|
||||||
@ -240,22 +244,37 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
|
|||||||
|
|
||||||
QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
|
QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
|
||||||
--remaining_tasks;
|
--remaining_tasks;
|
||||||
|
SPDLOG_DEBUG("remaining tasks: {}", remaining_tasks);
|
||||||
if (remaining_tasks <= 0) {
|
if (remaining_tasks <= 0) {
|
||||||
|
SPDLOG_DEBUG("no remaining task, quit");
|
||||||
looper.quit();
|
looper.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (context.task_runner != nullptr) {
|
if (context.task_runner != nullptr) {
|
||||||
context.task_runner->PostTask(task);
|
target_task_runner = context.task_runner;
|
||||||
} else {
|
} else {
|
||||||
GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
|
target_task_runner =
|
||||||
.GetTaskRunner(
|
GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
|
||||||
Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
|
Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
|
||||||
->PostTask(task);
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
if (QThread::currentThread() == target_task_runner->GetThread()) {
|
||||||
|
need_looper = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
looper.exec();
|
if (need_looper) {
|
||||||
|
// block until task finished
|
||||||
|
// this is to keep reference vaild until task finished
|
||||||
|
looper.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace GpgFrontend
|
} // namespace GpgFrontend
|
@ -31,17 +31,13 @@
|
|||||||
#include <gpg-error.h>
|
#include <gpg-error.h>
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "core/function/CoreSignalStation.h"
|
#include "core/function/CoreSignalStation.h"
|
||||||
#include "core/function/basic/GpgFunctionObject.h"
|
#include "core/function/basic/GpgFunctionObject.h"
|
||||||
#include "core/function/gpg/GpgCommandExecutor.h"
|
|
||||||
#include "core/function/gpg/GpgKeyGetter.h"
|
|
||||||
#include "core/module/ModuleManager.h"
|
#include "core/module/ModuleManager.h"
|
||||||
#include "core/thread/Task.h"
|
|
||||||
#include "core/thread/TaskRunnerGetter.h"
|
|
||||||
#include "core/utils/CacheUtils.h"
|
|
||||||
#include "core/utils/CommonUtils.h"
|
|
||||||
#include "core/utils/GpgUtils.h"
|
#include "core/utils/GpgUtils.h"
|
||||||
#include "function/CacheManager.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -49,6 +45,15 @@
|
|||||||
|
|
||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
|
|
||||||
|
struct CtxRefDeleter {
|
||||||
|
void operator()(gpgme_ctx_t _ctx) {
|
||||||
|
if (_ctx != nullptr) gpgme_release(_ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using CtxRefHandler =
|
||||||
|
std::unique_ptr<struct gpgme_context, CtxRefDeleter>; ///<
|
||||||
|
|
||||||
class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
|
class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -58,169 +63,29 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
|
|||||||
Impl(GpgContext *parent, const GpgContextInitArgs &args, int channel)
|
Impl(GpgContext *parent, const GpgContextInitArgs &args, int channel)
|
||||||
: SingletonFunctionObject<GpgContext::Impl>(channel),
|
: SingletonFunctionObject<GpgContext::Impl>(channel),
|
||||||
parent_(parent),
|
parent_(parent),
|
||||||
args_(args) {
|
args_(args),
|
||||||
gpgme_ctx_t p_ctx;
|
good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
|
||||||
|
|
||||||
// get gpgme library version
|
[[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
|
||||||
Module::UpsertRTValue("core", "gpgme.version",
|
return binary_ctx_ref_.get();
|
||||||
std::string(gpgme_check_version(nullptr)));
|
|
||||||
|
|
||||||
// create a new context
|
|
||||||
CheckGpgError(gpgme_new(&p_ctx));
|
|
||||||
ctx_ref_ = CtxRefHandler(p_ctx);
|
|
||||||
|
|
||||||
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(CheckGpgError(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) {
|
|
||||||
CheckGpgError(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;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.app_path",
|
|
||||||
std::string(engine_info->file_name));
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
|
|
||||||
std::string(engine_info->version));
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.database_path",
|
|
||||||
std::string(engine_info->home_dir == nullptr
|
|
||||||
? "default"
|
|
||||||
: engine_info->home_dir));
|
|
||||||
break;
|
|
||||||
case GPGME_PROTOCOL_CMS:
|
|
||||||
find_cms = true;
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
|
|
||||||
std::string(engine_info->file_name));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case GPGME_PROTOCOL_GPGCONF:
|
|
||||||
find_gpgconf = true;
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
|
|
||||||
std::string(engine_info->file_name));
|
|
||||||
break;
|
|
||||||
case GPGME_PROTOCOL_ASSUAN:
|
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
|
|
||||||
std::string(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
|
|
||||||
"core", "gpgme.ctx.gnupg_version", std::string{"0.0.0"});
|
|
||||||
SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
|
|
||||||
|
|
||||||
// conditional check: only support gpg 2.x now
|
|
||||||
if ((CompareSoftwareVersion(gnupg_version, "2.0.0") >= 0 && find_gpgconf &&
|
|
||||||
find_openpgp && find_cms)) {
|
|
||||||
check_passed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_passed) {
|
|
||||||
this->good_ = false;
|
|
||||||
SPDLOG_ERROR("env check failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// speed up loading process
|
|
||||||
gpgme_set_offline(*this, 1);
|
|
||||||
|
|
||||||
// set keylist mode
|
|
||||||
if (gnupg_version >= "2.0.0") {
|
|
||||||
CheckGpgError(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 {
|
|
||||||
CheckGpgError(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(
|
|
||||||
[=](const DataObjectPtr &) -> int {
|
|
||||||
ctx_post_initialize();
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
"ctx_post_initialize"));
|
|
||||||
|
|
||||||
good_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
[[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t {
|
||||||
* @brief
|
return ctx_ref_.get();
|
||||||
*
|
}
|
||||||
* @return gpgme_ctx_t
|
|
||||||
*/
|
|
||||||
operator gpgme_ctx_t() const { return ctx_ref_.get(); }
|
|
||||||
|
|
||||||
[[nodiscard]] auto Good() const -> bool { return good_; }
|
[[nodiscard]] auto Good() const -> bool { return good_; }
|
||||||
|
|
||||||
void SetPassphraseCb(gpgme_passphrase_cb_t cb) {
|
auto SetPassphraseCb(const CtxRefHandler &ctx, gpgme_passphrase_cb_t cb)
|
||||||
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
|
-> bool {
|
||||||
"core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"});
|
if (gpgme_get_pinentry_mode(ctx.get()) != GPGME_PINENTRY_MODE_LOOPBACK) {
|
||||||
|
if (CheckGpgError(gpgme_set_pinentry_mode(
|
||||||
if (CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0) {
|
ctx.get(), GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
|
||||||
if (gpgme_get_pinentry_mode(*this) != GPGME_PINENTRY_MODE_LOOPBACK) {
|
return false;
|
||||||
gpgme_set_pinentry_mode(*this, GPGME_PINENTRY_MODE_LOOPBACK);
|
|
||||||
}
|
}
|
||||||
gpgme_set_passphrase_cb(*this, cb, reinterpret_cast<void *>(parent_));
|
|
||||||
} else {
|
|
||||||
SPDLOG_ERROR("not supported for gnupg version: {}", gnupg_version);
|
|
||||||
}
|
}
|
||||||
|
gpgme_set_passphrase_cb(ctx.get(), cb, reinterpret_cast<void *>(parent_));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto TestPassphraseCb(void *opaque, const char *uid_hint,
|
static auto TestPassphraseCb(void *opaque, const char *uid_hint,
|
||||||
@ -288,47 +153,82 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CtxRefDeleter {
|
|
||||||
void operator()(gpgme_ctx_t _ctx) {
|
|
||||||
if (_ctx != nullptr) gpgme_release(_ctx);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using CtxRefHandler =
|
|
||||||
std::unique_ptr<struct gpgme_context, CtxRefDeleter>; ///<
|
|
||||||
|
|
||||||
GpgContext *parent_;
|
GpgContext *parent_;
|
||||||
GpgContextInitArgs args_{}; ///<
|
GpgContextInitArgs args_{}; ///<
|
||||||
CtxRefHandler ctx_ref_ = nullptr; ///<
|
CtxRefHandler ctx_ref_ = nullptr; ///<
|
||||||
|
CtxRefHandler binary_ctx_ref_ = nullptr; ///<
|
||||||
bool good_ = true;
|
bool good_ = true;
|
||||||
|
|
||||||
void ctx_post_initialize() {
|
static auto set_ctx_key_list_mode(const CtxRefHandler &ctx) -> bool {
|
||||||
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
|
assert(ctx.get() != nullptr);
|
||||||
"core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"});
|
|
||||||
|
|
||||||
if (args_.ascii) {
|
const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
|
||||||
/** Setting the output type must be done at the beginning */
|
"core", "gpgme.version", std::string{"0.0.0"});
|
||||||
/** think this means ascii-armor --> ? */
|
SPDLOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
|
||||||
gpgme_set_armor(*this, 1);
|
|
||||||
} else {
|
if (gpgme_get_keylist_mode(ctx.get()) == 0) {
|
||||||
/** Setting the output type must be done at the beginning */
|
SPDLOG_ERROR(
|
||||||
/** think this means ascii-armor --> ? */
|
"ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
|
||||||
gpgme_set_armor(*this, 0);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set keylist mode
|
||||||
|
return CheckGpgError(gpgme_set_keylist_mode(
|
||||||
|
ctx.get(),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto common_ctx_initialize(const CtxRefHandler &ctx,
|
||||||
|
const GpgContextInitArgs &args) -> bool {
|
||||||
|
assert(ctx.get() != nullptr);
|
||||||
|
|
||||||
|
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.get(), GPGME_PROTOCOL_GPGCONF,
|
||||||
|
args.custom_gpgconf_path.c_str(), nullptr);
|
||||||
|
|
||||||
|
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
|
||||||
|
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set context offline mode
|
||||||
|
SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
|
||||||
|
gpgme_set_offline(ctx.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) {
|
||||||
|
if (CheckGpgError(gpgme_set_ctx_flag(ctx.get(), "auto-key-import",
|
||||||
|
"1")) != GPG_ERR_NO_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set_ctx_key_list_mode(ctx)) {
|
||||||
|
SPDLOG_DEBUG("set ctx key list mode failed");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for unit test
|
// for unit test
|
||||||
if (args_.test_mode) {
|
if (args_.test_mode) {
|
||||||
if (CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0) {
|
if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
|
||||||
SetPassphraseCb(TestPassphraseCb);
|
SPDLOG_ERROR("set passphrase cb failed, test");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
} else if (!args_.use_pinentry) {
|
||||||
|
if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
|
||||||
|
SPDLOG_DEBUG("set passphrase cb failed, custom");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
gpgme_set_status_cb(*this, TestStatusCb, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args_.use_pinentry) {
|
// set custom gpg key db path
|
||||||
SetPassphraseCb(CustomPassphraseCb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set custom key db path
|
|
||||||
if (!args_.db_path.empty()) {
|
if (!args_.db_path.empty()) {
|
||||||
Module::UpsertRTValue("core", "gpgme.ctx.database_path",
|
Module::UpsertRTValue("core", "gpgme.ctx.database_path",
|
||||||
std::string(args_.db_path));
|
std::string(args_.db_path));
|
||||||
@ -342,8 +242,50 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
|
|||||||
gpgme_ctx_set_engine_info(ctx_ref_.get(), GPGME_PROTOCOL_OpenPGP,
|
gpgme_ctx_set_engine_info(ctx_ref_.get(), GPGME_PROTOCOL_OpenPGP,
|
||||||
app_path.c_str(), database_path.c_str());
|
app_path.c_str(), database_path.c_str());
|
||||||
SPDLOG_DEBUG("ctx set custom key db path: {}", database_path);
|
SPDLOG_DEBUG("ctx set custom key db path: {}", database_path);
|
||||||
|
|
||||||
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
|
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
|
||||||
|
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
|
||||||
|
gpgme_ctx_t p_ctx;
|
||||||
|
if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(p_ctx != nullptr);
|
||||||
|
binary_ctx_ref_ = CtxRefHandler(p_ctx);
|
||||||
|
|
||||||
|
if (!common_ctx_initialize(binary_ctx_ref_, args)) {
|
||||||
|
SPDLOG_ERROR("get new ctx failed, binary");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setting the output type must be done at the beginning */
|
||||||
|
/** think this means ascii-armor --> ? */
|
||||||
|
gpgme_set_armor(binary_ctx_ref_.get(), 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) {
|
||||||
|
SPDLOG_ERROR("get new ctx failed, default");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(p_ctx != nullptr);
|
||||||
|
ctx_ref_ = CtxRefHandler(p_ctx);
|
||||||
|
|
||||||
|
if (!common_ctx_initialize(ctx_ref_, args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_set_armor(ctx_ref_.get(), 1);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -357,12 +299,10 @@ GpgContext::GpgContext(const GpgContextInitArgs &args, int channel)
|
|||||||
|
|
||||||
auto GpgContext::Good() const -> bool { return p_->Good(); }
|
auto GpgContext::Good() const -> bool { return p_->Good(); }
|
||||||
|
|
||||||
void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t passphrase_cb) const {
|
auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
|
||||||
p_->SetPassphraseCb(passphrase_cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
GpgContext::operator gpgme_ctx_t() const {
|
auto GpgContext::DefaultContext() -> gpgme_ctx_t {
|
||||||
return static_cast<gpgme_ctx_t>(*p_);
|
return p_->DefaultContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
GpgContext::~GpgContext() = default;
|
GpgContext::~GpgContext() = default;
|
||||||
|
@ -37,17 +37,16 @@ namespace GpgFrontend {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct GpgContextInitArgs {
|
struct GpgContextInitArgs {
|
||||||
std::string db_path = {};
|
std::string db_path = {}; ///<
|
||||||
|
|
||||||
bool test_mode = false;
|
bool test_mode = false; ///<
|
||||||
bool ascii = true;
|
bool offline_mode = false; ///<
|
||||||
bool offline_mode = false;
|
bool auto_import_missing_key = false; ///<
|
||||||
bool auto_import_missing_key = false;
|
|
||||||
|
|
||||||
bool custom_gpgconf = false;
|
bool custom_gpgconf = false; ///<
|
||||||
std::string custom_gpgconf_path;
|
std::string custom_gpgconf_path; ///<
|
||||||
|
|
||||||
bool use_pinentry = false;
|
bool use_pinentry = false; ///<
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,9 +66,9 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
|
|||||||
|
|
||||||
[[nodiscard]] auto Good() const -> bool;
|
[[nodiscard]] auto Good() const -> bool;
|
||||||
|
|
||||||
operator gpgme_ctx_t() const;
|
auto BinaryContext() -> gpgme_ctx_t;
|
||||||
|
|
||||||
void SetPassphraseCb(gpgme_passphrase_cb_t passphrase_cb) const;
|
auto DefaultContext() -> gpgme_ctx_t;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
@ -54,7 +54,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpgme_key_t p_key = nullptr;
|
gpgme_key_t p_key = nullptr;
|
||||||
gpgme_get_key(ctx_, fpr.c_str(), &p_key, 1);
|
gpgme_get_key(ctx_.DefaultContext(), fpr.c_str(), &p_key, 1);
|
||||||
if (p_key == nullptr) {
|
if (p_key == nullptr) {
|
||||||
SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
|
SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
|
||||||
return GetPubkey(fpr, true);
|
return GetPubkey(fpr, true);
|
||||||
@ -70,7 +70,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpgme_key_t p_key = nullptr;
|
gpgme_key_t p_key = nullptr;
|
||||||
gpgme_get_key(ctx_, fpr.c_str(), &p_key, 0);
|
gpgme_get_key(ctx_.DefaultContext(), fpr.c_str(), &p_key, 0);
|
||||||
if (p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
|
if (p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
|
||||||
return GpgKey(std::move(p_key));
|
return GpgKey(std::move(p_key));
|
||||||
}
|
}
|
||||||
@ -88,13 +88,13 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FlushKeyCache() {
|
void FlushKeyCache() {
|
||||||
SPDLOG_DEBUG("called channel id: {}", GetChannel());
|
SPDLOG_DEBUG("flush key channel called, channel: {}", GetChannel());
|
||||||
|
|
||||||
// clear the keys cache
|
// clear the keys cache
|
||||||
keys_cache_.clear();
|
keys_cache_.clear();
|
||||||
|
|
||||||
// init
|
// init
|
||||||
GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
|
GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
|
||||||
|
|
||||||
// for debug
|
// for debug
|
||||||
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
|
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
|
||||||
@ -106,7 +106,8 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
|
|||||||
// get the lock
|
// get the lock
|
||||||
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
|
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
|
||||||
gpgme_key_t key;
|
gpgme_key_t key;
|
||||||
while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
|
while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
|
||||||
|
GPG_ERR_NO_ERROR) {
|
||||||
auto gpg_key = GpgKey(std::move(key));
|
auto gpg_key = GpgKey(std::move(key));
|
||||||
|
|
||||||
// detect if the key is in a smartcard
|
// detect if the key is in a smartcard
|
||||||
@ -120,14 +121,16 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_DEBUG("cache address: {} object address: {}",
|
SPDLOG_DEBUG("flush key channel cache address: {} object address: {}",
|
||||||
static_cast<void*>(&keys_cache_), static_cast<void*>(this));
|
static_cast<void*>(&keys_cache_), static_cast<void*>(this));
|
||||||
|
|
||||||
// for debug
|
// for debug
|
||||||
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
|
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
|
||||||
|
|
||||||
err = gpgme_op_keylist_end(ctx_);
|
err = gpgme_op_keylist_end(ctx_.DefaultContext());
|
||||||
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
|
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
|
||||||
|
|
||||||
|
SPDLOG_DEBUG("flush key channel done, channel: {}", GetChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
|
auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
|
||||||
|
@ -48,11 +48,11 @@ auto GpgKeyImportExporter::ImportKey(StdBypeArrayPtr in_buffer)
|
|||||||
if (in_buffer->empty()) return {};
|
if (in_buffer->empty()) return {};
|
||||||
|
|
||||||
GpgData data_in(in_buffer->data(), in_buffer->size());
|
GpgData data_in(in_buffer->data(), in_buffer->size());
|
||||||
auto err = CheckGpgError(gpgme_op_import(ctx_, data_in));
|
auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
|
||||||
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
|
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
|
||||||
|
|
||||||
gpgme_import_result_t result;
|
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;
|
gpgme_import_status_t status = result->imports;
|
||||||
auto import_info = std::make_unique<GpgImportInformation>(result);
|
auto import_info = std::make_unique<GpgImportInformation>(result);
|
||||||
while (status != nullptr) {
|
while (status != nullptr) {
|
||||||
@ -90,7 +90,8 @@ auto GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
|
|||||||
keys_array[index] = nullptr;
|
keys_array[index] = nullptr;
|
||||||
|
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
auto err = gpgme_op_export_keys(ctx_, keys_array, mode, data_out);
|
auto err =
|
||||||
|
gpgme_op_export_keys(ctx_.DefaultContext(), keys_array, mode, data_out);
|
||||||
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
|
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
|
||||||
|
|
||||||
delete[] keys_array;
|
delete[] keys_array;
|
||||||
@ -156,7 +157,7 @@ auto GpgKeyImportExporter::ExportSecretKey(const GpgKey& key,
|
|||||||
|
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
// export private key to outBuffer
|
// export private key to outBuffer
|
||||||
gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
|
gpgme_error_t err = gpgme_op_export_keys(ctx_.DefaultContext(), target_key,
|
||||||
GPGME_EXPORT_MODE_SECRET, data_out);
|
GPGME_EXPORT_MODE_SECRET, data_out);
|
||||||
|
|
||||||
auto temp_out_buffer = data_out.Read2Buffer();
|
auto temp_out_buffer = data_out.Read2Buffer();
|
||||||
@ -168,7 +169,8 @@ auto GpgKeyImportExporter::ExportSecretKey(const GpgKey& key,
|
|||||||
auto GpgKeyImportExporter::ExportKey(const GpgKey& key,
|
auto GpgKeyImportExporter::ExportKey(const GpgKey& key,
|
||||||
ByteArrayPtr& out_buffer) const -> bool {
|
ByteArrayPtr& out_buffer) const -> bool {
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
|
auto err =
|
||||||
|
gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(), 0, data_out);
|
||||||
|
|
||||||
SPDLOG_DEBUG("export keys read_bytes: {}",
|
SPDLOG_DEBUG("export keys read_bytes: {}",
|
||||||
gpgme_data_seek(data_out, 0, SEEK_END));
|
gpgme_data_seek(data_out, 0, SEEK_END));
|
||||||
@ -182,8 +184,8 @@ auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key,
|
|||||||
ByteArrayPtr& out_buffer) const
|
ByteArrayPtr& out_buffer) const
|
||||||
-> bool {
|
-> bool {
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
|
auto err = gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(),
|
||||||
data_out);
|
GPGME_EXPORT_MODE_SSH, data_out);
|
||||||
|
|
||||||
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
|
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key,
|
|||||||
auto GpgKeyImportExporter::ExportSecretKeyShortest(
|
auto GpgKeyImportExporter::ExportSecretKeyShortest(
|
||||||
const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool {
|
const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool {
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
|
auto err = gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(),
|
||||||
GPGME_EXPORT_MODE_MINIMAL, data_out);
|
GPGME_EXPORT_MODE_MINIMAL, data_out);
|
||||||
|
|
||||||
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
|
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
|
||||||
|
@ -54,9 +54,9 @@ auto GpgFrontend::GpgKeyManager::SignKey(
|
|||||||
expires_time_t = to_time_t(*expires);
|
expires_time_t = to_time_t(*expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto err =
|
auto err = CheckGpgError(
|
||||||
CheckGpgError(gpgme_op_keysign(ctx_, static_cast<gpgme_key_t>(target),
|
gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
|
||||||
uid.c_str(), expires_time_t, flags));
|
uid.c_str(), expires_time_t, flags));
|
||||||
|
|
||||||
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -69,9 +69,9 @@ auto GpgFrontend::GpgKeyManager::RevSign(
|
|||||||
for (const auto& sign_id : *signature_id) {
|
for (const auto& sign_id : *signature_id) {
|
||||||
auto signing_key = key_getter.GetKey(sign_id.first);
|
auto signing_key = key_getter.GetKey(sign_id.first);
|
||||||
assert(signing_key.IsGood());
|
assert(signing_key.IsGood());
|
||||||
auto err = CheckGpgError(gpgme_op_revsig(ctx_, gpgme_key_t(key),
|
auto err = CheckGpgError(
|
||||||
gpgme_key_t(signing_key),
|
gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
|
||||||
sign_id.second.c_str(), 0));
|
gpgme_key_t(signing_key), sign_id.second.c_str(), 0));
|
||||||
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
|
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -90,8 +90,9 @@ auto GpgFrontend::GpgKeyManager::SetExpire(
|
|||||||
|
|
||||||
if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
|
if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
|
||||||
|
|
||||||
auto err = CheckGpgError(gpgme_op_setexpire(
|
auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
|
||||||
ctx_, static_cast<gpgme_key_t>(key), expires_time, sub_fprs, 0));
|
static_cast<gpgme_key_t>(key),
|
||||||
|
expires_time, sub_fprs, 0));
|
||||||
|
|
||||||
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -180,9 +181,9 @@ auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
|
|||||||
|
|
||||||
GpgData data_out;
|
GpgData data_out;
|
||||||
|
|
||||||
auto err = gpgme_op_interact(ctx_, static_cast<gpgme_key_t>(key), 0,
|
auto err = gpgme_op_interact(
|
||||||
GpgKeyManager::interactor_cb_fnc,
|
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
|
||||||
(void*)&handel_struct, data_out);
|
GpgKeyManager::interactor_cb_fnc, (void*)&handel_struct, data_out);
|
||||||
if (err != GPG_ERR_NO_ERROR) {
|
if (err != GPG_ERR_NO_ERROR) {
|
||||||
SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
|
SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
|
||||||
trust_level, key.GetId(), gpgme_strerror(err));
|
trust_level, key.GetId(), gpgme_strerror(err));
|
||||||
|
@ -63,9 +63,9 @@ void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
|
|||||||
for (const auto& tmp : *key_ids) {
|
for (const auto& tmp : *key_ids) {
|
||||||
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
|
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
|
||||||
if (key.IsGood()) {
|
if (key.IsGood()) {
|
||||||
err = CheckGpgError(
|
err = CheckGpgError(gpgme_op_delete_ext(
|
||||||
gpgme_op_delete_ext(ctx_, static_cast<gpgme_key_t>(key),
|
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
|
||||||
GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
|
GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
|
||||||
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
|
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
|
||||||
} else {
|
} else {
|
||||||
SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
|
SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
|
||||||
@ -95,11 +95,13 @@ auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
|
|||||||
|
|
||||||
GpgError err;
|
GpgError err;
|
||||||
if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty()) {
|
if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty()) {
|
||||||
err = gpgme_op_setexpire(ctx_, static_cast<gpgme_key_t>(key), expires_time,
|
err =
|
||||||
nullptr, 0);
|
gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
|
||||||
|
expires_time, nullptr, 0);
|
||||||
} else {
|
} else {
|
||||||
err = gpgme_op_setexpire(ctx_, static_cast<gpgme_key_t>(key), expires_time,
|
err =
|
||||||
subkey_fpr.c_str(), 0);
|
gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
|
||||||
|
expires_time, subkey_fpr.c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -192,11 +194,13 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
|
|||||||
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
|
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
|
||||||
|
|
||||||
SPDLOG_DEBUG("key generation args: {}", userid, algo, expires, flags);
|
SPDLOG_DEBUG("key generation args: {}", userid, algo, expires, flags);
|
||||||
err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags);
|
err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
|
||||||
|
nullptr, flags);
|
||||||
|
|
||||||
GpgGenKeyResult result;
|
GpgGenKeyResult result;
|
||||||
if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
|
if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
|
||||||
auto temp_result = NewResult(gpgme_op_genkey_result(ctx));
|
auto temp_result =
|
||||||
|
NewResult(gpgme_op_genkey_result(ctx.DefaultContext()));
|
||||||
std::swap(temp_result, result);
|
std::swap(temp_result, result);
|
||||||
}
|
}
|
||||||
data_object->Swap({result});
|
data_object->Swap({result});
|
||||||
@ -241,8 +245,9 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
|
|||||||
|
|
||||||
SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
|
SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
|
||||||
|
|
||||||
auto err = gpgme_op_createsubkey(ctx, static_cast<gpgme_key_t>(key),
|
auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
|
||||||
algo, 0, expires, flags);
|
static_cast<gpgme_key_t>(key), algo, 0,
|
||||||
|
expires, flags);
|
||||||
return CheckGpgError(err);
|
return CheckGpgError(err);
|
||||||
},
|
},
|
||||||
callback, "gpgme_op_createsubkey", "2.1.13");
|
callback, "gpgme_op_createsubkey", "2.1.13");
|
||||||
@ -252,7 +257,8 @@ void GpgKeyOpera::ModifyPassword(const GpgKey& key,
|
|||||||
const GpgOperationCallback& callback) {
|
const GpgOperationCallback& callback) {
|
||||||
RunGpgOperaAsync(
|
RunGpgOperaAsync(
|
||||||
[&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
|
[&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
|
||||||
return gpgme_op_passwd(ctx, static_cast<gpgme_key_t>(key), 0);
|
return gpgme_op_passwd(ctx.DefaultContext(),
|
||||||
|
static_cast<gpgme_key_t>(key), 0);
|
||||||
},
|
},
|
||||||
callback, "gpgme_op_passwd", "2.0.15");
|
callback, "gpgme_op_passwd", "2.0.15");
|
||||||
}
|
}
|
||||||
@ -269,8 +275,8 @@ auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
|
|||||||
return GPG_ERR_NOT_SUPPORTED;
|
return GPG_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto err =
|
auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
|
||||||
gpgme_op_tofu_policy(ctx_, static_cast<gpgme_key_t>(key), tofu_policy);
|
static_cast<gpgme_key_t>(key), tofu_policy);
|
||||||
return CheckGpgError(err);
|
return CheckGpgError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,21 +39,22 @@ GpgUIDOperator::GpgUIDOperator(int channel)
|
|||||||
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
|
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
|
||||||
|
|
||||||
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& uid) -> bool {
|
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& uid) -> bool {
|
||||||
auto err =
|
auto err = gpgme_op_adduid(ctx_.DefaultContext(),
|
||||||
gpgme_op_adduid(ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), 0);
|
static_cast<gpgme_key_t>(key), uid.c_str(), 0);
|
||||||
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GpgUIDOperator::RevUID(const GpgKey& key, const std::string& uid) -> bool {
|
auto GpgUIDOperator::RevUID(const GpgKey& key, const std::string& uid) -> bool {
|
||||||
auto err = CheckGpgError(
|
auto err = CheckGpgError(gpgme_op_revuid(
|
||||||
gpgme_op_revuid(ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), 0));
|
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.c_str(), 0));
|
||||||
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const std::string& uid)
|
auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const std::string& uid)
|
||||||
-> bool {
|
-> bool {
|
||||||
auto err = CheckGpgError(gpgme_op_set_uid_flag(
|
auto err = CheckGpgError(gpgme_op_set_uid_flag(
|
||||||
ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), "primary", nullptr));
|
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.c_str(),
|
||||||
|
"primary", nullptr));
|
||||||
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& name,
|
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& name,
|
||||||
|
@ -80,8 +80,10 @@ class Event::Impl {
|
|||||||
|
|
||||||
void ExecuteCallback(ListenerIdentifier listener_id,
|
void ExecuteCallback(ListenerIdentifier listener_id,
|
||||||
const DataObjectPtr& data_object) {
|
const DataObjectPtr& data_object) {
|
||||||
|
SPDLOG_DEBUG("try to execute callback for event {} with listener {}",
|
||||||
|
event_identifier_, listener_id);
|
||||||
if (callback_) {
|
if (callback_) {
|
||||||
SPDLOG_DEBUG("execute callback for event {} with listener {}",
|
SPDLOG_DEBUG("executing callback for event {} with listener {}",
|
||||||
event_identifier_, listener_id);
|
event_identifier_, listener_id);
|
||||||
if (!QMetaObject::invokeMethod(
|
if (!QMetaObject::invokeMethod(
|
||||||
callback_thread_,
|
callback_thread_,
|
||||||
|
@ -273,8 +273,9 @@ class GlobalModuleContext::Impl {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto IsModuleExists(const ModuleIdentifier& m_id) const -> bool {
|
auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool {
|
||||||
return search_module_register_table(m_id).has_value();
|
auto m = search_module_register_table(m_id);
|
||||||
|
return m.has_value() && m->get()->activate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -374,8 +375,8 @@ auto GlobalModuleContext::GetDefaultChannel(ModuleRawPtr channel) -> int {
|
|||||||
return GlobalModuleContext::Impl::GetDefaultChannel(channel);
|
return GlobalModuleContext::Impl::GetDefaultChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GlobalModuleContext::IsModuleExists(ModuleIdentifier m_id) -> bool {
|
auto GlobalModuleContext::IsModuleActivated(ModuleIdentifier m_id) -> bool {
|
||||||
return p_->IsModuleExists(std::move(m_id));
|
return p_->IsModuleActivated(std::move(m_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace GpgFrontend::Module
|
} // namespace GpgFrontend::Module
|
||||||
|
@ -77,7 +77,7 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject {
|
|||||||
|
|
||||||
auto TriggerEvent(EventRefrernce) -> bool;
|
auto TriggerEvent(EventRefrernce) -> bool;
|
||||||
|
|
||||||
auto IsModuleExists(ModuleIdentifier) -> bool;
|
auto IsModuleActivated(ModuleIdentifier) -> bool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
@ -102,6 +102,10 @@ class ModuleManager::Impl {
|
|||||||
return grt_->ListChildKeys(n, k);
|
return grt_->ListChildKeys(n, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto IsModuleActivated(ModuleIdentifier id) -> bool {
|
||||||
|
return gmc_->IsModuleActivated(id);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ModuleMangerPtr global_module_manager;
|
static ModuleMangerPtr global_module_manager;
|
||||||
TaskRunnerPtr task_runner_;
|
TaskRunnerPtr task_runner_;
|
||||||
@ -109,6 +113,10 @@ class ModuleManager::Impl {
|
|||||||
GRTPtr grt_;
|
GRTPtr grt_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto IsModuleAcivate(ModuleIdentifier id) -> bool {
|
||||||
|
return ModuleManager::GetInstance()->IsModuleActivated(id);
|
||||||
|
}
|
||||||
|
|
||||||
auto UpsertRTValue(const std::string& namespace_, const std::string& key,
|
auto UpsertRTValue(const std::string& namespace_, const std::string& key,
|
||||||
const std::any& value) -> bool {
|
const std::any& value) -> bool {
|
||||||
return ModuleManager::GetInstance()->UpsertRTValue(namespace_, key,
|
return ModuleManager::GetInstance()->UpsertRTValue(namespace_, key,
|
||||||
@ -170,4 +178,8 @@ auto ModuleManager::ListRTChildKeys(const std::string& n, const std::string& k)
|
|||||||
return p_->ListRTChildKeys(n, k);
|
return p_->ListRTChildKeys(n, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ModuleManager::IsModuleActivated(ModuleIdentifier id) -> bool {
|
||||||
|
return p_->IsModuleActivated(id);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GpgFrontend::Module
|
} // namespace GpgFrontend::Module
|
@ -63,6 +63,8 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager : public QObject {
|
|||||||
|
|
||||||
void RegisterModule(ModulePtr);
|
void RegisterModule(ModulePtr);
|
||||||
|
|
||||||
|
auto IsModuleActivated(ModuleIdentifier) -> bool;
|
||||||
|
|
||||||
void TriggerEvent(EventRefrernce);
|
void TriggerEvent(EventRefrernce);
|
||||||
|
|
||||||
void ActiveModule(ModuleIdentifier);
|
void ActiveModule(ModuleIdentifier);
|
||||||
@ -110,13 +112,43 @@ void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
|
|||||||
std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
|
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 std::string& namespace_,
|
auto GPGFRONTEND_CORE_EXPORT UpsertRTValue(const std::string& namespace_,
|
||||||
const std::string& key,
|
const std::string& key,
|
||||||
const std::any& value) -> bool;
|
const std::any& value) -> bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
|
auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
|
||||||
LPCallback) -> bool;
|
LPCallback) -> bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param namespace_
|
||||||
|
* @param key
|
||||||
|
* @return std::vector<Key>
|
||||||
|
*/
|
||||||
auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const std::string& namespace_,
|
auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const std::string& namespace_,
|
||||||
const std::string& key)
|
const std::string& key)
|
||||||
-> std::vector<Key>;
|
-> std::vector<Key>;
|
||||||
|
@ -37,9 +37,9 @@
|
|||||||
namespace GpgFrontend {
|
namespace GpgFrontend {
|
||||||
|
|
||||||
Thread::CoreInitTask::CoreInitTask() : Task("ctx_check_task") {
|
Thread::CoreInitTask::CoreInitTask() : Task("ctx_check_task") {
|
||||||
connect(this, &CoreInitTask::SignalGnupgNotInstall,
|
connect(this, &CoreInitTask::SignalBadGnupgEnv,
|
||||||
CoreSignalStation::GetInstance(),
|
CoreSignalStation::GetInstance(),
|
||||||
&CoreSignalStation::SignalGnupgNotInstall);
|
&CoreSignalStation::SignalBadGnupgEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::CoreInitTask::Run() {
|
void Thread::CoreInitTask::Run() {
|
||||||
@ -48,7 +48,7 @@ void Thread::CoreInitTask::Run() {
|
|||||||
|
|
||||||
// Create & Check Gnupg Context Status
|
// Create & Check Gnupg Context Status
|
||||||
if (!GpgContext::GetInstance().Good()) {
|
if (!GpgContext::GetInstance().Good()) {
|
||||||
emit SignalGnupgNotInstall();
|
emit SignalBadGnupgEnv();
|
||||||
}
|
}
|
||||||
// Try flushing key cache
|
// Try flushing key cache
|
||||||
else {
|
else {
|
||||||
|
@ -50,7 +50,7 @@ class GPGFRONTEND_CORE_EXPORT CoreInitTask : public Task {
|
|||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SignalGnupgNotInstall();
|
void SignalBadGnupgEnv();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +55,9 @@ static inline auto Trim(std::string& s) -> std::string {
|
|||||||
|
|
||||||
auto CheckGpgError(GpgError err) -> GpgError {
|
auto CheckGpgError(GpgError err) -> GpgError {
|
||||||
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
|
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
|
||||||
SPDLOG_ERROR("[error: {}] source: {} description: {}", gpg_err_code(err),
|
SPDLOG_ERROR(
|
||||||
gpgme_strsource(err), gpgme_strerror(err));
|
"gpg operation failed [error code: {}], source: {} description: {}",
|
||||||
|
gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err));
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
18
src/init.cpp
18
src/init.cpp
@ -41,7 +41,7 @@
|
|||||||
#include "core/function/GlobalSettingStation.h"
|
#include "core/function/GlobalSettingStation.h"
|
||||||
#include "core/utils/MemoryUtils.h"
|
#include "core/utils/MemoryUtils.h"
|
||||||
#include "module/GpgFrontendModuleInit.h"
|
#include "module/GpgFrontendModuleInit.h"
|
||||||
#include "spdlog/logger.h"
|
#include "module/sdk/Log.h"
|
||||||
#include "ui/GpgFrontendUIInit.h"
|
#include "ui/GpgFrontendUIInit.h"
|
||||||
|
|
||||||
// main
|
// main
|
||||||
@ -88,7 +88,7 @@ void InitMainLoggingSystem(spdlog::level::level_enum level) {
|
|||||||
spdlog::set_default_logger(main_logger);
|
spdlog::set_default_logger(main_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitModules(InitArgs args) {
|
void InitLoggingSystem(InitArgs args) {
|
||||||
// init the logging system for main
|
// init the logging system for main
|
||||||
InitMainLoggingSystem(args.log_level);
|
InitMainLoggingSystem(args.log_level);
|
||||||
|
|
||||||
@ -97,21 +97,15 @@ void InitModules(InitArgs args) {
|
|||||||
|
|
||||||
// init the logging system for ui
|
// init the logging system for ui
|
||||||
GpgFrontend::UI::InitUILoggingSystem(args.log_level);
|
GpgFrontend::UI::InitUILoggingSystem(args.log_level);
|
||||||
|
|
||||||
// init the logging system for modules
|
|
||||||
GpgFrontend::Module::ModuleInitArgs module_init_args;
|
|
||||||
module_init_args.log_level = args.log_level;
|
|
||||||
//
|
|
||||||
GpgFrontend::Module::LoadGpgFrontendModules(module_init_args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownModules() {
|
void ShutdownLoggingSystem() {
|
||||||
// shutdown the logging system for core
|
|
||||||
GpgFrontend::Module::ShutdownGpgFrontendModules();
|
|
||||||
|
|
||||||
// shutdown the logging system for ui
|
// shutdown the logging system for ui
|
||||||
GpgFrontend::UI::ShutdownUILoggingSystem();
|
GpgFrontend::UI::ShutdownUILoggingSystem();
|
||||||
|
|
||||||
|
// shutdown the logging system for modules
|
||||||
|
GpgFrontend::Module::ShutdownGpgFrontendModulesLoggingSystem();
|
||||||
|
|
||||||
// shutdown the logging system for core
|
// shutdown the logging system for core
|
||||||
GpgFrontend::ShutdownCoreLoggingSystem();
|
GpgFrontend::ShutdownCoreLoggingSystem();
|
||||||
|
|
||||||
|
@ -44,16 +44,17 @@ void HandleSignal(int sig);
|
|||||||
void BeforeExit();
|
void BeforeExit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialize the logging system.
|
* @brief
|
||||||
*
|
*
|
||||||
|
* @param args
|
||||||
*/
|
*/
|
||||||
void InitModules(InitArgs);
|
void InitLoggingSystem(InitArgs args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialize the logging system.
|
* @brief initialize the logging system.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void ShutdownModules();
|
void ShutdownLoggingSystem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief init global PATH env
|
* @brief init global PATH env
|
||||||
|
@ -29,7 +29,9 @@
|
|||||||
#include "GpgFrontendModuleInit.h"
|
#include "GpgFrontendModuleInit.h"
|
||||||
|
|
||||||
#include <core/module/ModuleManager.h>
|
#include <core/module/ModuleManager.h>
|
||||||
#include <module/sdk/Log.h>
|
|
||||||
|
#include "core/thread/Task.h"
|
||||||
|
#include "core/thread/TaskRunnerGetter.h"
|
||||||
|
|
||||||
// integrated modules
|
// integrated modules
|
||||||
#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h"
|
#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h"
|
||||||
@ -37,8 +39,17 @@
|
|||||||
|
|
||||||
namespace GpgFrontend::Module {
|
namespace GpgFrontend::Module {
|
||||||
|
|
||||||
|
void LoadGpgFrontendModulesLoggingSystem(ModuleInitArgs args) {
|
||||||
|
GpgFrontend::Module::SDK::InitModuleLoggingSystem(args.log_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutdownGpgFrontendModulesLoggingSystem() {
|
||||||
|
GpgFrontend::Module::SDK::ShutdownModuleLoggingSystem();
|
||||||
|
}
|
||||||
|
|
||||||
void LoadGpgFrontendModules(ModuleInitArgs args) {
|
void LoadGpgFrontendModules(ModuleInitArgs args) {
|
||||||
SDK::InitModuleLoggingSystem(args.log_level);
|
// init the logging system for module system
|
||||||
|
LoadGpgFrontendModulesLoggingSystem(args);
|
||||||
|
|
||||||
MODULE_LOG_INFO("loading integrated module...");
|
MODULE_LOG_INFO("loading integrated module...");
|
||||||
|
|
||||||
@ -51,8 +62,13 @@ void LoadGpgFrontendModules(ModuleInitArgs args) {
|
|||||||
Integrated::GnuPGInfoGatheringModule::GnuPGInfoGatheringModule>();
|
Integrated::GnuPGInfoGatheringModule::GnuPGInfoGatheringModule>();
|
||||||
|
|
||||||
MODULE_LOG_INFO("load integrated module done.");
|
MODULE_LOG_INFO("load integrated module done.");
|
||||||
|
|
||||||
|
// must init at default thread before core
|
||||||
|
Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
|
||||||
|
new Thread::Task([](const DataObjectPtr&) -> int { return 0; },
|
||||||
|
"modules_system_init_task"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownGpgFrontendModules() { SDK::ShutdownModuleLoggingSystem(); }
|
void ShutdownGpgFrontendModules() {}
|
||||||
|
|
||||||
} // namespace GpgFrontend::Module
|
} // namespace GpgFrontend::Module
|
@ -36,11 +36,25 @@ struct ModuleInitArgs {
|
|||||||
spdlog::level::level_enum log_level;
|
spdlog::level::level_enum log_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
void GPGFRONTEND_MODULE_EXPORT
|
||||||
|
LoadGpgFrontendModulesLoggingSystem(ModuleInitArgs args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GPGFRONTEND_MODULE_EXPORT ShutdownGpgFrontendModulesLoggingSystem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief init the module library
|
* @brief init the module library
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs);
|
void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief shutdown the module library
|
* @brief shutdown the module library
|
||||||
|
@ -97,7 +97,7 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
|
|||||||
event->GetIdentifier());
|
event->GetIdentifier());
|
||||||
|
|
||||||
const auto gpgme_version = RetrieveRTValueTypedOrDefault<>(
|
const auto gpgme_version = RetrieveRTValueTypedOrDefault<>(
|
||||||
"core", "gpgme.version", std::string{"2.0.0"});
|
"core", "gpgme.version", std::string{"0.0.0"});
|
||||||
MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
|
MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
|
||||||
|
|
||||||
const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>(
|
const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>(
|
||||||
@ -289,8 +289,7 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
|
|||||||
std::string{});
|
std::string{});
|
||||||
|
|
||||||
auto jsonlized_component_info = nlohmann::json::parse(component_info_json);
|
auto jsonlized_component_info = nlohmann::json::parse(component_info_json);
|
||||||
GpgComponentInfo component_info =
|
auto component_info = jsonlized_component_info.get<GpgComponentInfo>();
|
||||||
jsonlized_component_info.get<GpgComponentInfo>();
|
|
||||||
MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
|
MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
|
||||||
component_info.name);
|
component_info.name);
|
||||||
|
|
||||||
@ -393,6 +392,8 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
|
|||||||
UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true);
|
UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true);
|
||||||
event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true));
|
event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true));
|
||||||
|
|
||||||
|
SPDLOG_INFO("gnupg external info gathering done");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include <spdlog/sinks/rotating_file_sink.h>
|
#include <spdlog/sinks/rotating_file_sink.h>
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "core/function/GlobalSettingStation.h"
|
#include "core/function/GlobalSettingStation.h"
|
||||||
|
|
||||||
namespace GpgFrontend::Module::SDK {
|
namespace GpgFrontend::Module::SDK {
|
||||||
@ -81,7 +83,13 @@ void ShutdownModuleLoggingSystem() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<spdlog::logger> GetModuleLogger() {
|
auto GetModuleLogger() -> std::shared_ptr<spdlog::logger> {
|
||||||
|
// check if logging system is initalized
|
||||||
|
auto ptr = spdlog::get("module");
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
throw std::runtime_error("logging system of modules is not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
return spdlog::get("module");
|
return spdlog::get("module");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "GpgFrontendUIInit.h"
|
#include "GpgFrontendUIInit.h"
|
||||||
|
|
||||||
|
#include <qapplication.h>
|
||||||
#include <spdlog/async.h>
|
#include <spdlog/async.h>
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/sinks/rotating_file_sink.h>
|
#include <spdlog/sinks/rotating_file_sink.h>
|
||||||
@ -37,9 +38,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "core/GpgConstants.h"
|
#include "core/GpgConstants.h"
|
||||||
|
#include "core/function/CoreSignalStation.h"
|
||||||
#include "core/function/GlobalSettingStation.h"
|
#include "core/function/GlobalSettingStation.h"
|
||||||
|
#include "core/module/ModuleManager.h"
|
||||||
#include "core/thread/CtxCheckTask.h"
|
#include "core/thread/CtxCheckTask.h"
|
||||||
#include "core/thread/TaskRunnerGetter.h"
|
#include "core/thread/TaskRunnerGetter.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
#include "ui/UISignalStation.h"
|
#include "ui/UISignalStation.h"
|
||||||
#include "ui/UserInterfaceUtils.h"
|
#include "ui/UserInterfaceUtils.h"
|
||||||
#include "ui/main_window/MainWindow.h"
|
#include "ui/main_window/MainWindow.h"
|
||||||
@ -52,6 +56,65 @@ namespace GpgFrontend::UI {
|
|||||||
|
|
||||||
extern void InitLocale();
|
extern void InitLocale();
|
||||||
|
|
||||||
|
void WaitEnvCheckingProcess() {
|
||||||
|
SPDLOG_DEBUG("need to waiting for env checking process");
|
||||||
|
|
||||||
|
// create and show loading window before starting the main window
|
||||||
|
auto* waiting_dialog = new QProgressDialog();
|
||||||
|
waiting_dialog->setMaximum(0);
|
||||||
|
waiting_dialog->setMinimum(0);
|
||||||
|
auto* waiting_dialog_label =
|
||||||
|
new QLabel(QString(_("Loading Gnupg Info...")) + "<br /><br />" +
|
||||||
|
_("If this process is too slow, please set the key "
|
||||||
|
"server address appropriately in the gnupg configuration "
|
||||||
|
"file (depending "
|
||||||
|
"on the network situation in your country or region)."));
|
||||||
|
waiting_dialog_label->setWordWrap(true);
|
||||||
|
waiting_dialog->setLabel(waiting_dialog_label);
|
||||||
|
waiting_dialog->resize(420, 120);
|
||||||
|
QApplication::connect(CoreSignalStation::GetInstance(),
|
||||||
|
&CoreSignalStation::SignalGoodGnupgEnv, waiting_dialog,
|
||||||
|
[=]() {
|
||||||
|
SPDLOG_DEBUG("gpg env loaded successfuly");
|
||||||
|
waiting_dialog->finished(0);
|
||||||
|
waiting_dialog->deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
|
// new local event looper
|
||||||
|
QEventLoop looper;
|
||||||
|
QApplication::connect(CoreSignalStation::GetInstance(),
|
||||||
|
&CoreSignalStation::SignalGoodGnupgEnv, &looper,
|
||||||
|
&QEventLoop::quit);
|
||||||
|
|
||||||
|
QApplication::connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
|
||||||
|
SPDLOG_DEBUG("cancel clicked on wairing dialog");
|
||||||
|
QApplication::quit();
|
||||||
|
exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto env_state = Module::RetrieveRTValueTypedOrDefault<>(
|
||||||
|
"core", "env.state.basic", std::string{"0"});
|
||||||
|
|
||||||
|
SPDLOG_DEBUG("ui is ready to wating for env initialized, env_state: {}",
|
||||||
|
env_state);
|
||||||
|
|
||||||
|
// check twice to avoid some unlucky sitations
|
||||||
|
if (env_state == "1") {
|
||||||
|
SPDLOG_DEBUG("env state turned initialized before the looper start");
|
||||||
|
waiting_dialog->finished(0);
|
||||||
|
waiting_dialog->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// show the loading window
|
||||||
|
waiting_dialog->setModal(true);
|
||||||
|
waiting_dialog->setFocus();
|
||||||
|
waiting_dialog->show();
|
||||||
|
|
||||||
|
// block the main thread until the gpg context is loaded
|
||||||
|
looper.exec();
|
||||||
|
}
|
||||||
|
|
||||||
void InitGpgFrontendUI(QApplication* app) {
|
void InitGpgFrontendUI(QApplication* app) {
|
||||||
// init locale
|
// init locale
|
||||||
InitLocale();
|
InitLocale();
|
||||||
@ -132,51 +195,10 @@ void InitGpgFrontendUI(QApplication* app) {
|
|||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the thread to load the gpg context
|
if (Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic",
|
||||||
auto* init_ctx_task = new Thread::CoreInitTask();
|
std::string{"0"}) == "0") {
|
||||||
|
WaitEnvCheckingProcess();
|
||||||
// create and show loading window before starting the main window
|
}
|
||||||
auto* waiting_dialog = new QProgressDialog();
|
|
||||||
waiting_dialog->setMaximum(0);
|
|
||||||
waiting_dialog->setMinimum(0);
|
|
||||||
auto waiting_dialog_label =
|
|
||||||
new QLabel(QString(_("Loading Gnupg Info...")) + "<br /><br />" +
|
|
||||||
_("If this process is too slow, please set the key "
|
|
||||||
"server address appropriately in the gnupg configuration "
|
|
||||||
"file (depending "
|
|
||||||
"on the network situation in your country or region)."));
|
|
||||||
waiting_dialog_label->setWordWrap(true);
|
|
||||||
waiting_dialog->setLabel(waiting_dialog_label);
|
|
||||||
waiting_dialog->resize(420, 120);
|
|
||||||
app->connect(init_ctx_task, &Thread::CoreInitTask::SignalTaskEnd,
|
|
||||||
waiting_dialog, [=]() {
|
|
||||||
SPDLOG_DEBUG("gpg context loaded");
|
|
||||||
waiting_dialog->finished(0);
|
|
||||||
waiting_dialog->deleteLater();
|
|
||||||
});
|
|
||||||
|
|
||||||
app->connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
|
|
||||||
SPDLOG_DEBUG("cancel clicked");
|
|
||||||
app->quit();
|
|
||||||
exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// show the loading window
|
|
||||||
waiting_dialog->setModal(true);
|
|
||||||
waiting_dialog->setFocus();
|
|
||||||
waiting_dialog->show();
|
|
||||||
|
|
||||||
// new local event looper
|
|
||||||
QEventLoop looper;
|
|
||||||
app->connect(init_ctx_task, &Thread::CoreInitTask::SignalTaskEnd, &looper,
|
|
||||||
&QEventLoop::quit);
|
|
||||||
|
|
||||||
// start the thread to load the gpg context
|
|
||||||
Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
|
|
||||||
init_ctx_task);
|
|
||||||
|
|
||||||
// block the main thread until the gpg context is loaded
|
|
||||||
looper.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int RunGpgFrontendUI(QApplication* app) {
|
int RunGpgFrontendUI(QApplication* app) {
|
||||||
@ -187,12 +209,15 @@ int RunGpgFrontendUI(QApplication* app) {
|
|||||||
if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
|
if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
|
||||||
SPDLOG_DEBUG("application need to restart, before mian window init");
|
SPDLOG_DEBUG("application need to restart, before mian window init");
|
||||||
return kDeepRestartCode;
|
return kDeepRestartCode;
|
||||||
} else {
|
|
||||||
main_window->Init();
|
|
||||||
SPDLOG_DEBUG("main window inited");
|
|
||||||
main_window->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init main window
|
||||||
|
main_window->Init();
|
||||||
|
|
||||||
|
// show main windows
|
||||||
|
SPDLOG_DEBUG("main window is ready to show");
|
||||||
|
main_window->show();
|
||||||
|
|
||||||
// start the main event loop
|
// start the main event loop
|
||||||
return app->exec();
|
return app->exec();
|
||||||
}
|
}
|
||||||
@ -242,6 +267,8 @@ void ShutdownUILoggingSystem() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI() { ShutdownUILoggingSystem(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief setup the locale and load the translations
|
* @brief setup the locale and load the translations
|
||||||
*
|
*
|
||||||
|
@ -44,6 +44,12 @@ void GPGFRONTEND_UI_EXPORT InitGpgFrontendUI(QApplication *);
|
|||||||
*/
|
*/
|
||||||
void GPGFRONTEND_UI_EXPORT InitUILoggingSystem(spdlog::level::level_enum level);
|
void GPGFRONTEND_UI_EXPORT InitUILoggingSystem(spdlog::level::level_enum level);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief init the UI library
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
@ -160,8 +160,8 @@ CommonUtils *CommonUtils::GetInstance() {
|
|||||||
|
|
||||||
CommonUtils::CommonUtils() : QWidget(nullptr) {
|
CommonUtils::CommonUtils() : QWidget(nullptr) {
|
||||||
connect(CoreSignalStation::GetInstance(),
|
connect(CoreSignalStation::GetInstance(),
|
||||||
&CoreSignalStation::SignalGnupgNotInstall, this,
|
&CoreSignalStation::SignalBadGnupgEnv, this,
|
||||||
&CommonUtils::SignalGnupgNotInstall);
|
&CommonUtils::SignalBadGnupgEnv);
|
||||||
connect(this, &CommonUtils::SignalKeyStatusUpdated,
|
connect(this, &CommonUtils::SignalKeyStatusUpdated,
|
||||||
UISignalStation::GetInstance(),
|
UISignalStation::GetInstance(),
|
||||||
&UISignalStation::SignalKeyDatabaseRefresh);
|
&UISignalStation::SignalKeyDatabaseRefresh);
|
||||||
@ -184,7 +184,7 @@ CommonUtils::CommonUtils() : QWidget(nullptr) {
|
|||||||
&UISignalStation::SignalRestartApplication, this,
|
&UISignalStation::SignalRestartApplication, this,
|
||||||
&CommonUtils::SlotRestartApplication);
|
&CommonUtils::SlotRestartApplication);
|
||||||
|
|
||||||
connect(this, &CommonUtils::SignalGnupgNotInstall, this, [=]() {
|
connect(this, &CommonUtils::SignalBadGnupgEnv, this, [=]() {
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(_("GnuPG Context Loading Failed"));
|
msgBox.setText(_("GnuPG Context Loading Failed"));
|
||||||
msgBox.setInformativeText(
|
msgBox.setInformativeText(
|
||||||
|
@ -207,7 +207,7 @@ class CommonUtils : public QWidget {
|
|||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SignalGnupgNotInstall();
|
void SignalBadGnupgEnv();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief emit when the key database is refreshed
|
* @brief emit when the key database is refreshed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user